方案一
通过setComponentEnabledSetting方式,禁止掉应用的监听开机启动的广播组件。
代码如下:
getContext().getPackageManager().setComponentEnabledSetting(
new ComponentName("包名", "组件名"),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
缺点:
- 让组件不能再使用,除非设置成COMPONENT_ENABLED_STATE_ENABLED。
- 系统开关机仍然有效,但应用被卸载此属性会失效。
方案二
通过forceStopPackage方式,将应用stop掉。应用被stop后,stopped属性变为true,
如果应用没再被使用,开机启动时即使接收了开机广播应用也不会自启动。
代码如下:
private void setPackageForceStop(String pkg) {
try {
Method method = Class.forName("android.app.ActivityManager").getMethod("forceStopPackage", String.class);
if (mActivityManager == null) {
mActivityManager = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
}
method.invoke(mActivityManager, pkg);
} catch (Exception e) {
e.printStackTrace();
}
}
缺点:
- 如果该应用是系统应用,每次开机启动stopped属性会被置为false,即该应用能开机自启。
- 同样的,如果该应用被卸载后重装也会导致stopped属性会被置为false,即该应用能开机自启。
- 应用被stop后然后被使用,stopped属性会被置为false,即该应用能开机自启。
方案三
通过拦截应用的开机广播,不让应用接收到开机广播。
因开机广播是全局的、无序的广播,暂时没有办法做到拦截应用的开机广播
(系统端能做到,但这是应用层的业务,显然系统端不会做这样不合理的处理)。
方案四
通过禁止应用的开机广播权限,不让应用接收到开机广播。
此想法应该是,暂时没法拦截应用的开机广播,就想法禁止应用的开机广播权限。
总之,就是不想让应用接收到开机广播,但目前没有好的办法去禁止应用的开机广播权限。
总结
方案一和方案二是一般应用的实现方式,但两者都有一些小缺点,并且两者的实现都不能保证应用开机后不自启。
所以,无论采用方案一和方案二,目前能想到的最好方式还是,管理应用自启动的APK自己开机自启后,
stop掉被限制开机自启的应用,然后,如果此管理APK不必要,可以kill掉自己。
备注
- 查看应用的stopped属性:dumpsys package com.tcl.tvweishi | grep stop
- shell命令stop掉应用:am force-stop com.tcl.tvweishi