最近项目中,有用到开机自启动的功能,这里做一下总结,供大家学习探讨!
Android 开机启动延迟问题
Android 开机自启动被拦截问题
实战演练
测试手机:红米手机 Redmi 6A 安卓version 9
华为手机 DUA-AL00 安卓version 8.1.0
华为手机 Honor 9i 安卓version 9.1.0
VIVO手机 vivo iQOO 安卓version 11
小米平板 MI PAD 4 安卓version 8.1.0
经测试以上机型测试成功
对于开机自启的基本思路:
- 想要实现app开机自启动,我们用广播的方式来实现这种需求。app首先需要去注册一个关于接收发送开机启动的广播(android.intent.action.BOOT_COMPLETED);而且必须要注意的一点是:这个广播必须的静态注册的,不能是动态注册的广播(这种接收开机广播的,一定要静态注册,这样应用还没运行起来时也照样能够接收到开机广播
,动态广播就不行了)。 - 静态注册好了广播之后,在onReceive方法里面做处理就可以了
- 重点注意项
(1)在安装完应用后,要先运行一次,然后关机,再启动。
(2)针对Andorid4.0之后需先启动一次APP才可收到开机完成的广播,主要目的是防止恶意程序
(3)同设备尽可能只允许一个APP实现开机自启动的功能,否则俩者应该会有冲突
具体实现
//加入权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
这里关于onReceive方法里面的处理,有些机型不起作用,这里总结了两种实现方式:
1.根据包名启动应用
2.指定class类,跳转到相应的Activity
/**
* @author Martin-harry
* @date 2022/3/4
* @address
* @Desc 定义自启动BroadcastReceiver
*/
public class AutoStartBroadReceiver extends BroadcastReceiver {
private static final String ACTION = "android.intent.action.BOOT_COMPLETED";
@Override
public void onReceive(Context context, Intent intent) {
Log.e("接收广播", "onReceive: ");
Log.e("接收广播", "onReceive: " + intent.getAction());
//开机启动
if (ACTION.equals(intent.getAction())) {
Log.e("接收广播", "onReceive: 启动了。。。");
//第一种方式:根据包名
// PackageManager packageManager = context.getPackageManager();
// Intent mainIntent = packageManager.getLaunchIntentForPackage("com.harry.martin");
// mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// context.startActivity(mainIntent);
// context.startService(mainIntent);
//第二种方式:指定class类,跳转到相应的Acitivity
Intent mainIntent = new Intent(context, LoginActivity.class);
/**
* Intent.FLAG_ACTIVITY_NEW_TASK
* Intent.FLAG_ACTIVITY_CLEAR_TOP
*/
mainIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(mainIntent);
// context.startService(mainIntent);
}
}
}
注册广播
<receiver
android:name=".receiver.AutoStartBroadReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</receiver>
<activity
android:name=".mvp.view.Activity.LoginActivity"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
场景测试
做完上面的工作后,这里就针对部分手机应用的权限管理操作了
ComponentName localComponentName = new ComponentName(MyApp.getInstance(), MyInstalledReceiver.class);
int i = MyApp.getInstance().getPackageManager().getComponentEnabledSetting(localComponentName);
// Log.e("自启动 >>>>", "onCreate: " + i);
getAutostartSettingIntent(this);
/**
* 获取自启动管理页面的Intent
*
* @param context context
* @return 返回自启动管理页面的Intent
*/
public static Intent getAutostartSettingIntent(Context context) {
ComponentName componentName = null;
String brand = Build.MANUFACTURER;
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
switch (brand.toLowerCase()) {
case "samsung"://三星
componentName = new ComponentName("com.samsung.android.sm", "com.samsung.android.sm.app.dashboard.SmartManagerDashBoardActivity");
break;
case "huawei"://华为
Log.e("自启动管理 >>>>", "getAutostartSettingIntent: 华为");
componentName = new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.appcontrol.activity.StartupAppControlActivity");
// componentName = new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity");//目前看是通用的
break;
case "xiaomi"://小米
// componentName = new ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity");
componentName = new ComponentName("com.android.settings","com.android.settings.BackgroundApplicationsManager");
break;
case "vivo"://VIVO
// componentName = new ComponentName("com.iqoo.secure", "com.iqoo.secure.safaguard.PurviewTabActivity");
componentName = new ComponentName("com.iqoo.secure", "com.iqoo.secure.ui.phoneoptimize.AddWhiteListActivity");
break;
case "oppo"://OPPO
// componentName = new ComponentName("com.oppo.safe", "com.oppo.safe.permission.startup.StartupAppListActivity");
componentName = new ComponentName("com.coloros.oppoguardelf", "com.coloros.powermanager.fuelgaue.PowerUsageModelActivity");
break;
case "yulong":
case "360"://360
componentName = new ComponentName("com.yulong.android.coolsafe", "com.yulong.android.coolsafe.ui.activity.autorun.AutoRunListActivity");
break;
case "meizu"://魅族
componentName = new ComponentName("com.meizu.safe", "com.meizu.safe.permission.SmartBGActivity");
break;
case "oneplus"://一加
componentName = new ComponentName("com.oneplus.security", "com.oneplus.security.chainlaunch.view.ChainLaunchAppListActivity");
break;
case "letv"://乐视
intent.setAction("com.letv.android.permissionautoboot");
default://其他
intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
intent.setData(Uri.fromParts("package", context.getPackageName(), null));
break;
}
intent.setComponent(componentName);
return intent;
}
关于红米手机授权操作:
找到红米手机里面的手机管家应用,并打开里面的应用管理
打开授权管理,给自己的应用设置自启动权限,并允许应用在后台弹出界面
关于华为手机授权操作:
总结
本人在测试的时候,红米手机开机自启时间需要等待一段时间,如果有大佬知道怎么解决的,可以下方评论一下,谢谢啦
项目下载地址:AutoBroadCastReceiver_HandlerOOM
题外话:
另外一种实现方式的话,最好就是让系统桌面应用启动你,Launcher
PackageName:comp.xxx.launcher
launcher就是java写的一个app,只不过它是系统应用,但是拿这个代码的话,好像得fw的人帮忙,或者你自己搞出来
具体的也是在Launcher这个的MainActivity里面加个intent 跳转你app的包名