锁屏应用开发的搁浅

开始

一个多月的 Android 学习,是时候写一些应用了,恰巧我看到少数派中谢了一片文章,推荐了一款时间锁屏软件,于是决定写一个锁屏软件,轻量级的,但是结果还是给了我不小的打击。


过程

废话不多说,先记录下过程,便于以后的拾起。


第一次动手,当然是先收集资料,做好准备工作。通过网络查询得知,锁屏类应用的实现方式有两种:

  1. 修改锁屏源码,定制自己的锁屏,这样子就没有我后来的问题了,一劳永逸
  2. 编写锁屏app,做成apk,这是市场上主流锁屏应用采用的方式,但是这样会有很多问题,后续很麻烦
第一种方式,由于我还没有达到那种级别,果断放弃,采用了第二种,还能借鉴一下网络高手的经验。微笑

采用第二种方式需要解决几个问题,我根据开发过程中的难易程度,对它们进行了排序,先易后难:

  1. 屏蔽系统锁屏,用自己的锁屏界面替换系统锁屏
  2. 自己的锁屏应用不能出现在最近任务列表中
  3. 屏蔽物理按键,包括Home键、Back键、音量键、Menu或最近任务键等(由于市场上有多个Android系统版本与厂商,会导致按键不同)
  4. 每次屏幕唤醒、系统开机重启显示自己的锁屏界面
问题不多,但是难度不小,这里的难度体现在适配不同的机型与 Android 版本。下面是我的实现方式:

问题一:屏蔽系统锁屏,用自己的锁屏界面替换系统锁屏

最好的方法是引导用户关闭系统锁屏;如果用户不关闭,就在后台使用代码禁用系统锁屏(键盘锁 Keyguard),因为有很多地方都会调用这个功能,所以独立成一个方法:

<span style="font-size:18px;"><span style="font-size:18px;">/**
 * 屏蔽系统内置锁屏,待测试
 */
public void CloseSysLock(Context context) {
    KeyguardManager mKeyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
    KeyguardManager.KeyguardLock mKeyguardLock = mKeyguardManager.newKeyguardLock("ScreenLock");
    //这句话需要在manifest文件中添加权限
    //<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
    mKeyguardLock.disableKeyguard();
}</span></span>


问题二:自己的锁屏应用不能出现在最近任务列表中

这个比较简单,在 manifest 文件中的 Activity 标签中添加属性 android:excludeFromRecents="true"

<span style="font-size:18px;"><!-- 应用不出现在最近任务列表中,android:excludeFromRecents="true" -->
<activity android:name=".MainActivity" android:excludeFromRecents="true"></span>

问题三:屏蔽物理按键,包括Home键、Back键、音量键、Menu或最近任务键等

这里又有两种方法,第一种是利用 Android 的 WindowManager,添加类型为WindowManager.LayoutParams.TYPE_SYSTEM_ERROR 的对话框(View),这个 View 会出现在所有 View 的最顶层,且不会对任何按键做处理,最终达到屏蔽物理按键的作用。贴出参考代码:

<span style="font-size:18px;"><span style="font-size:14px;">WindowManager mWindowManager = getWindowManager();
WindowManager.LayoutParams mLockViewLayoutParams = new WindowManager.LayoutParams();
mLockViewLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
mLockViewLayoutParams.height = WindowManager.LayoutParams.MATCH_PARENT;
//实现关键:添加类型为 WindowManager.LayoutParams.TYPE_SYSTEM_ERROR 的对话框(View)
mLockViewLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
mLockViewLayoutParams.flags = 1280;
View view = View.inflate(this,R.layout.activity_main,null);
mWindowManager.addView(view, mLockViewLayoutParams);
//记得在 Activity 被回收时,删除该 View
//mWindowManager.removeView(view);</span></span>


getWindowManager() 方法是Activity的方法,在其他类中调用,需要有 Activiy的引用。还有,记得在 Activity 被回收时,删除该 View:mWindowManager.removeView(view);

但是,这种方法会屏蔽掉 关机/重启界面,长按 Power 键,关机界面不会弹出,会被遮盖,作为一个强迫症,外加一点完美主义,这是无法容忍的,所以我没有采用这种方法。


第二种方法,是在 Activity 的 onCreate() 方法中,设置 Window 的 Flag,代码如下:

<span style="font-size:18px;"><span style="font-size:14px;">static final int FLAG_HOMEKEY_DISPATCHED = 0x80000000; 
getWindow().setFlags(FLAG_HOMEKEY_DISPATCHED, FLAG_HOMEKEY_DISPATCHED)</span></span>

上边的代码用于屏蔽 Home 键,然后重写 onKey() 方法,屏蔽其他物理按键,如下所示:

<span style="font-size:18px;"><span style="font-size:14px;">@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    //屏蔽Back、Menu、音量键
    switch (keyCode) {
        case KeyEvent.KEYCODE_BACK:
        case KeyEvent.KEYCODE_VOLUME_DOWN:
        case KeyEvent.KEYCODE_VOLUME_UP:
        case KeyEvent.KEYCODE_MENU:
            return true;
//        case KeyEvent.KEYCODE_HOME:
//            Toast.makeText(this, "Home", Toast.LENGTH_SHORT).show();
//            return false;
        default:
            break;
    }
    return super.onKeyDown(keyCode, event);
}</span></span>

但是,在如今市场上 Android 4.4 及以上版本占主导的情况下,屏蔽 Home 键的代码已经无效,本以为 Home 键与其他物理按键一样,但是测试结果让我很无奈,网上也没有最新的代码与资料。


问题四:每次屏幕唤醒、系统开机重启显示自己的锁屏界面
这个还比较简单,添加三个监听广播(Receiver):ScreenOn、ScreenOff、BootCompleted,在三个Receiver 中分别监听屏幕唤醒、屏幕关闭、系统启动完成,并添加启动 Activity 的代码,为避免重复启动 Activity,我将它的启动模式(launchMode)设置为 singleTask。

测试的时候遇到一个异常:

Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag.
原来,从Service 或 Receiver 中启动 Activity,需要给 Intent 加一个flag: intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

 
但是,又是但是,在系统开机后自动启动的 Activity,系统会自动加一个延时 5 秒的效果,哎,受不了。

总结
最后,简单的 app 出来了,测试结果却不太令我满意,有各种各样的瑕疵:Home 键屏蔽不起作用,屏幕唤醒时启动锁屏界面时灵时不灵(有可能是Home键引起的),开机启动体验不好,这些无形中给我泼了冷水。

后来反思了一下,是我太心急的缘故,目前只掌握了 Android 的基础开发,且只有应用方面的软件功能开发知识,锁屏应用开起来很小,知识点不多,但是没有对 Android 掌握足够的深度,还是有点力不从心。

我还是有点信心膨胀了,仗着 Java 有点基础, Android 基础只是掌握了一点,有迫不及待想“干番大事业”,结果弄巧成拙,学习这事,慢就是快,需要一步一脚印的走。

谨以这篇文章做记录,锁屏应用,我还会回来的!


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值