Android O实现限制自启&&限制后台&&杀活方案

本文探讨了Android O系统中如何限制应用自启和后台活动,包括广播接收、全家桶应用拉活、账户同步、JobScheduler等方式。同时分析了应用保活的常见策略,如提升服务优先级、前台服务等。提出了通过限制启动权限和AppOpsManager来管控后台行为的解决方案,但指出面对深度保活技术,如应用宝的六进程保活,仍存在挑战。
摘要由CSDN通过智能技术生成
  • 由 b178903294创建, 最后修改于12月 30, 2020

上回书说到android的powersave lowmemorykiller 等的后台清理机制,与系统如何保证应用不被杀掉的保活方案。我们为了自己的应用能够常驻后台提供了系统保活的机制。那么其他三防应用为了自己能够永生,各种手段无所不用其极,绕过各种系统的杀活机制来达到常驻后台干些见不得人的勾当。所以我们常常见到系统运行的好好的突然各种弹窗,突然的cpu占用飙升猝不及防的卡死········    即使我们信任的各种学习app后台罪行也是罄竹难书。

基于此,我们必须要想办法就惩治这些流氓,那必须的要拿出方案来解决这个棘手的问题。不巧,这个活儿被鄙人接下了。那么咱们先研究一下应用自启的原理吧,知己知彼百战不殆,知道他们的犯罪方法才能有针对性的防治。

一、应用自启常见套路

1.接收各种广播

原理就不多说了,网上很多文章都已经说过了,核心就是因为 Android 系统在很多时刻都会给所有的应用广播消息,比如 系统开机、电量低,网络状态变化等,只需自己静态注册广播接收者,然后接收系统发出的广播消息然后处理即可。

android.intent.action.BATTERY_CHANGED 持久的广播,包含电池的充电状态,级别和其他信息。
android.intent.action.BATTERY_LOW 标识设备的低电量条件。
android.intent.action.BATTERY_OKAY 标识电池在电量低之后,现在已经好了。
android.intent.action.BOOT_COMPLETED 在系统完成启动后广播一次。
android.intent.action.BUG_REPORT 显示报告bug的活动。
android.intent.action.CALL 执行呼叫数据指定的某人。
android.intent.action.CALL_BUTTON 用户点击"呼叫"按钮打开拨号器或者其他拨号的合适界面。
android.intent.action.DATE_CHANGED 日期发生改变。
android.intent.action.REBOOT 设备重启。

防治办法:禁掉接收这些广播的注册的activity

2.被其他全家桶应用拉活

此处典型的有:腾讯全家桶、百度全家桶、360全家桶、阿里系、抖音系、美团系·········

防治此类的方法就是能在google play下载的应用,绝对不要去国内的应用商城下载。(原理是,google play对应用各种都有严格限制,重点是应用互相拉活大多时候是为了推送广告,谷歌会要求广告进行分成)

3.系统账户同步机制拉活

手机系统设置里会有Account帐户一项功能,任何第三方APP都可以通过此功能将我们自己的APP注册到这个Account帐户中,并且将数据在一定时间内同步到服务器中去。系统在将APP帐户同步时,自动将未启动的APP进程拉活,具体操作参见Google官方demo

4.JobSchedule 机制拉活

JobScheduler允许在特定状态与特定时间间隔周期执行任务,所以我们也可以利用它的这个机制来完成拉活的功能,其效果就像是开启一个定时器,与普通定时器不同的是其调度由系统完成,也比较可靠稳定,但是会受到白名单等模式的影响,在某些ROM中甚至无法拉活。

5.其他和混合自启拉活

终极版就是该应用集合和所有的拉活自启方案。

二、应用保活常见套路

1.提升优先级 设为前台服务  (前排采坑: camera自动升级失败问题)

2. 1像素前台保活,由于前台可见activity系统为了保证用户体验,提升到了最高优先级,所以系统不会主动杀掉前台有显示界面的app

3.  循环播放无声音乐 原理同上

4. 利用系统Service机制拉活      将 Service 设置为 START_STICKY,利用系统机制在 Service 挂掉后拉活

5. 利用 Native 进程拉活  多进程守护 互相拉活

三、解决思路和方案

1.针对应用开机自启的应用,我们采用传统的disable掉其在AndroidManifest.xml中声明的activity。 那么我们怎么查询哪些activity声明了android.intent.action.BOOT_COMPLETED呢,这时候packageManager就尅一派上用场了。

PackageManager pm = mContext.getPackageManager();

        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED);

        List<ResolveInfo> resolveInfoList = pm.queryBroadcastReceivers(intent, PackageManager.GET_DISABLED_COMPONENTS);       //  参考     android 静态和动态设置 Receiver的 android:enabled值

//然后将对应的activity disable掉

 pm.setComponentEnabledSetting(cm, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);

ps:   pms里面有很多的queryIntent* 的查询方法,可以查询各种类型的activity和service, 都是很好用的查询工具

2.针对后台自启的应用,我们又要梳理一下后台启动流程了

先丢一张流程框架图:

我们启动服务的时候使用startService方法,其直接调用:

frameworks/base/core/java/android/app/ContextImpl.java

private ComponentName startServiceCommon(Intent service, boolean requireForeground,

        UserHandle user) {

    try {

        validateServiceIntent(service);

        service.prepareToLeaveProcess(this);

        ComponentName cn = ActivityManager.getService().startService(

            mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(

                        getContentResolver()), requireForeground,

                        getOpPackageName(), user.getIdentifier());

        if (cn != null) {

        <!--返回值是?的情况下就是后台启动service的异常-->

             if (cn.getPackageName().equals("?")) {

                throw new IllegalStateException(

                        "Not allowed to start service " + service + ": " + cn.getClassName());

            }

}

ContextImpl中只做了validateServiceIntent校验(target 21之后限制隐式启动),然后调用了AMS的startService方法。再看AMS中的实现:

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

@Override

public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType, boolean requireForeground, String callingPackage, int userId)

    throws TransactionTooLargeException { <

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值