argent-settings-permissions
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWhat this tool is for
工具用途
settings-permissionsIt is a test-setup / out-of-band tool, not a general permissions toggle. The default way to change a permission is still through the app - this tool is the exception for the cases the app can't reach.
settings-permissions这是一款测试设置/离线操作工具,而非通用权限切换工具。更改权限的常规方式仍是通过应用本身——仅当应用无法实现权限更改时,才使用本工具。
When to use it - and when NOT to
适用场景与禁用场景
Decide with this order. The first matching row wins.
| Situation | Do this | Why |
|---|---|---|
| The app has an in-app control for the permission (a toggle in its own settings screen) | Tap it in the app ( | It's real user behavior and exercises the flow you're testing. See |
| The app is about to ask (or just asked) and the system permission dialog is on screen | Tap the dialog ( | The app-triggered prompt is the natural path; answering it is what a user does. |
| You need the permission already granted/denied before the app runs, so no dialog interrupts the flow | Use this tool ( | The app can't pre-set its own permission; a real user would do it in Settings. This is the core use case. ( |
| The user already denied it and you need it on again | Use this tool ( | iOS never re-shows a dialog once denied - the only in-device path is the Settings app. This tool is the shortcut. |
| You need the first-run dialog to appear again (test the prompt itself, or reset dirty state) | Use this tool ( | Returns the permission to "not yet asked" so the app prompts on next use. |
| The permission is not one this tool supports on the target platform (see the support table) | Do NOT use this tool | It will return an "unsupported" error. Use the app dialog if the app triggers one, or navigate the real Settings app. |
| The setting isn't one of the 11 runtime permissions below (e.g. Wi-Fi, cellular data, dark mode, VPN, Focus) | Do NOT use this tool | Out of scope - drive the Settings app or the app's own UI instead. |
Rule of thumb: if a human tester could flip it inside the app, do that. Reach for only for a change a human would otherwise make in the system Settings app.
settings-permissions请按以下优先级判断,符合第一条即执行对应操作。
| 场景 | 操作建议 | 原因 |
|---|---|---|
| 应用内有该权限的控制开关(如应用自身设置界面中的切换按钮) | 在应用内点击开关(使用 | 这符合真实用户行为,且能测试你关注的流程。可参考 |
| 应用即将请求(或刚请求)权限,且系统权限对话框已弹出 | 点击对话框选项( | 应用触发的提示是自然流程,用户会直接回应。 |
| 需要在应用启动前就授予/拒绝权限,避免权限对话框打断测试流程 | 使用本工具(执行 | 应用无法预先设置自身权限,真实用户需进入系统设置操作。这是本工具的核心适用场景。(注:仅iOS平台的 |
| 用户已拒绝权限,现在需要重新启用该权限 | 使用本工具(执行 | iOS平台一旦用户拒绝权限,就不会再次弹出提示——唯一的设备内操作路径是进入系统设置。本工具可实现快捷操作。 |
| 需要重新显示首次运行的权限提示(测试提示本身,或重置脏状态) | 使用本工具(执行 | 将权限恢复为“未请求”状态,应用下次使用时会重新弹出提示。 |
| 目标平台不支持本工具管理该权限(详见支持表) | 请勿使用本工具 | 工具会返回“不支持”错误。若应用能触发权限对话框,则使用对话框;否则进入真实系统设置操作。 |
| 该设置不属于以下11项运行时权限(如Wi-Fi、蜂窝数据、深色模式、VPN、专注模式) | 请勿使用本工具 | 超出工具范围——请通过系统设置或应用自身界面操作。 |
经验法则:如果人工测试员可以在应用内完成权限切换,就直接操作应用。仅当人工需要进入系统设置才能更改权限时,再使用。
settings-permissionsSupported permissions & platform coverage
支持的权限与平台覆盖
| iOS simulator (TCC service) | Android ( |
|---|---|---|
| | |
| | |
| | |
| | |
| unsupported - no iOS equivalent; answer the app's dialog instead | |
| | |
| | |
| | |
| | |
| | |
| | unsupported - no Android runtime permission |
One abstract permission can map to several concrete Android permissions; which ones actually exist depends on the app's manifest and the device's API level (e.g. on API 33+ vs below it).
READ_MEDIA_*READ_EXTERNAL_STORAGE | iOS模拟器(TCC服务) | Android( |
|---|---|---|
| | |
| | |
| | |
| | |
| 不支持——iOS无对应机制;请直接回应应用的权限对话框 | |
| | |
| | |
| | |
| | |
| | |
| | 不支持——Android无对应运行时权限 |
一项抽象权限可能对应多个具体Android权限;实际生效的权限取决于应用的清单文件和设备的API级别(例如API 33+使用,低于该版本使用)。
READ_MEDIA_*READ_EXTERNAL_STORAGEActions
操作类型
- - pre-authorize the permission. Requires
grant.bundleId - - refuse it. Requires
deny. Use to test the app's "permission denied" path.bundleId - - return to the not-yet-asked state so the dialog reappears on next use. Always per-app (
resetrequired):bundleId- iOS: removes that app's TCC row. A device-wide reset (no bundleId) is not offered - on recent iOS runtimes it reports success but leaves existing per-app grants untouched, so it would report a change that never happened.
- Android: revokes the grant, then best-effort clears the user-set/user-fixed flags (flag-clearing first appears in Android 13 / API 33; the revoke is what counts toward success). Below API 33 (i.e. API 23-32, everywhere a user-fixed state can exist) flag-clearing is unavailable, so a there revokes the grant but cannot clear a "don't ask again" (user-fixed) state - the dialog may stay suppressed on those older devices.
reset
- ——预先授权权限,需指定
grant。bundleId - ——拒绝权限,需指定
deny,用于测试应用的“权限被拒绝”流程。bundleId - ——将权限恢复为“未请求”状态,下次使用应用时会重新弹出提示。始终针对单个应用(必须指定
reset):bundleId- iOS:移除该应用在TCC中的记录。不提供设备级重置(无)——在新版iOS运行时中,设备级重置会返回成功,但不会更改已有的应用权限,导致工具报告虚假的更改结果。
bundleId - Android:撤销权限授权,然后尽力清除用户设置/用户固定标记(标记清除功能从Android 13 / API 33开始支持;权限撤销是判断操作成功的标准)。在API 33以下(即API 23-32,存在用户固定状态的版本),无法清除标记,因此操作仅会撤销权限授权,但无法清除“不再询问”(用户固定)状态——在这些旧设备上,权限提示可能仍会被屏蔽。
reset
- iOS:移除该应用在TCC中的记录。不提供设备级重置(无
Parameters
参数说明
json
{
"udid": "<UDID-or-serial>",
"action": "grant",
"permission": "camera",
"bundleId": "com.example.app"
}- - target from
udid(iOS simulator UDID, or Android serial). Seelist-devices/argent-ios-simulator-setupto get one.argent-android-emulator-setup - -
action|grant|deny.reset - - one of the 11 names above.
permission - - iOS bundle id or Android package name. Required for every action.
bundleId
json
{
"udid": "<UDID-or-serial>",
"action": "grant",
"permission": "camera",
"bundleId": "com.example.app"
}- ——目标设备标识,来自
udid(iOS模拟器UDID或Android设备序列号)。可通过list-devices/argent-ios-simulator-setup获取。argent-android-emulator-setup - ——可选值:
action|grant|deny。reset - ——上述11种权限名称之一。
permission - ——iOS应用的Bundle ID或Android应用的包名。所有操作均需指定该参数。
bundleId
Platform behavior
平台行为
iOS simulator only. Edits the simulator's TCC store - always per-app ( required). There is no host-side TCC switch on a physical iPhone, so this tool does not apply to real iOS devices. The simulator must be booted first () - otherwise the tool fails with a "current state: Shutdown" error and surfaces the boot hint.
bundleIdboot-deviceAndroid emulator and physical device. Changes the app's runtime permissions over adb (and, for , best-effort clears the user-set/user-fixed flags - the revoke is what decides success; flag-clearing needs Android 13 / API 33+). Requirements:
android.permission.*reset- The app must be installed - the tool probes for the package first and errors clearly if it is missing (a transport/timeout failure surfaces adb's real cause, not a false "not installed").
- The app must declare the permission in its manifest. The package manager rejects any mapped permission the manifest doesn't request; those come back in the result's list. The action succeeds if at least one mapped permission sticks, and errors only if all of them were rejected.
skipped
仅适用于iOS模拟器:修改模拟器的TCC存储——始终针对单个应用(必须指定)。物理iPhone上没有主机端TCC开关,因此本工具不适用于真实iOS设备。模拟器必须先启动(调用)——否则工具会返回“当前状态:已关机”错误,并提示启动模拟器。
bundleIdboot-device适用于Android模拟器与物理设备:通过adb修改应用的运行时权限(执行操作时,会尽力清除用户设置/用户固定标记——权限撤销是判断操作成功的标准;标记清除需要Android 13 / API 33+)。要求:
android.permission.*reset- 应用必须已安装——工具会先检测应用是否存在,若未安装会明确报错(传输/超时失败会显示adb的真实原因,而非虚假的“未安装”提示)。
- 应用必须在清单文件中声明该权限。包管理器会拒绝所有清单文件未请求的映射权限,这些权限会出现在结果的列表中。只要至少一个映射权限生效,操作即视为成功;仅当所有映射权限均被拒绝时,操作才会报错。
skipped
Gotchas
注意事项
- Changing a permission can terminate a running app (system behavior on both platforms). Prefer setting permissions before ; if you change one while the app is running,
launch-appafterward.restart-app - Reset is per-app on both platforms - pass ; there is no reliable device-wide reset.
bundleId - A partial Android result is normal. lists what actually changed;
appliedlists mapped permissions the package manager rejected (usually not in the manifest, or gated by API level). Both together tell you what happened.skipped - A pre-launch suppresses the prompt on iOS only. On iOS a TCC denial answers the app's request, so no dialog appears. On Android a
denyclears the grant but sets no "user-fixed" flag, so the app's next request still shows the system dialog - a pre-launchdenythere tests the revoked state, not a suppressed prompt.deny - on iOS may be rejected by a simulator runtime that doesn't model the service (it varies by simruntime, not by the installed Xcode - a runtime can accept
cameraeven when the platform's own service list omits it). A rejection surfaces as a generic CoreSimulator error, so acamerafailure (unless it's the shutdown-simulator case, which gets the boot hint instead) is reported with a hint about the runtime's supported services.camera - needs the app installed first (iOS). Location authorization isn't stored in TCC and isn't applied to a bundle id until the app exists, so a pre-install
grant location/grant locationrecords nothing. On a local simulator the tool checks install state and errors clearly instead of reporting a false success; on a remote simulator it cannot probe install state, so a pre-install grant there reports success while recording nothing - make sure the app is installed before granting location remotely. (TCC-backed services likegrant location-always/cameracan be granted before install; they persist and apply on install.)photos
- 更改权限可能会终止运行中的应用(两个平台的系统行为)。建议在调用前设置权限;若在应用运行时更改权限,之后需调用
launch-app重启应用。restart-app - 重置操作在两个平台均针对单个应用——必须传入;不存在可靠的设备级重置方式。
bundleId - Android平台出现部分生效结果是正常现象。列表显示实际更改的权限;
applied列表显示被包管理器拒绝的映射权限(通常是清单文件未声明或受API级别限制)。两者结合可告知操作结果。skipped - 仅iOS平台的预启动操作会屏蔽权限提示。iOS平台的TCC拒绝操作会直接响应应用的权限请求,因此不会弹出对话框。Android平台的
deny操作仅会清除权限授权,但不会设置“用户固定”标记,因此应用下次请求权限时仍会弹出系统对话框——预启动deny操作测试的是权限被撤销的状态,而非屏蔽提示。deny - iOS平台的权限可能会被模拟器运行时环境拒绝(取决于模拟器运行时,而非安装的Xcode——即使平台服务列表中没有
camera,运行时仍可能支持)。拒绝会显示为通用CoreSimulator错误,因此camera操作失败(除非是模拟器关机的情况,会提示启动)时,会附带关于运行时支持服务的提示。camera - iOS平台授予权限需先安装应用。位置授权不存储在TCC中,且只有应用存在时才会绑定到Bundle ID,因此在安装应用前执行
location/grant location操作不会记录任何信息。在本地模拟器上,工具会检测应用安装状态并明确报错,而非报告虚假成功;在远程模拟器上,无法检测安装状态,因此预安装授予位置权限会报告成功但无实际效果——请确保远程模拟器上已安装应用,再授予位置权限。(基于TCC的服务如grant location-always/camera可在安装前授予,权限会保留并在应用安装后生效。)photos
Result
返回结果
Returns :
{ action, permission, bundleId, applied, skipped? }- - the platform-level services/permissions actually changed (the TCC service(s) on iOS; the
appliednames on Android).android.permission.* - - Android only, present when some mapped permissions were rejected but others succeeded.
skipped
The call fails when nothing could be applied - read the error; it names the reason: an unsupported permission for the platform ( on iOS, on Android), the app not installed (including a pre-install on iOS), a shutdown simulator (iOS), or every mapped permission being rejected (usually a missing manifest entry). A non-shutdown failure additionally hints about the simulator runtime's supported services (a shutdown-simulator failure gets the boot hint instead).
notificationsremindersgrant locationcamera返回:
{ action, permission, bundleId, applied, skipped? }- ——实际更改的平台级服务/权限(iOS平台为TCC服务;Android平台为
applied名称)。android.permission.* - ——仅Android平台存在,当部分映射权限被拒绝但其他权限生效时显示。
skipped
当没有任何权限生效时,调用会失败——请查看错误信息,原因包括:平台不支持该权限(iOS的、Android的)、应用未安装(包括iOS平台预安装时授予权限)、模拟器已关机(iOS)、所有映射权限均被拒绝(通常是清单文件未声明)。非关机状态下的操作失败还会附带关于模拟器运行时支持服务的提示(关机状态下的失败会提示启动模拟器)。
notificationsreminderslocationcameraExamples
示例
Pre-grant the camera before launching, so the app never prompts:
json
{ "udid": "<UDID>", "action": "grant", "permission": "camera", "bundleId": "com.example.app" }Test the denied path - refuse location, then launch and observe the fallback:
json
{ "udid": "<serial>", "action": "deny", "permission": "location", "bundleId": "com.example.app" }Reset notifications on Android so the first-run prompt appears again next launch:
json
{
"udid": "<serial>",
"action": "reset",
"permission": "notifications",
"bundleId": "com.example.app"
}Grant always-on location on Android (fans out to background + foreground automatically):
json
{
"udid": "<serial>",
"action": "grant",
"permission": "location-always",
"bundleId": "com.example.app"
}启动应用前预先授予相机权限,避免应用弹出提示:
json
{ "udid": "<UDID>", "action": "grant", "permission": "camera", "bundleId": "com.example.app" }测试权限被拒绝的流程——拒绝位置权限,然后启动应用并观察 fallback 逻辑:
json
{ "udid": "<serial>", "action": "deny", "permission": "location", "bundleId": "com.example.app" }重置Android应用的通知权限,让下次启动时重新显示首次运行提示:
json
{
"udid": "<serial>",
"action": "reset",
"permission": "notifications",
"bundleId": "com.example.app"
}授予Android应用始终允许位置权限(会自动包含后台与前台权限):
json
{
"udid": "<serial>",
"action": "grant",
"permission": "location-always",
"bundleId": "com.example.app"
}