实现锁屏的方式有多种(锁屏应用、悬浮窗、普通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

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

[Android] Android 锁屏实现与总结 (一)的更多相关文章

  1. Android忘记锁屏密码如何进入手机?

    Android忘记锁屏密码如何进入手机?     1.关闭手机 2.进入recovery模式(即恢复模式,记住不是挖煤模式.进入恢复模式不同手机有不同方法,三星的话安主页键,关机键和音量+(或-键), ...

  2. Android逆向之旅---Android中锁屏密码算法解析以及破解方案

    一.前言 最近玩王者荣耀,下载了一个辅助样本,结果被锁机了,当然破解它很简单,这个后面会详细分析这个样本,但是因为这个样本引发出的欲望就是解析Android中锁屏密码算法,然后用一种高效的方式制作锁机 ...

  3. Android一键锁屏源码

    APK下载 源程序下载 锁屏流程如下(参考于Android一键锁屏开发全过程[源码][附图]) 源码参考于一键锁屏 源码 一共有2个Java文件: package com.example.onekey ...

  4. 【腾讯Bugly干货分享】浅谈Android自定义锁屏页的发车姿势

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57875330c9da73584b025873 一.为什么需要自定义锁屏页 锁屏 ...

  5. 浅谈 Android 自定义锁屏页的发车姿势

    作者:blowUp,原文链接:http://mp.weixin.qq.com/s?__biz=MzA3NTYzODYzMg==&mid=2653577446&idx=2&sn= ...

  6. android开发 锁屏 真正的锁屏,是go锁屏那种。

    想做个锁屏界面很久了,最近一周,历经千辛万苦,越过种种挫折,终于完美实现了这一要求,在此将锁屏思路分享出来. 注意:这不是什么一键锁屏,是类似“go锁屏”那样的锁屏界面. 准备:本程序共需要 两个ac ...

  7. 浅谈Android自定义锁屏页的发车姿势

    一.为什么需要自定义锁屏页 锁屏作为一种黑白屏时代就存在的手机功能,至今仍发挥着巨大作用,特别是触屏时代的到来,锁屏的功用被发挥到了极致.多少人曾经在无聊的时候每隔几分钟划开锁屏再关上,孜孜不倦,其酸 ...

  8. Android LockScreen (锁屏弹窗)

    在要弹窗的Activity需要进行以下设置,才可以在锁屏状态下弹窗 @Override protected void onCreate(Bundle savedInstanceState) { fin ...

  9. Android一键锁屏APP

    题记: 这个app完全是拾人牙慧,作为练手用的,其实没有什么原创的东西.当然,博客还是我自己写的,记录下来,对自己也算是一种成长吧. 转载请注明原文地址: http://www.cnblogs.com ...

  10. Android定时锁屏功能实现(AlarmManager定时部分)

    菜鸟入坑记——第一篇 关键字:AlarmManager 一.AlarmManager简介: 参考网址:https://www.jianshu.com/p/8a2ce9d02640        参考网 ...

随机推荐

  1. idea软件破解汉化

    →http://idea.lanyus.com/上可以找到最新的破解补丁,下载并放到软件的bin目录下  →更改bin目录下的两个文件:Idea.exe.vmoptions和Idea64.exe.vm ...

  2. APACHE SPARK 2.0 API IMPROVEMENTS: RDD, DATAFRAME, DATASET AND SQL

    What’s New, What’s Changed and How to get Started. Are you ready for Apache Spark 2.0? If you are ju ...

  3. python 中内存释放与函数传递numpy数组问题

    numpy.array 作为参数传入函数中时,是作为引用进去的,函数内部对这个数组的修改会直接修改原始数据.在函数中需要暂时修改数据,不对原始数据造成影响的话,需要用 np.copy() 先拷贝一份, ...

  4. 【P2015】二叉苹果树 (树形DP分组背包)

    题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 现在这颗树枝条太多了,需要剪枝.但是 ...

  5. 网易云歌词解析(配合audio标签实现本地歌曲播放,歌词同步)

    先看下效果 github上做的一个音乐播放器: https://github.com/SorrowX/electron-music 中文歌曲 英文歌曲(如果有翻译的中文给回返回出去) 韩文歌曲 来看下 ...

  6. 一款DMA性能优化记录:异步传输和指定实时信号做async IO

    关键词:DMA.sync.async.SIGIO.F_SETSIG. DMA本身用于减轻CPU负担,进行CPU off-load搬运工作. 在DMA驱动内部实现有同步和异步模式,异步模式使用dma_a ...

  7. Linux内存管理 (16)内存规整

    专题:Linux内存管理专题 关键词:内存规整.页面迁移.pageblock.MIGRATE_TYPES. 内存碎片的产生:伙伴系统以页为单位进行管理,经过大量申请释放,造成大量离散且不连续的页面.这 ...

  8. 【Swift 4.2】uuid 取 hashCode(与 Java/Go/Kotlin 一致)

    extension String { func hashCode() -> Int32 { let components = self.split(separator: "-" ...

  9. 【Swift 2.2】iOS开发笔记(三)

    1.UITableView 中调用 UIButton 的 setTitle 会闪 滚动列表时比较明显,解决办法: buttonType 改成 custom 即可,但是这样一来 UIButton 的高亮 ...

  10. 小议SQL数据插入

    --数据插入操作:INSERT INTO user_info(username,age) VALUES('ZHANGSAN',20);INSERT INTO user_info(username,ph ...