天天看点

Android 应用自动启动的两种方法(开机自启动 与 另一个应用广播通知启动)

最近遇到这么个问题:

在一个移动设备中安装了多个应用程序,其中自己开发的应用需要实现开机自启动这么个功能;

为了实现自己应用能够实现自动启动,最初的思路是监控设备的开机完成这类的广播信号;

思路一(开机自启动):

注册一个静态广播去监听开机启动完毕的广播,然后在接听到开机广播完毕后启动|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静态注册该广播:

<receiver android:name=".BootCompletedReceiver">
        <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <category android:name="android.intent.category.HOME" />
        </intent-filter>
</receiver>
           

然后在AndroidManifest.xml申请权限:

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

通过以上的方法,可以实现开启启动APP,但是,这个方法有问题,以上的方法必须要在安装APP后,手动运行一次APP后,APP才能接收到

android.intent.action.BOOT_COMPLETED

广播。

然而以上的解决思路在Android 3.1之后有了变更;

APP接收不到BOOT_COMPLETED广播可能的原因,有以下几种:

  1. BOOT_COMPLETED

    对应的

    action

    uses-permission

    没有一起添加
  2. 应用安装到了

    sd

    卡内,安装在

    sd

    卡内的应用是收不到

    BOOT_COMPLETED

    广播的
  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

状态。解决方式就是将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进行注册,代码如下:

     <receiver android:name="MyReceiver">
             <intent-filter>
                  <action android:name="com.example.BootUp"/>
            </intent-filter>
    </receiver>
           

这样就完成了通过应用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