Android开机自动唤醒屏幕、打开锁屏页并启动app

最近有个需求要求app要开机自启动,就按照一般的套路去注册了一个静态广播接收器,代码如下:
manifest文件:

<receiver android:name=".receiver.StartupReceiver">  
    <intent-filter>  
        <action android:name="android.intent.action.BOOT_COMPLETED" />  
    </intent-filter>  
</receiver>  

java文件:

[java] view plain copy
public class StartupReceiver extends BroadcastReceiver {  
     @Override  
     public void onReceive(Context context, Intent intent) {  
         ByLog.i(intent.getAction());  
         //开机启动  
         Intent mainIntent = new Intent(context, MainActivity.class);  
         //在BroadcastReceiver中显示Activity,必须要设置FLAG_ACTIVITY_NEW_TASK标志  
         mainIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
         context.startActivity(mainIntent);  
     }  
 }  

OK,运行然后重启。。。然而并没有作用。换了几个姿势重新重启。。。然而并没有作用。
google了一下,应该是没有添加

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

的缘故,于是添加上这行代码继续测试。。。然而并没有作用!!!
OK,继续google。但是google来google去得到的的结论都差不多,只要按照上面的套路来就可以接收到开机广播了。期间在stackoverflow一篇问答上看到有的说法是要加上

     <action android:name="android.intent.action.QUICKBOOT_POWERON" />

于是尝试了。。。然而并没有作用。
然后,我想到了可能是权限的问题,可能自启动权限被系统禁用了,于是到应用管理里面找到自家的app,进入权限设置页,没有自启动这一选项啊。。。那可能就是手机的问题了,因为刚才用来测试的是国产机。。。可能有改了些什么系统代码(stackoverflow 有一篇问答上就有提到小米和htc使用了非常规或者自定义的开机广播action)。。。于是就换了一部机子测试,通过了!!!!
冷静下来仔细想想,发现还有个解释不通的地方:第一部机子开机时留意到某些软件是可以开机自启的(启动后马上在通知栏里面出现了),也就是说我的app应该也可以在那部机子上开机自启的才对。于是抱着学习的心态去反编译了那些软件,结果发现它们不仅仅接受BOOT_COMPLETED广播,同时还接收了NEW_OUTGOING_CALL、PHONE_STATE、CONNECTIVITY_CHANGE,难怪。。。但我不能这么做啊,它那个只是在通知栏里面通知,我这是要启动app的。。。
想不通啊,最后想来想去觉得最有可能还是设置里面某些选项禁掉了开机启动,于是在设置里面一项一项仔细的找,然后我看到了应用权限页面里有个设置单项权限的菜单,想着设置单项跟外面的一起列出来的应该是一样的权限选项才对(之前也是这么想的,所以就没点进去),但是点进去一看,里面竟然就有外面没列出的应用自动启动选项 !!!我顿时就忍不住爆粗了。。。把这个选项打开,测试,毫无悬念的通过了。。。
开机自启这个是通过了,但是还有个问题就是开机之后一般都会停留在锁屏页且短时间内没有进行解锁操作屏幕会进入休眠状态,之后要手动操作进到系统才能看到打开的app,这个不能放着不管。于是又只能靠google了,花费了些时间,终于找到了解决方法(改源码那些解决方法我就不用想了,暂时做不到T_T),就是在app启动时,主动唤醒屏幕并解锁,代码如下:

//屏幕唤醒  
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);  
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP  
     | PowerManager.SCREEN_DIM_WAKE_LOCK, "StartupReceiver");//最后的参数是LogCat里用的Tag  
wl.acquire();  
//屏幕解锁  
KeyguardManager km= (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);  
KeyguardManager.KeyguardLock kl = km.newKeyguardLock("StartupReceiver");//参数是LogCat里用的Tag  
kl.disableKeyguard();  

到此,开机自启的这块需求就算是完成了。最后附上完整的代码:

