权限管理
统一管理 Android 运行时权限、系统设置类特殊权限及第三方权限 (如 Shizuku)。
脚本可动态检查是否已授权、动态申请权限,无需提前在模块 build.as 中声明。
from ascript.android.system import permission
权限来源
所有权限常量与 Java 层 airscript.system.Permission 保持同一份,底层由 PermissionCatalog 字典统一维护。
传入 key 时支持三种形式:
- Android 原生权限字符串:
"android.permission.CAMERA" - 模块定义的短别名:
"camera" - 常量引用(推荐):
permission.CAMERA
权限常量
Runtime 类(可弹窗直接申请)
| 常量 | 对应权限 | 说明 |
|---|---|---|
permission.CAMERA | android.permission.CAMERA | 摄像头 |
permission.RECORD_AUDIO / permission.MICROPHONE | android.permission.RECORD_AUDIO | 麦克风/录音 |
permission.READ_SMS / permission.SMS | android.permission.READ_SMS | 读取短信 |
permission.READ_PHONE_STATE / permission.PHONE | android.permission.READ_PHONE_STATE | 读取手机状态 |
permission.READ_PHONE_NUMBERS | android.permission.READ_PHONE_NUMBERS | 读取本机号码 (API 26+) |
permission.ACCESS_FINE_LOCATION / permission.LOCATION | android.permission.ACCESS_FINE_LOCATION | 精确定位 |
permission.ACCESS_COARSE_LOCATION | android.permission.ACCESS_COARSE_LOCATION | 粗略定位 |
permission.BLUETOOTH_CONNECT / permission.BLUETOOTH | android.permission.BLUETOOTH_CONNECT | 蓝牙连接 (API 31+) |
permission.BLUETOOTH_SCAN | android.permission.BLUETOOTH_SCAN | 蓝牙扫描 (API 31+) |
permission.POST_NOTIFICATIONS / permission.NOTIFICATION | android.permission.POST_NOTIFICATIONS | 发送通知 (API 33+) |
permission.READ_CONTACTS / permission.CONTACTS | android.permission.READ_CONTACTS | 读取通讯录 |
permission.READ_EXTERNAL_STORAGE / permission.STORAGE | android.permission.READ_EXTERNAL_STORAGE | 读取外部存储 |
permission.WRITE_EXTERNAL_STORAGE | android.permission.WRITE_EXTERNAL_STORAGE | 写入外部存储 |
Settings 类(需跳转系统设置页手动勾选)
| 常量 | 说明 |
|---|---|
permission.ACCESSIBILITY_SERVICE | 辅助功能(无障碍) |
permission.NOTIFICATION_LISTENER | 通知监听 |
permission.USAGE_STATS | 应用使用情况访问 |
permission.SYSTEM_ALERT_WINDOW / permission.OVERLAY | 悬浮窗 |
permission.WRITE_SETTINGS | 修改系统设置 |
permission.MANAGE_EXTERNAL_STORAGE | 所有文件访问 (API 30+) |
permission.INSTALL_PACKAGES | 安装未知来源应用 (API 26+) |
第三方
| 常量 | 说明 |
|---|---|
permission.SHIZUKU | Shizuku 代理 |
结果码
request() 返回以下整数之一:
| 常量 | 值 | 说明 |
|---|---|---|
permission.GRANTED | 1 | 已授权 |
permission.DENIED | 0 | 被拒绝 |
permission.TIMEOUT | -1 | 超时 (用户长时间未响应) |
permission.UNSUPPORTED | -2 | 未注册的 key |
方法
检查权限
判断某权限当前是否已授予。
- 函数
permission.has(key:str) -> bool
- 参数
| 参数 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
| key | str | 是 | 权限常量、Android 原生权限字符串或短别名 |
- 返回值
bool: 已授权返回 True,否则 False。未注册的 key 也返回 False。
- 示例
from ascript.android.system import permission
if permission.has(permission.CAMERA):
print("摄像头已授权")
else:
print("摄像头未授权")
is_granted 是 has 的别名permission.is_granted(key) 与 permission.has(key) 完全等价,任选其一。
申请权限
动态发起权限申请。
- 函数
permission.request(key:str, timeout:int=30) -> int
- 参数
| 参数 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
| key | str | 是 | 权限常量、Android 原生权限字符串或短别名 |
| timeout | int | 否 | Runtime 类权限阻塞等待超时 (秒),默认 30 |
- 返回值
Runtime 与 Settings 类行为差异
- Runtime 类:弹出系统权限对话框,脚本阻塞等待用户操作。用户点允许/拒绝后立即返回,或
timeout秒后返回TIMEOUT。 - Settings 类:跳转到系统设置页,由用户手动勾选。函数立即返回
DENIED,脚本需自行通过has()轮询确认。 - 部分厂商 ROM(MIUI/EMUI 等)对后台启动 Activity 有严格限制。若当前脚本在后台运行而系统拒绝拉起权限弹窗,会超时返回
TIMEOUT。
- 示例 1:申请摄像头(Runtime 类)
from ascript.android.system import permission
code = permission.request(permission.CAMERA)
if code == permission.GRANTED:
print("用户已授权")
elif code == permission.DENIED:
print("用户拒绝")
elif code == permission.TIMEOUT:
print("超时未响应")
elif code == permission.UNSUPPORTED:
print("未知权限 key")
- 示例 2:申请辅助功能(Settings 类 + 轮询)
import time
from ascript.android.system import permission
if not permission.has(permission.ACCESSIBILITY_SERVICE):
# 跳转系统设置页,立即返回 DENIED
permission.request(permission.ACCESSIBILITY_SERVICE)
# 轮询等待用户勾选完成
for _ in range(60):
if permission.has(permission.ACCESSIBILITY_SERVICE):
break
time.sleep(1)
if permission.has(permission.ACCESSIBILITY_SERVICE):
print("辅助功能已开启")
- 示例 3:自定义超时
from ascript.android.system import permission
# 最多等待 60 秒
code = permission.request(permission.RECORD_AUDIO, timeout=60)
确保已授权
语法糖:已授权直接返回 True;否则发起申请并返回最终是否授权。
- 函数
permission.ensure(key:str, timeout:int=30) -> bool
- 参数
| 参数 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
| key | str | 是 | 权限常量、Android 原生权限字符串或短别名 |
| timeout | int | 否 | Runtime 类权限超时 (秒),默认 30 |
- 返回值
bool: 最终是否已授权。
- 示例
from ascript.android.system import permission
# 一行代码完成"检查+申请+判断"
if permission.ensure(permission.CAMERA):
# 摄像头可用,继续业务
open_scanner()
else:
print("摄像头权限未获取,无法扫码")
列出所有权限
列出字典中所有已注册的权限主 key,便于调试或动态界面。
- 函数
permission.list_all() -> list
- 返回值
list: 字符串列表,元素为 Android 原生权限字符串或 Settings 类自定义 key。
- 示例
from ascript.android.system import permission
for key in permission.list_all():
state = "已授权" if permission.has(key) else "未授权"
print(f"{key}: {state}")
进阶:与 build.as 预申请的关系
传统做法是在模块 build.as 中声明 permissions 字段,安装 / 启动时一次性预申请。
新的 permission 模块与这种方式互不冲突,两者可共存:
- 想让用户在安装模块时就批量授权 → 继续在
build.as声明 - 想在脚本运行过程中按需动态提权 → 使用
permission.request()
推荐
新脚本优先使用动态提权(按需申请),用户体验更好:
- 只在使用到摄像头那一步才申请摄像头权限
- 失败时可以在脚本里给出友好的提示或降级逻辑