Master Android Permission Management: Runtime Checks, Compatibility, and Settings Navigation
This article explains Android permission fundamentals, how to perform runtime permission checks across different SDK levels, compatibility strategies for older devices, and practical methods to jump directly to the app's permission management screen on various OEM ROMs.
Introduction
This article covers several aspects of Android permission management:
Background of Android permissions;
Permission checking and compatibility;
Jumping to the app's permission management page.
1. Android Permission Background
Google introduced runtime permission management in Android 6.0 (API 23). Before Android 6.0, permissions declared in AndroidManifest.xml were granted at install time, which could cause security issues. Since Android 6.0, permissions are divided into two categories:
(1) Normal Permissions – do not involve user privacy and are granted automatically (e.g., vibration, network access).
(2) Dangerous Permissions – involve user privacy and must be granted at runtime (e.g., reading SIM state, contacts, external storage).
Use adb shell pm list permissions -d -g to view dangerous permission groups.
Dangerous permissions are organized into groups; granting any permission in a group grants the whole group.
2. Permission Checking and Compatibility
Three main scenarios are considered:
(1) targetSdkVersion ≥ 23 on devices running Android 6.0+ (API 23+)
Permissions are requested at runtime. Use ContextCompat.checkSelfPermission to check, ActivityCompat.shouldShowRequestPermissionRationale to decide whether to show an explanation, and ActivityCompat.requestPermissions to request the permission.
Check if permission is granted ( ContextCompat.checkSelfPermission).
If an explanation is needed, show a custom UI ( ActivityCompat.shouldShowRequestPermissionRationale).
If no explanation is needed, request the permission directly ( ActivityCompat.requestPermissions).
(2) targetSdkVersion < 23 on devices running Android 6.0+ (API 23+)
The old install‑time permission model is used, but users can later disable permissions in the settings, which may affect app functionality.
(3) Devices running Android versions below 6.0 (API < 23)
Although the old model applies, some Chinese ROMs allow users to toggle permissions before Android 6.0, so compatibility handling is still required.
During development, the author encountered issues with the READ_PHONE_STATE permission causing failures when the permission was disabled. Several attempts were made to detect the permission state:
(1) try‑catch around permission‑using code – ineffective because the internal method already catches exceptions.
(2) ContextCompat.checkSelfPermission – works on API 23+ but fails on lower APIs.
(3) PermissionChecker – internally uses AppOpsManagerCompat, which was added in API 19.
(4) AppOpsManager – provides checkOp methods (hidden for API < 23, public for API ≥ 23). Reflection is required for the integer‑based version:
AppOpsManager::checkOp(int op, int uid, String packageName)On API < 23, the operation constant for READ_PHONE_STATE (51) does not exist, causing reflection to fail.
Version‑specific _NUM_OP values were examined (e.g., API 23 has 62 ops, API 22 has 48). This explains why certain ops are unavailable on older versions.
Third‑party permission libraries such as PermissionsDispatcher and AndPermission were also referenced.
3. Jumping to the App Permission Management Page
Because of Android fragmentation, a single method cannot handle all OEM ROMs. Two main approaches are presented:
(1) Directly open the system settings page
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.fromParts("package", getPackageName(), null));
try {
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}This works universally but requires the user to locate the specific app's permission settings manually.
(2) Use OEM‑specific intents
Examples for MIUI:
// MIUI 6/7
Intent localIntent = new Intent("miui.intent.action.APP_PERM_EDITOR");
localIntent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.AppPermissionsEditorActivity");
localIntent.putExtra("extra_pkgname", context.getPackageName());
try { startActivity(localIntent); } catch (Exception e) { e.printStackTrace(); }
// MIUI 8
Intent localIntent = new Intent("miui.intent.action.APP_PERM_EDITOR");
localIntent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.PermissionsEditorActivity");
localIntent.putExtra("extra_pkgname", context.getPackageName());
try { startActivity(localIntent); } catch (Exception e) { e.printStackTrace(); }Activity names differ between MIUI versions, so using the wrong intent can cause crashes.
(3) Discover the activity name for a specific ROM
For Huawei P8, the steps are:
Open the app's permission page manually.
Use adb shell dumpsys activity | grep "mFocusedActivity" to obtain the current activity.
Alternatively, use an Activity Tracer tool.
These methods help developers find the correct activity to launch.
References Working with System Permissions – https://developer.android.com/training/permissions/index.html Android version _NUM_OP lookup – http://grepcode.com/search?query=android.app.AppOpsManager&n= PermissionsDispatcher – https://github.com/hotchemi/PermissionsDispatcher AndPermission – https://github.com/yanzhenjie/AndPermission Android OEM permission page guide – http://www.jianshu.com/p/b5c494dba0bc Android development tools article – http://www.jianshu.com/p/672d64fdc486
Tencent TDS Service
TDS Service offers client and web front‑end developers and operators an intelligent low‑code platform, cross‑platform development framework, universal release platform, runtime container engine, monitoring and analysis platform, and a security‑privacy compliance suite.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
