当前位置:
文章详情

Android 7.0 通过 AppOps 和 Android 8.0 一样禁止软件后台活动

2019-02-08 15:49:05 4点赞 7收藏 5评论

众所周知,现在国内绝大多数的Android APP,不管是什么类型,都会在后台运行各种进程和服务,而且通过各种方式自启动和相互唤醒,耗费手机资源和电量。

为了提升用户体验,Android 8.0 对应用在后台运行时可以执行的操作施加了限制。点击【电池】—【后台活动】然后关闭,在退出应用后一会儿后台的服务就关了,同时可以有效控制软件的自启动和相互唤醒。

Android 7.0 通过 AppOps 和 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,还自己手机一个干净的后台环境。


展开 收起
5评论

  • 精彩
  • 最新
  • 请问一下大兄弟,给安卓权限伪信息目前有什么招吗?手机不root的情况下。colorOS6.1系统。谢谢🙏

    校验提示文案

    提交
    不root的话,基本没什么能做的,因为动不了应用的私有数据,系统层面我只知道 AppOps 可以在没有 root 的情况下通过 Adb 运行,可以看下 去看看,基本上所有的权限都有,可以将 apk 对应的权限设为 ignore 试试。

    校验提示文案

    提交
    谢谢指路!我先去学习学习!! [高兴] [高兴] [高兴]

    校验提示文案

    提交
    收起所有回复
  • 专业老哥!唉,辛苦科普的没人看,吹牛拍月亮的天天赚大钱。。。

    校验提示文案

    提交
  • Android 9下App ops权限设置无用,OxygenOS

    校验提示文案

    提交
提示信息

取消
确认
评论举报

相关文章推荐

更多精彩文章
更多精彩文章
最新文章 热门文章
7
扫一下,分享更方便,购买更轻松