实现锁屏的方式有多种(锁屏应用、悬浮窗、普通Activity伪造锁屏等等)。但国内比较主流并且被广泛应用的Activity伪造锁屏方式。

实例演示图片如下:

系列文章链接如下:

[Android] Android 锁屏实现与总结 (一)

[Android] Android 锁屏实现与总结 (二)

[Android] Android 锁屏实现与总结 (三)

代码文件地址:

https://github.com/wukong1688/Android-BaseLockScreen

1、广播注册

2、Activity设置

3、按键的屏蔽

4、滑屏解锁

Activity实现自定义锁屏页的思路很简单,即在听书模式开启时,启动一个service,在service中监听系统SCREEN_OFF的广播。当屏幕熄灭时service监听到广播,开启一个锁屏页Activity在屏幕最上层显示,该Activity创建的同时会去掉系统的锁屏(如果有密码是禁不掉的)。示意图如下:

 

二、重要实现

1、广播注册

<service
android:name=".service.LockScreenService"
android:enabled="true"
android:exported="true" />

注意:SCREEN_OFF广播监听必须是 动态注册 的,如果在AndroidManifest.xml中静态注册将无法接收到SCREEN_OFF广播。

LockScreenService.java

详细代码如下:

package com.jack.applockscreen.service;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.BitmapFactory;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.widget.Toast; import com.jack.applockscreen.R;
import com.jack.applockscreen.activity.DetailActivity;
import com.jack.applockscreen.activity.LockScreenActivity;
import com.jack.applockscreen.receiver.LockScreenReceiver; public class LockScreenService extends Service {
private LockScreenReceiver mReceiver;
private IntentFilter mIntentFilter = new IntentFilter();
private boolean isNotiShow = false; @Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
} @Override
public void onCreate() {
super.onCreate();
} @Override
public int onStartCommand(Intent intent, int flags, int startId) {
//动态注册
mIntentFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
mIntentFilter.addAction(Intent.ACTION_SCREEN_OFF);
mIntentFilter.addAction(Intent.ACTION_SCREEN_ON);
mIntentFilter.addAction(Intent.ACTION_TIME_TICK); mIntentFilter.setPriority(Integer.MAX_VALUE);
if (null == mReceiver) {
mReceiver = new LockScreenReceiver();
mIntentFilter.setPriority(Integer.MAX_VALUE);
registerReceiver(mReceiver, mIntentFilter); buildNotification();
Toast.makeText(getApplicationContext(), "开启成功", Toast.LENGTH_LONG).show();
} return START_STICKY;
} /**
* 通知栏显示
*/
private void buildNotification() {
if (!isNotiShow){ //避免多次显示
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Intent intent = new Intent(this, DetailActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, , intent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new NotificationCompat.Builder(this, "default")
.setTicker("APP正在运行")
.setAutoCancel(false)
.setContentTitle("APP正在运行")
.setContentText("运行中")
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pendingIntent)
.build();
manager.notify(, notification); startForeground(0x11, notification); isNotiShow = true;
}
} @Override
public void onDestroy() {
if (mReceiver != null) {
unregisterReceiver(mReceiver);
mReceiver = null;
}
super.onDestroy();
}
}

广播接收 LockScreenReceiver.java

package com.jack.applockscreen.receiver;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telecom.TelecomManager;
import android.telephony.TelephonyManager; import com.jack.applockscreen.activity.LockScreenActivity;
import com.jack.applockscreen.util.Parser; public class LockScreenReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_SCREEN_OFF.equals(action)) {
if (Parser.sPhoneCallState == TelephonyManager.CALL_STATE_IDLE) { // 手机状态为未来电的空闲状态
// 判断锁屏界面是否已存在,如果已存在就先finish,防止多个锁屏出现
if (!Parser.KEY_GUARD_INSTANCES.isEmpty()) {
for (Activity activity : Parser.KEY_GUARD_INSTANCES) {
activity.finish();
}
}
Intent lockScreen = new Intent(context, LockScreenActivity.class);
lockScreen.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
context.startActivity(lockScreen);
}
} else {
Parser.killBackgroundProcess(context);
}
}
}

注意:

1) 标志位FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS,是为了避免在最近使用程序列表出现Service所启动的Activity。

2) 启动Activity时Intent的Flag,如果不添加FLAG_ACTIVITY_NEW_TASK的标志位,会出现“Calling startActivity() from outside of an Activity”的运行时异常,因为我们是从Service启动的Activity。Activity要存在于activity的栈中,而Service在启动activity时必然不存在一个activity的栈,所以要新起一个栈,并装入启动的activity。使用该标志位时,也需要在AndroidManifest中声明taskAffinity,即新task的名称,否则锁屏Activity实质上还是在建立在原来App的task栈中。
下接:
 

本博客地址: wukong1688

本文原文地址:https://www.cnblogs.com/wukong1688/p/10716875.html

转载请著名出处!谢谢~~

最新文章

  1. Ncut源码编译错误的解决方法
  2. ajax和sap以及网络安全
  3. 用脚本来简化iOS美术同学的工作
  4. squid常用调试命令
  5. upstream 负载均衡
  6. matlab求曲线长度
  7. java中List集合及其遍历详解
  8. WF4的数据库 表
  9. 基于url拦截实现权限控制
  10. git 删除右键菜单
  11. 认识css
  12. HDU-4861-Couple doubi(数学题,难懂!难懂!)
  13. Linux系统挂载操作mount详解
  14. 2018-2019-2 20175217 实验二《Java面向对象程序设计》实验报告
  15. 物联网温度服务器-ECharts、HTML5、JavaScript / ECharts gauge使用示例
  16. JVM GC-----2、垃圾标记算法(一)
  17. ios页面间跳转方式总结
  18. 调试Java源代码时变量的值无法追踪怎么办?
  19. 黑马程序员_java基础笔记(03)...面向对象
  20. 把thinkphp项目拷贝到其他电脑上报错

热门文章

  1. LeetCode算法题-Binary Tree Tilt(Java实现)
  2. docker容器日志收集方案(方案二 filebeat+syslog本地日志收集)
  3. 在Linux系统中同步更新我们的Github博客
  4. 环境配置 mac安装bazel
  5. Framework7 索引列表插件的异步加载实现
  6. PS制作漂亮紫色霓虹灯光文字
  7. DOTween 相关API效果
  8. dubbo 使用zookeeper 出现 Dubbo客户端调用报错NullPointerException
  9. JSON.stringify()的不常见用法
  10. A Java Runtime Environment (JRE) or Java Development Kit (JDK) must be available in order to run Eclipse.