AppOps是Android 自4.3加入的应用权限授权管理框架,虽然到了后来6.0引入了另外一套方案Android Runtime Permission,但是 AppOps并没有被废弃掉,它依然存在于系统框架内,只不过没有图形管理入口而已,但是依然保留并增加了API,而且AppOps命令行管理工具依然可用。我们所用到的就是AppOps Command line utility。
1
2
3
4
5
6
7
8
9
|
usage
:
appops
set
[
--
user
<
USER_ID
>
]
<
PACKAGE
>
<
OP
>
<
MODE
>
appops
get
[
--
user
<
USER_ID
>
]
<
PACKAGE
>
[
<
OP
>
]
appops
reset
[
--
user
<
USER_ID
>
]
[
<
PACKAGE
>
]
<
PACKAGE
>
指定的应用包名
<
OP
>
指定一项
AppOps
操作权限
.
<
USER_ID
>
指定系统用户
ID
(
5.0引入的多用户
),如果未指定则默认当前登录用户
(可选
)
specified
,
the
current
user
is
assumed
.
<
allow
|
ignore
|
deny
|
default
>
allow
放行权限,
ignore表示拒绝权限,但是应用不知道自己的权限被拒绝
(这个选项用来对付国内流氓权限
),
deny明确拒绝权限,并告知应用权限申请被拒绝,
default恢复默认的设置
<
br
>
|
所有的OP(Operations),即操作权限列表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
COARSE_LOCATION
:
低精度定位
FINE_LOCATION
:
高精度定位
OP_READ_PHONE_STATE
:
读取电话信息权限
READ_EXTERNAL_STORAGE
:
读取外置存储权限
WRITE_EXTERNAL_STORAGE
:
写入外置存储权限
RUN_IN_BACKGROUND
:
后台运行服务权限,禁用后系统将在应用进入后台几分钟后将后台服务杀死
GPS
:
GPS
VIBRATE
:
震动
READ_CONTACTS
:
读取通讯录
WRITE_CONTACTS
:
写入通讯录
READ_CALL_LOG
:
读取通话记录
WRITE_CALL_LOG
:
写入通话记录
READ_CALENDAR
:
读取日历
WRITE_CALENDAR
:
写入日历
WIFI_SCAN
:
扫描
Wifi热点
POST_NOTIFICATION
:
发布通知
WAKE_LOCK
:
唤醒锁
CALL_PHONE
:
拨打电话
READ_SMS
:
读取短信
WRITE_SMS
:
写入短信
SEND_SMS
:
发送短信
RECEIVE_SMS
:
接收短信
RECEIVE_EMERGECY_SMS
:
接受紧急短信息
RECEIVE_MMS
:
接受彩信
RECEIVE_WAP_PUSH
:
接受
Wap
Push消息
READ_ICC_SMS
:
接收运营商短信息
WRITE_ICC_SMS
:
写入运营商短信息
SYSTEM_ALERT_WINDOW
:
悬浮窗口权限
ACCESS_NOTIFICATIONS
:
读取通知
WRITE_SETTINGS
:
写入修改设置
CAMERA
:
摄像机权限
RECORD_AUDIO
:
录音
PLAY_AUDIO
:
播放音频
READ_CLIPBOARD
:
读取剪切板
WRITE_CLIPBOARD
:
写入修改剪切板
TAKE_MEDIA_BUTTONS
:
获取多媒体按钮权限
TAKE_AUDIO_FOCUS
:
获取声音焦点权限
GET_USAGE_STATS
:
获取应用使用情况权限
PROCESS_OUTGOING_CALLS
:
处理
(拦截
)外拨号码
USE_FINGERPRINT
:
使用指纹读取器
BODY_SENSORS
:
身体传感器
READ_CELL_BROADCASTS
:
读取移动蜂窝广播
MOCK_LOCATION
:
模拟位置
TURN_ON_SCREEN
:
关闭屏幕
GET_ACCOUNTS
:
获取系统账户列表
NEIGHBORING_CELLS
AUDIO_MASTER_VOLUME
AUDIO_VOICE_VOLUME
AUDIO_RING_VOLUME
AUDIO_MEDIA_VOLUME
AUDIO_ALARM_VOLUME
AUDIO_NOTIFICATION_VOLUME
AUDIO_BLUETOOTH_VOLUME
MONITOR_LOCATION
MONITOR_HIGH_POWER_LOCATION
MUTE_MICROPHONE
TOAST_WINDOW
PROJECT_MEDIA
ACTIVATE_VPN
WRITE_WALLPAPER
ASSIST_STRUCTURE
ASSIST_SCREENSHOT
ADD_VOICEMAIL
USE_SIP
|
appops 命令是Android系统的可执行程序,我们要运行,需要使用电脑USB连接手机并开启开发者调试,使用 adb shell [-e escape] [-n] [-Tt][-x] [command] 运行远程shell命令(如果没有给定命令则开启交互的shell终端) 在Android系统内执行shell命令。
现在,我们就要拿微信来举个例子,微信中文版在Android 6.0下强制要求读取电话状态信息、定位、读取写入外置存储权限,否则应用强制无法正常使用。我不知道大家怎么看待,我个人认为这三个权限都是可选的权限,微信就是在耍流氓。而我们就可以使用AppOps将其某项强制要求权限忽略掉,注意这里说的是忽略掉而不是禁用,如果单纯禁用在Android Runtime Permission内即可做到,但是微信可以感知到自己的权限被禁用,就会流氓的提示你应用无法使用。而AppOps可以忽略应用的权限申请,但是这个应用本身是无法感知判断的。在这里我们尝试禁用微信的读取电话状态信息权限、位置定位权限和后台服务运行权限(这个导致无法后台收消息):
1
2
3
4
|
adb
shell
appops
set
com
.tencent
.mm
OP_READ_PHONE_STATE
ignore
adb
shell
appops
set
com
.tencent
.mm
COARSE_LOCATION
ignore
adb
shell
appops
set
com
.tencent
.mm
FINE_LOCATION
ignore
adb
shell
appops
set
com
.tencent
.mm
RUN_IN_BACKGROUND
ignore
|
通过上面的操作,微信已经无法获取上述权限,而且再退出微信应用后,几分钟后微信后台服务(注意Foreground Service不会被关掉)都会被系统关掉,但是微信应用本身的主进程依然是作为空进程缓存在内存中,而不是被整个杀掉。
作为Android开发者,真心希望大家能够尽可能的克制规范自己的行为,少申请一些非必要权限,少运行一些后台活跃唤醒服务。