Every capability outside the app's sandbox needs a permission declared in AndroidManifest.xml. A new Cordova 129 app asks for almost nothing:
apkanalyzer manifest permissions platforms/android/app/build/outputs/apk/debug/app-debug.apkandroid.permission.INTERNET com.example.booknest.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION
INTERNET comes from cordova-android's template, because nearly every app talks to a server. The second is a signature-level permission that the AndroidX 234 Core library defines for the app's own use with private broadcast receivers; no user ever sees it. Android sorts permissions by risk:
| Kind | Granted | Examples |
|---|---|---|
| Normal | Automatically at install | INTERNET, VIBRATE, ACCESS_NETWORK_STATE |
| Runtime (dangerous) | By the user, in a dialog, while the app runs | CAMERA, ACCESS_FINE_LOCATION, POST_NOTIFICATIONS |
| Signature | Only to apps signed with the same key | The AndroidX receiver permission above |
You rarely write these yourself: a plugin's plugin.xml adds its permissions (plugin.xml Wiring), and its Java code requests runtime ones through cordova-android's PermissionHelper when you call it, so the user sees the dialog in context (Permissions and Data). Your own additions go in a <config-file> (edit-config).
Declare only what you use: Google Play 1 reviews some permissions (SMS, call log, background location) under special policies. adb shell pm revoke com.example.booknest <permission> takes a grant back to test denial.