manifest文件:
记得要添加权限

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />  ```

```xml
<receiver android:name=".receiver.StartupReceiver">  
     <intent-filter>  
          <action android:name="android.intent.action.BOOT_COMPLETED" />  
          <action android:name="android.intent.action.QUICKBOOT_POWERON" />  
     </intent-filter>  
</receiver>  ```

java文件:
```java
public class StartupReceiver extends BroadcastReceiver {  
        @Override  
        public void onReceive(Context context, Intent intent) {  
            ByLog.i(intent.getAction());  
  
             //开机后一般会停留在锁屏页面且短时间内没有进行解锁操作屏幕会进入休眠状态,此时就需要先唤醒屏幕和解锁屏幕  
             //屏幕唤醒  
             PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);  
             PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP  
                | PowerManager.SCREEN_DIM_WAKE_LOCK, "StartupReceiver");//最后的参数是LogCat里用的Tag  
             wl.acquire();  
  
             //屏幕解锁  
             KeyguardManager km= (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);  
             KeyguardManager.KeyguardLock kl = km.newKeyguardLock("StartupReceiver");//参数是LogCat里用的Tag  
             kl.disableKeyguard();  
  
            //开机启动  
            Intent mainIntent = new Intent(context, MainActivity.class);  
            //在BroadcastReceiver中显示Activity,必须要设置FLAG_ACTIVITY_NEW_TASK标志  
            mainIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
            context.startActivity(mainIntent);  
        }  
    }  

在解决开机自启的问题时发现了一篇文章,觉得里面提到的自启动失败的原因总结的很好,后面的adb发送广播更是省下了很多操作,节约了很多时间,在这里摘录(略有修改)一下以防以后找不到:
2、自启动失败的原因
接收不到BOOT_COMPLETED广播可能的原因

  1. BOOT_COMPLETED对应的action和uses-permission("android.permission.RECEIVE_BOOT_COMPLETED" )没有一起添加
  2. 应用安装到了sd卡内,安装在sd卡内的应用是收不到BOOT_COMPLETED广播的,可以在manifest节点下添加android:installLocation="internalOnly"来指定只能安装在手机内存里面,也可以监听开机加载sd卡的广播,可惜有的手机是没有sd卡的。。。
  3. 系统开启了Fast Boot模式,这种模式下系统启动并不会发送BOOT_COMPLETED广播
  4. 应用程序安装后重来没有启动过,这种情况下应用程序接收不到任何广播,包括BOOT_COMPLETED、ACTION_PACKAGE_ADDED、CONNECTIVITY_ACTION等等。

Android3.1之后,系统为了加强了安全性控制,应用程序安装后或是(设置)应用管理中被强制关闭后处于stopped状态,在这种状态下接收不到任何广播,除非广播带有FLAG_INCLUDE_STOPPED_PACKAGES标志,而默认所有系统广播都是FLAG_EXCLUDE_STOPPED_PACKAGES的,所以就没法通过系统广播自启动了。所以Android3.1之后

  1. 应用程序无法在安装后自己启动
  2. 没有ui的程序必须通过其他应用激活才能启动,如它的Activity、Service、Content Provider被其他应用调用。
    存在一种例外,就是应用程序被adb push you.apk /system/app/下是会自动启动的,不处于stopped状态。

具体说明见:
http://developer.android.com/about/versions/android-3.1.html#launchcontrols
http://commonsware.com/blog/2011/07/13/boot-completed-regression-confirmed.html

3、adb发送BOOT_COMPLETED
我们可以通过 adb shell am broadcast -a android.intent.action.BOOT_COMPLETED命令发送BOOT_COMPLETED广播,而不用重启测试机或模拟器来测试BOOT_COMPLETED广播(用真机测过,还是会重启的,所以推荐后面的指定包名命令),以下命令可以更精确的发送到某个package,如下:

adb shell am broadcast -a android.intent.action.BOOT_COMPLETED -c android.intent.category.HOME -n package_name/class_name

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容