因项目的需要,做一个自启管理的功能,管理其它app的自启动。看到这个功能的时候我有点无从下手,大多数第三方的管理app是没有这个功能的,网上关于这个功能的例子也很少,没有什么好的参考。只能自己研究了。很多的app的自启都是靠监听系统的广播,像最典型的就是开机广播。所以我想到的方法是禁止应用收听相关的广播来实现。有一个方法可以禁止掉android四大组件的使用。

public void setComponentEnabledSetting (ComponentName componentName, int newState, int flags)
componentName:组件名称
newState:组件新的状态,可以设置三个值,分别是如下:
不可用状态:COMPONENT_ENABLED_STATE_DISABLED
可用状态:COMPONENT_ENABLED_STATE_ENABLED
默认状态:COMPONENT_ENABLED_STATE_DEFAULT
flags:行为标签,值可以是DONT_KILL_APP或者0。 0说明杀死包含该组件的app
public int getComponentEnabledSetting(ComponentName componentName)
获取组件的状态

特别注意setComponentEnabledSetting 这个方法是需要系统权限的,也就是说用这个方法去实现必须可以拿到系统权限。
下面说下具体的实现,首先获取到需要禁止掉应用的信息,数据保存在ArrayList里面。AutoStartInfo用来
存储信息。

 public static List<AutoStartInfo> fetchAutoApps(Context mContext) {PackageManager pm = mContext.getPackageManager();Intent[] intents=getIntents();List<AutoStartInfo> appList = new ArrayList<AutoStartInfo>();String appName = null;Drawable icon = null;String packageName =null;boolean isSystem = false;boolean isenable = true;List<ResolveInfo> resolveInfoList=null;for (Intent intent : intents) {resolveInfoList = pm.queryBroadcastReceivers(intent, PackageManager.MATCH_DISABLED_COMPONENTS);for (int i = 0; i < resolveInfoList.size(); i++) {AutoStartInfo mAutoStartInfo = new AutoStartInfo();Log.d(TAG, "appName "+appName+" packageName "+packageName);mAutoStartInfo.setLabel(appName);mAutoStartInfo.setSystem(isSystem);mAutoStartInfo.setEnable(isenable);mAutoStartInfo.setIcon(icon);mAutoStartInfo.setPackageName(packageName);if(isAdd(appList,packageName)&&packageName!=null){appList.add(mAutoStartInfo);}appName = resolveInfoList.get(i).loadLabel(pm).toString();packageName = resolveInfoList.get(i).activityInfo.packageName;// Log.d(TAG, "packageName 1 " + packageName + " packageReceiver " + packageReceiver);icon = resolveInfoList.get(i).loadIcon(pm);ComponentName mComponentName2 = new ComponentName(resolveInfoList.get(i).activityInfo.packageName, resolveInfoList.get(i).activityInfo.name);if (pm.getComponentEnabledSetting(mComponentName2) == 2) {isenable = false;} else {isenable = true;}if ((resolveInfoList.get(i).activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {isSystem = true;} else {isSystem = false;}}}return appList;}

intents里面包含了所要禁止的广播种类,这里我禁止了5种广播。

 public static Intent[] getIntents(){return new Intent[]{new Intent("android.intent.action.BATTERY_CHANGED"),new Intent("android.intent.action.BOOT_COMPLETED"),new Intent("android.net.conn.CONNECTIVITY_CHANGE"),new Intent("android.intent.action.LOCALE_CHANGED"),new Intent("android.intent.action.USER_PRESENT")};}

这里的isAdd()方法用来限制添加相同的包名,因为有些应用可能注册了这里的几个广播。

 private static Boolean isAdd(List<AutoStartInfo> list, String packageName){for (AutoStartInfo autoStartInfo : list) {if (packageName.equals(autoStartInfo.getPackageName())) {Log.d("appListadd", "getPackageName " + autoStartInfo.getPackageName() + " packageName " + packageName);return false;}}return true;}

AutoStartInfo.java类保存信息

public class AutoStartInfo {private String label;private String packageName;private Drawable icon;private String name;private String packageReceiver;private String desc;/**  是否是系统进程. */public boolean isSystem;public boolean isenable;public String getLabel() {return label;}public void setLabel(String label) {this.label = label;}public String getPackageName() {return packageName;}public void setPackageName(String packageName) {this.packageName = packageName;}public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}public Drawable getIcon() {return icon;}public void setIcon(Drawable icon) {this.icon = icon;}public String getName() {return name;}public void setName(String name) {this.name = name;}public boolean isSystem() {return isSystem;}public void setSystem(boolean isSystem) {this.isSystem = isSystem;}public boolean isEnable() {return isenable;}public void setEnable(boolean enable) {this.isenable = enable;}public String getPackageReceiver() {return packageReceiver;}public void setPackageReceiver(String packageReceiver) {this.packageReceiver = packageReceiver;}
}

布局的话比较简单,一个ListView,ListView的item里面放一个Switch来控制开关,这里就不贴代码了。
在Adapater里面实现相关逻辑。

holder.disable_switch.setOnCheckedChangeListener(null);Log.i(TAG, " item.getPackageName() "+item.getPackageName()+"getView Boolean= " + getSharedPreferences(mContext,item.getPackageName(),false));if (getSharedPreferences(mContext,item.getPackageName(),false)) {holder.disable_switch.setChecked(true);} else {holder.disable_switch.setChecked(false);}holder.disable_switch.setOnCheckedChangeListener(new SwitchButtonChangeListener(item.getPackageName()));

这里本来是很简单的代码,但是我在使用的时候一直有问题,把switch的开关打开,然后滑动listView,开关又自动关闭了。在网上有人解决了,就是加上holder.disable_switch.setOnCheckedChangeListener(null)这句。

这里我使用SharedPreferences来保存数据,用包名来当key.

 private void operateSharedPreferences(Context context,String packageName,Boolean value){SharedPreferences preferences=context.getSharedPreferences("user",Context.MODE_PRIVATE);SharedPreferences.Editor editor=preferences.edit();editor.putBoolean(packageName,value);editor.commit();}private Boolean getSharedPreferences(Context context,String packageName,Boolean value){SharedPreferences preferences=context.getSharedPreferences("user", Context.MODE_PRIVATE);boolean bool=preferences.getBoolean(packageName, value);return bool;}

SwitchButtonChangeListener的实现,把packageName传进去

    private class SwitchButtonChangeListener implements CompoundButton.OnCheckedChangeListener {private String mPackageName ;SwitchButtonChangeListener(String packageName){mPackageName= packageName;}@Overridepublic void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {diasableApp(mPackageName,isChecked);}
}

最核心的方法diasableApp(),里面包含了数据的存储和是否接受相关的广播

 private void diasableApp(String packageName,Boolean isDiasableApp) {Intent[] intents=BootStartUtils.getIntents();List<String> listReceiver = BootStartUtils.addReceiver(intents, mContext.getPackageManager(), packageName);controlBroadcastReceiver(mContext,packageName,listReceiver,isDiasableApp);notifyDataSetChanged();operateSharedPreferences(mContext,packageName,isDiasableApp);}
private void  controlBroadcastReceiver(Context context,String packageName,List<String> broadcastReceiverName,boolean isStop){PackageManager pm=context.getPackageManager();for (String s : broadcastReceiverName) {ComponentName componentName = new ComponentName(packageName, s);if (isStop == true){ //禁止接收相关的广播            pm.setComponentEnabledSetting(componentName,PackageManager.COMPONENT_ENABLED_STATE_DISABLED,PackageManager.DONT_KILL_APP);}else {//允许接收相关的广播    pm.setComponentEnabledSetting(componentName,PackageManager.COMPONENT_ENABLED_STATE_ENABLED,PackageManager.DONT_KILL_APP);}}}

到此,这个功能就基本上实现了,附上一张效果图。

源码下载地址:

android 应用自启管理相关推荐

  1. android应用自启分析与S4启动列表

     揭秘:手机软件自启原理 大家都会想知道,这些软件不是我主动运行的,到底是如何自己运行起来的呢?接下来我们将简单讲讲软件自启的方式和原理. 以下内容有些偏技术,读起来可能有些晦涩,还请耐心拜读. ...

  2. Android Studio配置统一管理依赖版本号引用

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 本Demo采用的是其中一个方案,其他方案请阅读参考资料<Android Studio中统一管理版本号引用配置> 使用步骤 ...

  3. android qq分组展开,Android仿qq分组管理的第三方库

    本文实例为大家分享了Android仿qq分组管理的第三方库,供大家参考,具体内容如下 下面先看效果 我们点击展开与折叠分组的功能在库里面是已经封装好的,只能把它已入到项目中,就可以直接用了,十分的方便 ...

  4. android fragment 管理器,Android Fragment 與 Fragment管理器

    Android Fragment 與 Fragment管理器 首先談談Fragement的需求 過去開發人員認為界面之間的跳轉只需要使用多個activity組成就行了: 例如下圖中,在Activity ...

  5. 在Android中查看和管理sqlite数据库

    在Android中查看和管理sqlite数据库 在Android中可以使用Eclipse插件DDMS来查看,也可以使用Android工具包中的adb工具来查看.android项目中的sqlite数据库 ...

  6. Android Sprd省电管理(二)应用省电模式设置流程

    在Android Sprd省电管理(一)appPowerSaveConfig.xml,我们介绍了appPowerSaveConfig.xml的主要参数的意义,这一篇我们介绍下,怎么设置应用的各种省电模 ...

  7. Android隐藏的权限管理机制:AppOps

    最近整理以前开发中的笔记,发现有点零乱,遂决定将这些笔记整理迁移到 CSDN 上,分享出来与大家一起交流学习.如果有发现不当或有待商榷的地方,欢迎大家拍砖和指正.废话结束,进入本文正题:Android ...

  8. Android 引导页开发管理2

    <Android 引导页开发管理1>说明的是连续页面的闪烁效果,本次文章显示的是,一张效果效果图等待3s后进入主页面. 后续开发可以显示一段flash或者其他效果图看看. 1.splash ...

  9. root禁止app后台自启,手机免root自启管理

    怎么禁止app后台启动 怎么禁止app后台启动 手机如果有自带安全管家应该可以禁止软体自启.若没有,获取ROOT许可权,再去下载类似于360等安全管家进行禁止自启. 仅仅针对安卓手机 怎么禁止程式后台 ...

  10. Android Gradle Composing builds 管理三方依赖

    Android Gradle Composing builds 管理三方依赖 Android Gradle Composing builds 管理三方依赖 Gradle Composing build ...

最新文章

  1. php静态页面缓存,php处理静态页面:页面设置缓存时间实例
  2. WinCE下串口虚拟软件
  3. 线性代数:第四章 向量组的线性相关性(2)向量空间 线性方程组解的结构
  4. 《Debug Hacks》和调试技巧【转】
  5. java 变成题_Java 习题8 参考答案及解析
  6. 移动端常用的四个框架
  7. js与C#服务端 json数据交互
  8. Linux初步(一)——关于操作系统的启动
  9. excel VBA 编程,数据处理,并画图,详细代码,加解释
  10. DHT11修改stm32引脚的笔记
  11. 司空见惯 - 大哲学家康德的作息时间表
  12. Codeforces 364D Ghd(随机化)
  13. Hadoop HA_Yarn HA 集群的搭建
  14. GIS(地理信息系统/地理信息科学)怎么评职称?
  15. 一个基于OpenDDS的股票报价Stock Quote和交易exchange 的完整用例介绍
  16. 宏转录组方法_土壤宏转录组RNA的提取方法评价
  17. xshell用无线网远程连接linux失败_vnc远程控制软件怎么用,3个步骤教你vnc远程控制软件怎么用...
  18. Structured Program I – Print a Frame
  19. 如何用scanf语句为字符指针数组赋值
  20. Idea将Java文件导出jar包

热门文章

  1. smoothdraw4_使用SmoothDraw享受徒手绘制和图像修改
  2. 面向开发的内存调试神器,如何使用ASAN检测内存泄漏、堆栈溢出等问题
  3. Largest Rectangle in a Histogram 题解 Python
  4. fedora30解决Rhythmbox MP3中文歌曲歌名乱码
  5. Java开发入门学习线路图+配套Java基础视频教程分享
  6. Treedp贪吃的九头龙详解
  7. TNS-12555: TNS:permission denied错误解决
  8. python dask_使用Python并行框架Dask处理和分析大规模时空数据
  9. python办公自动化(6)——读取word文档
  10. 7-6 536 判定子串