最近遇到这么个问题:
在一个移动设备中安装了多个应用程序,其中自己开发的应用需要实现开机自启动这么个功能;
为了实现自己应用能够实现自动启动,最初的思路是监控设备的开机完成这类的广播信号;
注册一个静态广播去监听开机启动完毕的广播,然后在接听到开机广播完毕后启动|Activity或者Service;
其中广播监听器中内容为:
public class BootCompletedReceiver extends BroadcastReceiver {
private static final String ACTION_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED";
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_BOOT_COMPLETED)){
Intent intent=new Intent(context,MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
}
}
必须强调下如果没有设置标记 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
如果不添加这句,就会报 android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity,Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
然后在AndroidManifest.xml静态注册该广播:
然后在AndroidManifest.xml申请权限:
通过以上的方法,可以实现开启启动APP,但是,这个方法有问题,以上的方法必须要在安装APP后,手动运行一次APP后,APP才能接收到android.intent.action.BOOT_COMPLETED
广播。
然而以上的解决思路在Android 3.1之后有了变更;
APP接收不到BOOT_COMPLETED广播可能的原因,有以下几种:
BOOT_COMPLETED
对应的action
和uses-permission
没有一起添加sd
卡内,安装在sd
卡内的应用是收不到BOOT_COMPLETED
广播的Fast Boot
模式,这种模式下系统启动并不会发送BOOT_COMPLETED
广播BOOT_COMPLETED
、ACTION_PACKAGE_ADDED
、CONNECTIVITY_ACTION
等等。Android3.1之后,系统为了加强了安全性控制,应用程序安装后或是(设置)应用管理中被强制关闭后处于stopped状态,在这种状态下接收不到任何广播,除非广播带有FLAG_INCLUDE_STOPPED_PACKAGES
标志,而默认所有系统广播都是FLAG_EXCLUDE_STOPPED_PACKAGES
的,所以就没法通过系统广播自启动了。
所以Android3.1之后:
不过,存在一种例外,就是应用程序被adb push you.apk /system/app/
下是会自动启动的,不处于stopped
状态。解决方式就是将APK推送到/system/app
目录下,或者打包系统时,将APK放置到/system/app
中打包
结论是: 我没法将自己的应用安装到系统路径下,无root权限,即无法通过监控开机完成这个广播信号实现自启动了;那么采用思路二;
通过其他应用(命名为应用A)发送特定广播信号,我只需监控应用A发送的广播信号即可实现自启动了;
实现:A应用中的Activity发送广播,关键代码如下:
String broadcastIntent = "com.example.BootUp";//自己自定义
Intent intent = new Intent(broadcastIntent);
this.sendBroadcast(intent);
B应用中需要一个BroadcastReceiver来接收广播,取名MyReceiver继承BroadcastReceiver重写onReceive方法启动一个activity,关键代码如下:
if(intent.getAction().equals("com.example.BootUp")){
Intent intent = new Intent(context,MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
在AndroidManifest.xml中要对MyReceiver进行注册,代码如下:
这样就完成了通过应用A发送的广播启动另一个应用B中的Activity了(上面代码中Activity默认命名为MainActivity)。
注意问题:Context中有一 个startActivity方法,Activity继承自Context,重载了startActivity方法。如果使用 Activity的startActivity方法,不会有任何限制,而如果使用Context的startActivity方法的话,就需要开启一个新 的task,解决办法是,加一个flag,也就是这句 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);的作用。
开机自启动问题参考:https://segmentfault.com/q/1010000015837899
广播receiver中启动Activity参考:https://blog.csdn.net/u014005316/article/details/53671673
https://www.cnblogs.com/zhujiabin/p/4262049.html