权限
Access 用来检查和申请权限。无障碍、悬浮窗、图色、通知、媒体、文件、位置、蓝牙等,都由开发者在脚本里自行检查;未开启时弹窗或跳转设置引导用户打开。
系统默认需要哪几项,见 开发环境。
if (!Access.isAccessibilityServiceEnabled()) {
Dialogs.confirm('温馨提示', '请开启无障碍权限', function (result) {
Access.openAccessibilityServiceSetting();
System.exit();
});
}| 权限 | 何时需要 |
|---|---|
| 无障碍 | 找节点、点击、输入、滑动 |
| 悬浮窗 | 计时、连点两次停任务、常亮、后台弹窗 |
| 后台弹窗 | 部分机型从后台拉起其它 App |
| 图色(录屏) | 截图、找图、找色、识字、屏幕录像 |
| 通知 | 读通知栏 |
| 媒体 | 读相册、视频、音频 |
| 文件 | 读写外部存储 |
| 位置 | Device.getLocation() |
| 蓝牙 | Hid.initBluetooth |
| 短信 | Sms.startListening |
| 修改系统设置 | Device.setBrightness 等 |
| 电池优化豁免 | 长时间后台运行、避免被省电策略杀掉 |
被永久拒绝(用户点了「不再询问」)时,再调 request* 无效,要打开设置页让用户手动开。
在 DeekeScript Pro → 示例 → 接口 → 权限 Access 可逐项点测检测与申请;展厅封装见 common/permission.js 的 ensureXxx()。源码:deekeScriptV2Demo。
无障碍
找节点和手势都依赖无障碍。运行前用 Access.isAccessibilityServiceEnabled() 检查;未开则引导用户去 openAccessibilityServiceSetting()。
if (!Access.isAccessibilityServiceEnabled()) {
Dialogs.confirm('温馨提示', '请开启无障碍权限', function (result) {
Access.openAccessibilityServiceSetting();
System.exit();
});
}悬浮窗
悬浮窗用来显示运行时长、连点两次停止、保持常亮、后台拉起 App、后台弹 FloatDialogs。运行前用 Access.isFloatWindowsEnabled() 检查;未开则 openFloatWindowsSetting()。
if (!Access.isFloatWindowsEnabled()) {
Dialogs.confirm('温馨提示', '请开启悬浮窗权限', function (result) {
Access.openFloatWindowsSetting();
System.exit();
});
}isBackgroundAlertEnabled()
返回: {boolean} 后台弹窗是否已开
部分机型没开这项就无法从后台打开其它 App。
if (!Access.isBackgroundAlertEnabled()) {
Dialogs.confirm('温馨提示', '请开启后台弹窗权限', function (result) {
Access.openBackgroundAlertSetting();
System.exit();
});
}openBackgroundAlertSetting()
打开后台弹窗的系统设置页。
isMediaProjectionEnable()
返回: {boolean} 录屏 / 截图是否已授权
if (!Access.isMediaProjectionEnable()) {
Dialogs.confirm('温馨提示', '请开启屏幕截图权限', function (result) {
Access.openMediaProjectionSetting();
System.exit();
});
}openMediaProjectionSetting()
打开录屏授权页。截图与屏幕录像共用此授权。
hasNotificationAccess()
返回: {boolean} 是否能读通知
if (!Access.hasNotificationAccess()) {
Access.requestNotificationAccess();
System.exit();
}requestNotificationAccess()
打开通知读取授权。用户操作完再继续跑任务。
hasMediaReadPermission()
返回: {boolean} 是否能读相册、视频等媒体
Android 13+ 对应 READ_MEDIA_IMAGES / READ_MEDIA_VIDEO,更低版本对应存储读权限。访问相册见 MediaStore。
isMediaPermissionPermanentlyDenied()
返回: {boolean} 媒体权限是否被永久拒绝
requestMediaPermissions()
弹出系统媒体权限框。已被永久拒绝时不要调这个,改走 openPermissionSettings。
if (!Access.hasMediaReadPermission()) {
if (Access.isMediaPermissionPermanentlyDenied()) {
Dialogs.show('提示', '需要媒体权限才能继续,请在设置中开启');
Access.openPermissionSettings();
System.exit();
} else {
Access.requestMediaPermissions();
}
}hasStoragePermission()
返回: {boolean} 是否有外部存储读写权限
isStoragePermissionPermanentlyDenied()
返回: {boolean} 存储权限是否被永久拒绝
requestStoragePermission()
弹出存储权限框。
if (!Access.hasStoragePermission()) {
if (Access.isStoragePermissionPermanentlyDenied()) {
Access.openPermissionSettings();
} else {
Access.requestStoragePermission();
}
}openPermissionSettings()
打开当前应用的权限设置页。媒体、存储、位置被永久拒绝时用这个。
hasLocationPermission()
返回: {boolean} 是否有定位权限
对应 ACCESS_FINE_LOCATION / ACCESS_COARSE_LOCATION。有精确位置时同时具备粗略位置。取值见 Device。
isLocationPermissionPermanentlyDenied()
返回: {boolean} 定位权限是否被永久拒绝
requestLocationPermissions()
弹出定位权限框。
if (!Access.hasLocationPermission()) {
if (Access.isLocationPermissionPermanentlyDenied()) {
Dialogs.show('提示', '需要位置权限才能继续,请在设置中开启');
Access.openPermissionSettings();
System.exit();
} else {
Access.requestLocationPermissions();
System.sleep(1000);
}
} else {
let location = Device.getLocation();
if (location) {
console.log(location.latitude, location.longitude);
}
}hasBluetoothConnectionPermission()
返回: {boolean} 是否有蓝牙连接权限
蓝牙 Hid 需要 BLUETOOTH_CONNECT / BLUETOOTH_SCAN。Android 12(API 31)以下不用申请。见 Hid 方法。
isBluetoothPermissionPermanentlyDenied()
返回: {boolean} 蓝牙权限是否被永久拒绝
requestBluetoothConnectionPermission()
弹出蓝牙权限框。
openBluetoothPermissionSettings()
打开应用详情页,让用户手动打开蓝牙权限。
if (!Access.hasBluetoothConnectionPermission()) {
if (Access.isBluetoothPermissionPermanentlyDenied()) {
Dialogs.show('提示', '需要蓝牙权限才能继续,请在设置中开启');
Access.openBluetoothPermissionSettings();
System.exit();
} else {
Access.requestBluetoothConnectionPermission();
System.sleep(1000);
}
} else {
Hid.initBluetooth(context);
}短信 / 摄像头 / 麦克风 / 修改系统设置
| 方法 | 说明 |
|---|---|
hasSmsPermission() / requestSmsPermission() | 短信接收(见 Sms) |
isSmsPermissionPermanentlyDenied() | 短信权限永久拒绝 |
hasCameraPermission() / requestCameraPermission() | 摄像头(Images.takePhoto) |
isCameraPermissionPermanentlyDenied() | 摄像头权限永久拒绝 |
hasRecordAudioPermission() / requestRecordAudioPermission() | 麦克风(Audio.startRecord) |
isRecordAudioPermissionPermanentlyDenied() | 麦克风权限永久拒绝 |
canWriteSettings() / openWriteSettings() | 亮度等「修改系统设置」 |
isIgnoringBatteryOptimizations() | 是否已忽略电池优化(省电白名单) |
requestIgnoreBatteryOptimizations() | 弹出系统确认框,请求忽略电池优化 |
openIgnoreBatteryOptimizationSettings() | 打开系统「电池优化」列表(与底座「电池优化豁免」同一入口) |
if (!Access.hasCameraPermission()) {
if (Access.isCameraPermissionPermanentlyDenied()) {
Access.openPermissionSettings();
} else {
Access.requestCameraPermission();
}
}if (!Access.canWriteSettings()) {
Access.openWriteSettings();
}电池优化 / 省电限制
长时间后台跑脚本时,建议引导用户把本应用加入「不优化 / 无限制」。与底座设置页「电池优化豁免」同一系统入口。
| 方法 | 说明 |
|---|---|
isIgnoringBatteryOptimizations() | 是否已忽略电池优化;Android 6 以下视为 true |
requestIgnoreBatteryOptimizations() | 弹出系统确认框;已忽略返回 true;失败会打开设置列表并返回 false |
openIgnoreBatteryOptimizationSettings() | 打开系统电池优化应用列表,用户自行设为不优化 |
if (!Access.isIgnoringBatteryOptimizations()) {
Dialogs.confirm('温馨提示', '请允许忽略电池优化,避免自动化被系统杀掉', function (ok) {
if (ok) {
Access.requestIgnoreBatteryOptimizations();
// 部分机型对话框无效时:
// Access.openIgnoreBatteryOptimizationSettings();
}
});
}