Android 7.0 通过 AppOps 和 Android 8.0 一样禁止软件后台活动
众所周知,现在国内绝大多数的Android APP,不管是什么类型,都会在后台运行各种进程和服务,而且通过各种方式自启动和相互唤醒,耗费手机资源和电量。
为了提升用户体验,Android 8.0 对应用在后台运行时可以执行的操作施加了限制。点击【电池】—【后台活动】然后关闭,在退出应用后一会儿后台的服务就关了,同时可以有效控制软件的自启动和相互唤醒。
不过现在很多手机还在Android 7.0,在系统中并没有这个后台活动控制选项,比如我自己手中的HTC U Ultra。其实,这个功能本质上是通过 Android 原生权限管理 AppOps (Application Operations),设置RUN_IN_BACKGROUND 项实现的,并且在7.0中就已经可用了,只是并没有直接开放出来,但是可以通过ADB完成操作。虽然7.0后台控制不如8.0严格,但是对于不太流氓的软件,比如阿里系的淘宝、天猫、支付宝等,以及头条系的今日头条、抖音等,基本都可以控制住后台运行,不会出现打开WIFI开关后台一堆APP都开始运行的情况。
使用限制和效果
通过 AppOps 中的 RUN_IN_BACKGROUND 项,限制 APP 的后台运行仅适用于Android 7.0+。同时该方法并不完美,若手机已ROOT,推荐使用其它更彻底的方案。同时对于内置后台限制的安卓系统(MIUI、EMUI等),也不需使用该方法。
通过设置 RUN_IN_BACKGROUND 的效果,可以参考 https://zhuanlan.zhihu.com/p/22162719,而实际对于国内APP的限制效果,可以引用一下网上的结果:
美团系:
可以阻止美团、大众点评、猫眼之间的互相唤醒。
不能阻止大众点评自动唤醒(JobService),但唤醒频率很低。
阿里系:
可以大幅减少阿里系后台唤醒:
不能阻止支付宝唤醒高德地图(AMapService);
不能阻止飞猪唤醒支付宝 (Authenticated);
百度系:
不能阻止百度系(ShareService)相互唤醒;
不能阻止Uber被百度系唤醒(RegistrationReceiver);
其它:
不能阻止Bilibili自动唤醒(JobService),但唤醒频率很低。
对豆瓣、网易等APP效果明显;
总结:
该方法可阻止大多数后台唤醒。
禁止后台运行的Powershell脚本
实际用起来也很简单,这里给出一个个人写的Powershell脚本。GitHub上也有人比较系统地做了一个项目,有兴趣的可以去看看:https://github.com/Jiangyiqun/android_background_ignore
实际使用的话,首先需要保证可以通过ADB对手机进行USB调试,即安装过ADB和相关USB Driver,并且手机开启了USB调试。然后直接 Win + R 键运行 powershell_ise,拷贝下面的脚本,修改开头的两个参数,然后F5执行整个脚本就行。
需要修改的参数一个是 ADB 所在文件夹位置,$adbPath = 'C:/Tools/adb',即修改后 $adbPath 文件夹下有 adb.exe。
第二个参数 $appsToDisableRunInBackground 是所有需要禁止后台运行的 APP 包名,包名可以通过下面的命令获得,或者直接网上获得。
adb shell pm list packages # 获取所有包
adb shell pm list packages -3 # 获取所有第三方包
adb shell pm list packages -3 -f 'taobao' # 根据关键字“taobao”搜索第三方包
Powershell脚本内容
$adbPath = 'C:/Tools/adb'
$appsToDisableRunInBackground =
@('com.tencent.tws.gdevicemanager',
'com.eg.android.AlipayGphone')
$adbAppName = "$adbPathadb.exe"
$ExecutionContext.SessionState.Applications.Add($adbAppName)
Set-Alias -Name adb -Value $adbAppName
[Boolean]$IS_DEBUG = $true
# 获取设备列表及设备状态
adb devices
# 获取设备的状态 - device , offline or unknown
adb get-state
function Set-AndroidAppos([String]$appName, [String]$opName, [String]$value) {
if ($IS_DEBUG) { Write-Host "Executes command: adb shell cmd appops set $appName $opName $value" }
Invoke-Expression "adb shell cmd appops set $appName $opName $value"
}
function Set-AndroidApposIgnore([String]$appName, [String]$opName) {
Set-AndroidAppos($appName, $opName, 'ignore')
}
function Set-AndroidApposAllow([String]$appName, [String]$opName) {
Set-AndroidAppos($appName, $opName, 'allow')
}
function Set-AndroidAppRunInBackgroundIgnore([String]$appName) {
Set-AndroidApposIgnore($appName, 'RUN_IN_BACKGROUND')
}
foreach ($app in $appsToDisableRunInBackground) {
Set-AndroidAppRunInBackgroundIgnore $app
}
adb kill-server
脚本执行后的输出如下:
对每个应用都会简单打印实际执行的命令,例如:Executes command: adb shell cmd appops set com.tencent.tws.gdevicemanager RUN_IN_BACKGROUND ignore
如果正常执行,后继没有输出;如果包名不存在,则输出:Error: No UID for com.tencent.tws.gdevicemanager in user 0
重新允许后台运行
如果需要恢复APP的后台运行,可以将最后的 foreach 语句删除,换成下面的语句,在 $appsToEnableRunInBackground 写入所有需要允许后台执行的APP包名,然后执行脚本即可。
$appsToEnableRunInBackground = @('com.tencent.tws.gdevicemanager')
foreach ($app in $appsToEnableRunInBackground) {
Set-AndroidApposAllow($app, 'RUN_IN_BACKGROUND')
}
最后,祝愿大家都能控制住国内的流氓APP,还自己手机一个干净的后台环境。



手铁铁的小盆友
校验提示文案
ipxzerg
校验提示文案
Paradoxes
校验提示文案
手铁铁的小盆友
校验提示文案
Paradoxes
校验提示文案
ipxzerg
校验提示文案