-
- -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
我们可以查看一下这个变量
在我机器上面,普通用户是设置了这个变量的,切换到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_DEFAULT
Since: 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_DISABLED
Since: 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_USER
Since: 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_ENABLED
Since: 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_APP
Since: 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
我们可以查看一下这个变量
在我机器上面,普通用户是设置了这个变量的,切换到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_DEFAULT
Since: 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_DISABLED
Since: 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_USER
Since: 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_ENABLED
Since: 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_APP
Since: 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的手机随意下载软件,更不要以任何借口制造任何病毒!