-
- -d: filter to only show disbled packages.
- -e: filter to only show enabled packages.
- -s: filter to only show system packages.
- -3: filter to only show third party packages.
- -u: also include uninstalled packages.
- pm enable, disable, disable-user: these commands change the enabled state
- of a given package or component (written as "package/class").
这里只截取了一部分,详情请自行查看pm帮助
大家可以拿一个无关紧要的程序试试,disable再enable,看看launcher有什么变化(需要root权限,之前的查询是不需要root权限的) ,比如:
- pm disable cn.eoe.wiki
- pm enable cn.eoe.wiki
注:切换到root用户时,执行pm可能会出现段错误(android 4.0+)
- shell@android:/ # pm
- [1] + Stopped (signal) pm
- shell@android:/ # pm
- [2] + Stopped (signal) pm
- [1] - Segmentation fault pm
我们在执行pm之前,export一下LD_LIBRARY_PATH即可
- export LD_LIBRARY_PATH=/vendor/lib:/system/lib
我们可以查看一下这个变量
- echo $LD_LIBRARY_PATH
在我机器上面,普通用户是设置了这个变量的,切换到root的时候,这个变量就空了,所以需要重新export一下
第一个功能程序状态 讲解就结束了。
其实大多数人关心的是第二个功能开机启动 问题
首选,我们需要明确的是:我们需要知道哪些应用具有开机启动功能。
其实精确到应用还不可以,因为我们不是要把应用禁止掉,而是要把接收开机启动的Intent的receiver禁止掉,所以我们需要精确到class
首先我们来看看接收BOOT_COMPLETED的receiver在manifest中如何注册的
- <receiver android:name=".BootReceiver" android:enabled="true">
- <intent-filter>
- <action android:name="android.intent.action.BOOT_COMPLETED"/>
- </intent-filter>
- </receiver>
这里有一点是需要特别注意的: android:enabled="true"
enabled这个属性,大多数情况下我们是不显式写在这里的,当然,默认值就为true
禁止开机启动,其实就是设置接收BOOT_COMPLETED的receiver状态为disabled,即android:enabled="false"
首先要解决的就是如何获得所有接收BOOT_COMPLETED的receiver
开始我也搜索了一下,发现网上的很多方法都不可用,这里给大家说明一下:
错误方法1
- Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED);
- List<ResolveInfo> resolveInfoList = mPackageManager.queryBroadcastReceivers(intent, PackageManager.GET_RESOLVED_FILTER);
这里返回的list都是enabled的receiver
错误方法2
- List<ApplicationInfo> allAppsList = mPackageManager.getInstalledApplications(0);
- int allAppsListSize = allAppsList.size();
- for (int i = 0; i < allAppsListSize; i++) {
- ApplicationInfo applicationInfo = allAppsList.get(i);
- PackageInfo packageInfo = mPackageManager.getPackageInfo(applicationInfo.packageName, PackageManager.GET_RECEIVERS);
- ActivityInfo[] receivers = packageInfo.receivers;
- if(receivers != null) {
- ……
- }
- }
这里获得的也都是enable的
错误方法3
有的人使用下面代码片断
- if (PackageManager.PERMISSION_GRANTED == mPackageManager.checkPermission("android.permission.RECEIVE_BOOT_COMPLETED", app.packageName))
检查package干什么?!
其实android原生给我们提供了如何获得所有component的api(enabled+disabled)
int android.content.pm.PackageManager.GET_DISABLED_COMPONENTS = 512 [0x200]
PackageInfo flag: include disabled components in the returned info.
这样,我们使用如下代码就可以了
- Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED);
- List<ResolveInfo> resolveInfoList = mPackageManager.queryBroadcastReceivers(intent, PackageManager.GET_DISABLED_COMPONENTS);
然后我们需要知道组件的状态,disabled还是enabled
- ComponentName mComponentName = new ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name);
- Log.d(TAG, "COMPONENT_ENABLED_STATE:" + mPackageManager.getComponentEnabledSetting(mComponentName) + "\tpackageName:" + resolveInfo.activityInfo.packageName);
接下来的事情就简单了,如果你想禁止包名为package的应用开机启动,那么只需在上面list中,找到所有此包下的receiver,然后
- pm disable package/class
- pm enable package/class
即可
我们需要关注下面几个COMPONENT_ENABLED_STATE
写道public static final int COMPONENT_ENABLED_STATE_DEFAULTSince: API Level 1
Flag for setApplicationEnabledSetting(String, int, int) and setComponentEnabledSetting(ComponentName, int, int): This component or application is in its default enabled state (as specified in its manifest).Constant Value: 0 (0x00000000)
public static final int COMPONENT_ENABLED_STATE_DISABLEDSince: API Level 1
Flag for setApplicationEnabledSetting(String, int, int) and setComponentEnabledSetting(ComponentName, int, int): This component or application has been explicitly disabled, regardless of what it has specified in its manifest.Constant Value: 2 (0x00000002)
public static final int COMPONENT_ENABLED_STATE_DISABLED_USERSince: API Level 14
Flag for setApplicationEnabledSetting(String, int, int) only: The user has explicitly disabled the application, regardless of what it has specified in its manifest. Because this is due to the user's request, they may re-enable it if desired through the appropriate
system UI. This option currently can not be used with setComponentEnabledSetting(ComponentName, int, int).Constant Value: 3 (0x00000003)
public static final int COMPONENT_ENABLED_STATE_ENABLEDSince: API Level 1
Flag for setApplicationEnabledSetting(String, int, int) and setComponentEnabledSetting(ComponentName, int, int): This component or application has been explictily enabled, regardless of what it has specified in its manifest.Constant Value: 1 (0x00000001)
public static final int DONT_KILL_APPSince: API Level 1
Flag parameter for setComponentEnabledSetting(android.content.ComponentName, int, int) to indicate that you don't want to kill the app containing the component. Be careful when you set this since changing component states can make the containing application's
behavior unpredictable.Constant Value: 1 (0x00000001)
如果是自己应用中想disable或者enable自己的组件,那么是不需要任何权限的,当然不能使用pm命令
在原生email(4.0)应用中,旧有此功能,我们来看看email的代码
void com.android.email.service.EmailBroadcastProcessorService.setComponentEnabled(Class<?> clazz, boolean enabled)
- private void setComponentEnabled(Class<?> clazz, boolean enabled) {
- final ComponentName c = new ComponentName(this, clazz.getName());
- getPackageManager().setComponentEnabledSetting(c,
- enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
- : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
- PackageManager.DONT_KILL_APP);
- }
void com.android.email.Email.setServicesEnabled(Context context, boolean enabled)方法中也有参考代码
至此,开机启动、禁用程序 就全部讲解完了。
我们发现,海卓这个应用居然有这么多变态功能,居然可以禁止所有事件。。。这是不是过分了点,不过程序的原理应该都在我这篇博客之中了,我不太希望有禁止所有事件这种功能,那还不如把这个app删掉呢,何必折磨它呢?!
请大家不要用root的手机随意下载软件,更不要以任何借口制造任何病毒!
-d: filter to only show disbled packages.
- -e: filter to only show enabled packages.
- -s: filter to only show system packages.
- -3: filter to only show third party packages.
- -u: also include uninstalled packages.
- pm enable, disable, disable-user: these commands change the enabled state
- of a given package or component (written as "package/class").
这里只截取了一部分,详情请自行查看pm帮助
大家可以拿一个无关紧要的程序试试,disable再enable,看看launcher有什么变化(需要root权限,之前的查询是不需要root权限的) ,比如:
- pm disable cn.eoe.wiki
- pm enable cn.eoe.wiki
注:切换到root用户时,执行pm可能会出现段错误(android 4.0+)
- shell@android:/ # pm
- [1] + Stopped (signal) pm
- shell@android:/ # pm
- [2] + Stopped (signal) pm
- [1] - Segmentation fault pm
我们在执行pm之前,export一下LD_LIBRARY_PATH即可
- export LD_LIBRARY_PATH=/vendor/lib:/system/lib
我们可以查看一下这个变量
- echo $LD_LIBRARY_PATH
在我机器上面,普通用户是设置了这个变量的,切换到root的时候,这个变量就空了,所以需要重新export一下
第一个功能程序状态 讲解就结束了。
其实大多数人关心的是第二个功能开机启动 问题
首选,我们需要明确的是:我们需要知道哪些应用具有开机启动功能。
其实精确到应用还不可以,因为我们不是要把应用禁止掉,而是要把接收开机启动的Intent的receiver禁止掉,所以我们需要精确到class
首先我们来看看接收BOOT_COMPLETED的receiver在manifest中如何注册的
- <receiver android:name=".BootReceiver" android:enabled="true">
- <intent-filter>
- <action android:name="android.intent.action.BOOT_COMPLETED"/>
- </intent-filter>
- </receiver>
这里有一点是需要特别注意的: android:enabled="true"