### Grant All Runtime Permissions for Testing Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Use the `-g` option with the `adb shell install` command to automatically grant all runtime permissions when installing an app on an emulator or test device. This is useful for testing scenarios. ```shell adb shell install -g PATH_TO_APK_FILE ``` -------------------------------- ### Enforcing Permissions for Activities and Services Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Explains how permissions declared in the manifest are enforced when starting or binding to activities and services. A `SecurityException` is thrown if the caller lacks the required permission. ```APIDOC Activity Component Protection: - Use `android:permission` attribute in the `` tag. - Checked during `Context.startActivity()` and `Activity.startActivityForResult()`. - If caller lacks permission, a `SecurityException` occurs. Service Component Protection: - Use `android:permission` attribute in the `` tag. - Checked during `Context.startService()`, `Context.stopService()`, and `Context.bindService()`. - If caller lacks permission, a `SecurityException` occurs. ``` -------------------------------- ### Define Android Permission Label and Description Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Provides examples of string resources for defining the user-visible label and description of an Android permission. These strings are referenced in the manifest to inform users about the permission's purpose and potential risks. ```xml directly call phone numbers Allows the app to call non-emergency phone numbers without your intervention. Malicious apps may cause unexpected calls on your phone bill. ``` -------------------------------- ### Android: Create Attribution Context and Get Location (Java) Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md This Java code demonstrates creating an attribution context within an AppCompatActivity and subsequently obtaining a LocationManager to access device location information. It highlights the initialization of context for attribution purposes. ```Java public class SharePhotoLocationActivity extends AppCompatActivity { private Context attributionContext; @Override public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { attributionContext = createAttributionContext("sharePhotos"); } public void getLocation() { LocationManager locationManager = attributionContext.getSystemService(LocationManager.class); if (locationManager != null) { // Use "locationManager" to access device location information. } } } ``` -------------------------------- ### Android Foreground Services and Background Location Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Guidance on managing background location access and foreground services in Android. Avoid initiating foreground services from the background; use notifications or start services when the UI is visible. ```APIDOC https://developer.android.com/training/location/background Description: Implement background location access only as necessary. If your app must retain location access for a user-initiated ongoing task after navigating away, start a foreground service before going into the background. Related: Location access while app is visible, Degrade gracefully without location data. ``` -------------------------------- ### Android: Log Private Data Access with Attribution Tags Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md This code implements the AppOpsManager.OnOpNotedCallback interface to log details about private data access, including attribution tags and stack traces. It provides examples for both Kotlin and Java, covering onNoted, onSelfNoted, and onAsyncNoted events. ```Kotlin val appOpsCallback = object : AppOpsManager.OnOpNotedCallback() { private fun logPrivateDataAccess( opCode: String, attributionTag: String, trace: String) { Log.i(MY_APP_TAG, "Private data accessed. " + "Operation: $opCode\n " + "Attribution Tag:$attributionTag\nStack Trace:\n$trace") } override fun onNoted(syncNotedAppOp: SyncNotedAppOp) { logPrivateDataAccess(syncNotedAppOp.op, syncNotedAppOp.attributionTag, Throwable().stackTrace.toString()) } override fun onSelfNoted(syncNotedAppOp: SyncNotedAppOp) { logPrivateDataAccess(syncNotedAppOp.op, syncNotedAppOp.attributionTag, Throwable().stackTrace.toString()) } override fun onAsyncNoted(asyncNotedAppOp: AsyncNotedAppOp) { logPrivateDataAccess(asyncNotedAppOp.op, asyncNotedAppOp.attributionTag, asyncNotedAppOp.message) } } ``` ```Java @Override public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { AppOpsManager.OnOpNotedCallback appOpsCallback = new AppOpsManager.OnOpNotedCallback() { private void logPrivateDataAccess(String opCode, String attributionTag, String trace) { Log.i("MY_APP_TAG", "Private data accessed. " + "Operation: $opCode\n " + "Attribution Tag:$attributionTag\nStack Trace:\n$trace"); } @Override public void onNoted(@NonNull SyncNotedAppOp syncNotedAppOp) { logPrivateDataAccess(syncNotedAppOp.getOp(), syncNotedAppOp.getAttributionTag(), Arrays.toString(new Throwable().getStackTrace())); } @Override public void onSelfNoted(@NonNull SyncNotedAppOp syncNotedAppOp) { logPrivateDataAccess(syncNotedAppOp.getOp(), syncNotedAppOp.getAttributionTag(), Arrays.toString(new Throwable().getStackTrace())); } @Override public void onAsyncNoted(@NonNull AsyncNotedAppOp asyncNotedAppOp) { logPrivateDataAccess(asyncNotedAppOp.getOp(), asyncNotedAppOp.getAttributionTag(), asyncNotedAppOp.getMessage()); } }; AppOpsManager appOpsManager = getSystemService(AppOpsManager.class); if (appOpsManager != null) { appOpsManager.setNotedAppOpsCollector(appOpsCollector); } } ``` -------------------------------- ### Android App Activity Access Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Methods and permissions used by applications to access information about user activity, installed applications, and system services. ```APIDOC Android App Activity Access: AccessibilityService - Description: Base class for services that provide accessibility features. - Reference: https://developer.android.com/reference/android/accessibilityservice/AccessibilityService TextService - Description: Base class for services that provide text-related services. - Reference: https://developer.android.com/reference/android/service/textservice/package-summary QUERY_ALL_PACKAGES - Description: Allows an application to query information about all installed packages, regardless of whether they are visible to the user. - Type: Manifest Permission PackageManager.getInstalledApplications - Signature: getInstalledApplications(int flags) - Description: Returns a list of all installed applications on the device. - Parameters: - flags: Control which applications are returned (e.g., GET_META_DATA). - Returns: A List of ApplicationInfo objects. - Reference: Instrumentation API - Description: Provides facilities for instrumentation, allowing for testing and control of application execution. - Reference: https://developer.android.com/reference/android/app/Instrumentation Google Shortcuts Integration Library - Description: Library for creating and managing app shortcuts for better user engagement and discoverability. - Reference: about:/guide/topics/ui/shortcuts/creating-shortcuts#gsi-library ``` -------------------------------- ### Special Permission Check Methods Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Examples of custom access check functions for special permissions, which operate differently than standard runtime permissions. These methods are used to determine if an app has been granted a specific special permission. ```Java AlarmManager#canScheduleExactAlarms() // Checks if the app can schedule exact alarms. Environment#isExternalStorageManager() // Checks if the app has the MANAGE_EXTERNAL_STORAGE permission. ``` -------------------------------- ### Android Permissions Samples Repository Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md A GitHub repository containing sample applications that demonstrate the Android permissions workflow, including requesting and managing permissions at runtime. ```APIDOC Android Permissions Samples: URL: https://github.com/android/platform-samples/tree/main/samples/privacy/permissions Description: This repository provides practical code examples for implementing Android's permission model. It showcases: - Declaring permissions in the manifest. - Requesting runtime permissions from the user. - Handling user responses to permission requests. - Best practices for minimizing permission usage. Usage: Developers can clone this repository to study and adapt the provided code for their own applications to correctly handle permissions. ``` -------------------------------- ### Handle Permissions with ActivityResultLauncher (Kotlin) Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Demonstrates checking, showing rationale, and launching permission requests using `ActivityResultLauncher` in Kotlin. This approach leverages the modern Activity Result API for managing permission requests. ```Kotlin when { ContextCompat.checkSelfPermission( CONTEXT, Manifest.permission.REQUESTED_PERMISSION ) == PackageManager.PERMISSION_GRANTED -> { // You can use the API that requires the permission. } ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.REQUESTED_PERMISSION) -> { // In an educational UI, explain to the user why your app requires this // permission for a specific feature to behave as expected, and what // features are disabled if it's declined. In this UI, include a // "cancel" or "no thanks" button that lets the user continue // using your app without granting the permission. showInContextUI(...) } else -> { // You can directly ask for the permission. // The registered ActivityResultCallback gets the result of this request. requestPermissionLauncher.launch( Manifest.permission.REQUESTED_PERMISSION) } } ``` -------------------------------- ### Handle Permissions with ActivityResultLauncher (Java) Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Demonstrates checking, showing rationale, and launching permission requests using `ActivityResultLauncher` in Java. This approach leverages the modern Activity Result API for managing permission requests. ```Java if (ContextCompat.checkSelfPermission( CONTEXT, Manifest.permission.REQUESTED_PERMISSION) == PackageManager.PERMISSION_GRANTED) { // You can use the API that requires the permission. performAction(...); } else if (ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.REQUESTED_PERMISSION)) { // In an educational UI, explain to the user why your app requires this // permission for a specific feature to behave as expected, and what // features are disabled if it's declined. In this UI, include a // "cancel" or "no thanks" button that lets the user continue // using your app without granting the permission. showInContextUI(...); } else { // You can directly ask for the permission. // The registered ActivityResultCallback gets the result of this request. requestPermissionLauncher.launch( Manifest.permission.REQUESTED_PERMISSION); } ``` -------------------------------- ### Android Permission Request Lifecycle Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Explains the process of requesting permissions in Android, including checking status, showing rationale, and handling user responses. ```APIDOC ActivityCompat.requestPermissions(activity, permissions, requestCode) - Initiates a system-level permission request dialog. - Parameters: - activity: The Activity requesting the permission. - permissions: An array of permission strings to request. - requestCode: An integer request code to identify the request. ContextCompat.checkSelfPermission(context, permission) - Checks the current status of a single permission. - Parameters: - context: The application context. - permission: The permission string to check (e.g., "android.permission.CAMERA"). - Returns: PERMISSION_GRANTED or PERMISSION_DENIED. ActivityCompat.shouldShowRequestPermissionRationale(activity, permission) - Determines if the system should show a rationale for a permission. - Returns true if the user has previously denied the permission and the app has not requested it again. - Parameters: - activity: The Activity requesting the permission. - permission: The permission string to check. - Returns: Boolean indicating whether to show a rationale. ActivityResultContracts.RequestPermission - An AndroidX contract for requesting a single permission. - Simplifies permission request logic by managing request codes internally. - Usage: - Register for the activity result: `ActivityResultLauncher requestPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> { ... });` - Launch the request: `requestPermissionLauncher.launch(Manifest.permission.CAMERA);` ``` -------------------------------- ### Register Permission Request Launcher (Kotlin/Java) Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md This snippet demonstrates how to register an `ActivityResultLauncher` to handle permission requests using the `RequestPermission` contract. It includes a callback to process the user's granted or denied response. Dependencies on `androidx.activity` and `androidx.fragment` are required. ```kotlin val requestPermissionLauncher = registerForActivityResult(RequestPermission()) { isGranted: Boolean -> if (isGranted) { // Permission is granted. Continue the action or workflow in your // app. } else { // Explain to the user that the feature is unavailable because the // feature requires a permission that the user has denied. At the // same time, respect the user's decision. Don't link to system // settings in an effort to convince the user to change their // decision. } } ``` ```java private ActivityResultLauncher requestPermissionLauncher = registerForActivityResult(new RequestPermission(), isGranted -> { if (isGranted) { // Permission is granted. Continue the action or workflow in your // app. } else { // Explain to the user that the feature is unavailable because the // feature requires a permission that the user has denied. At the // same time, respect the user's decision. Don't link to system // settings in an effort to convince the user to change their // decision. } }); ``` -------------------------------- ### Kotlin: Create and Use Attribution Context Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md This Kotlin code demonstrates how to create an attribution context using `createAttributionContext()` within an Activity's `onCreate()` method. This context is then used to obtain system services, associating subsequent data access with the specified attribution tag. This helps in tracing data access back to specific logical parts of the app. ```kotlin class SharePhotoLocationActivity : AppCompatActivity() { lateinit var attributionContext: Context override fun onCreate(savedInstanceState: Bundle?) { attributionContext = createAttributionContext("sharePhotos") } fun getLocation() { val locationManager = attributionContext.getSystemService( LocationManager::class.java) as LocationManager // Use "locationManager" to access device location information. } } ``` -------------------------------- ### Android Permissions API Reference Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Provides a comprehensive list of all Android app permissions, their protection levels, and associated details. This is the primary reference for understanding available permissions. ```APIDOC Permissions API Reference: URL: https://developer.android.com/reference/android/Manifest.permission Description: This reference lists all available Android app permissions. Each permission entry typically includes: - Permission Name: The identifier for the permission (e.g., android.permission.CAMERA). - Protection Level: Indicates the security risk and how the permission is granted (e.g., normal, dangerous, signature, signatureOrSystem). - Description: Explains what the permission allows the app to do. - Related Permissions: Links to other relevant permissions. Usage: Developers consult this reference to identify and declare necessary permissions in their app's manifest file. ``` -------------------------------- ### Handling Permission Usage Intents Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Demonstrates how to retrieve extras from intents that trigger the data access rationale activity. These extras provide context about the permission group and the time period of access, allowing for a more detailed explanation to the user. ```java String permissionGroupName = getIntent().getStringExtra(Intent.EXTRA_PERMISSION_GROUP_NAME); if (getIntent().getAction().equals(Intent.ACTION_VIEW_PERMISSION_USAGE_FOR_PERIOD)) { long startTime = getIntent().getLongExtra(Intent.EXTRA_START_TIME, -1); long endTime = getIntent().getLongExtra(Intent.EXTRA_END_TIME, -1); String[] attributionTags = getIntent().getStringArrayExtra(Intent.EXTRA_ATTRIBUTION_TAGS); // Use these values to provide detailed rationale } ``` ```kotlin val permissionGroupName = intent.getStringExtra(Intent.EXTRA_PERMISSION_GROUP_NAME) if (intent.action == Intent.ACTION_VIEW_PERMISSION_USAGE_FOR_PERIOD) { val startTime = intent.getLongExtra(Intent.EXTRA_START_TIME, -1) val endTime = intent.getLongExtra(Intent.EXTRA_END_TIME, -1) val attributionTags = intent.getStringArrayExtra(Intent.EXTRA_ATTRIBUTION_TAGS) // Use these values to provide detailed rationale } ``` -------------------------------- ### Inspect Permission Status with ADB Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Use the `dumpsys package` command to inspect the runtime permissions granted to an application. This helps identify if permissions have been denied by the user, including permanent denials. ```shell adb shell dumpsys package PACKAGE_NAME ``` -------------------------------- ### ContentResolver Permissions Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Details the permissions required for various ContentResolver operations and the resulting SecurityException if permissions are not granted. ```APIDOC ContentResolver Operations and Permissions: Permissions are checked when a provider is first retrieved and when an app performs operations on it. If the requesting app lacks the required permission, a SecurityException is thrown. 1. **ContentResolver.query()** * **Description**: Retrieves data from a content provider. * **Required Permission**: Read permission. * **Signature Example**: `query(Uri uri, String[] projection, Bundle queryArgs, CancellationSignal cancellationSignal)` * **Error Condition**: Throws `SecurityException` if the app does not hold the read permission. 2. **ContentResolver.insert()** * **Description**: Inserts a new row into a content provider. * **Required Permission**: Write permission. * **Signature Example**: `insert(Uri uri, ContentValues values)` * **Error Condition**: Throws `SecurityException` if the app does not hold the write permission. 3. **ContentResolver.update()** * **Description**: Updates existing rows in a content provider. * **Required Permission**: Write permission. * **Signature Example**: `update(Uri uri, ContentValues values, String selection, String[] selectionArgs)` * **Error Condition**: Throws `SecurityException` if the app does not hold the write permission. 4. **ContentResolver.delete()** * **Description**: Deletes rows from a content provider. * **Required Permission**: Write permission. * **Signature Example**: `delete(Uri uri, String selection, String[] selectionArgs)` * **Error Condition**: Throws `SecurityException` if the app does not hold the write permission. **General Note**: In all cases, failing to hold the required permission (read for query, write for insert/update/delete) will result in a `SecurityException`. ``` -------------------------------- ### Java: Monitor Private Data Access with AppOpsManager Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md This Java code snippet demonstrates how to set up an AppOpsManager.OnOpNotedCallback to log private data access events. It defines callback methods to capture operation codes and stack traces, aiding in the debugging and auditing of data access within an Android application. Requires Android API level 31 or higher for full functionality. ```java @Override public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) { AppOpsManager.OnOpNotedCallback appOpsCallback = new AppOpsManager.OnOpNotedCallback() { private void logPrivateDataAccess(String opCode, String trace) { Log.i(MY_APP_TAG, "Private data accessed. " + "Operation: $opCode\nStack Trace:\n$trace"); } @Override public void onNoted(@NonNull SyncNotedAppOp syncNotedAppOp) { logPrivateDataAccess(syncNotedAppOp.getOp(), Arrays.toString(new Throwable().getStackTrace())); } @Override public void onSelfNoted(@NonNull SyncNotedAppOp syncNotedAppOp) { logPrivateDataAccess(syncNotedAppOp.getOp(), Arrays.toString(new Throwable().getStackTrace())); } @Override public void onAsyncNoted(@NonNull AsyncNotedAppOp asyncNotedAppOp) { logPrivateDataAccess(asyncNotedAppOp.getOp(), asyncNotedAppOp.getMessage()); } }; AppOpsManager appOpsManager = getSystemService(AppOpsManager.class); if (appOpsManager != null) { appOpsManager.setOnOpNotedCallback(getMainExecutor(), appOpsCallback); } } ``` -------------------------------- ### Android Photos and Videos Permissions Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Permissions for accessing and managing user photos and videos. Includes permissions for reading and writing media files, and using the system photo picker. ```APIDOC Permission: READ_EXTERNAL_STORAGE Description: Allows an application to read from external storage. Permission: READ_MEDIA_IMAGES Description: Allows an application to read images from external storage. Permission: READ_MEDIA_VIDEO Description: Allows an application to read video files from external storage. Permission: READ_MEDIA_AUDIO Description: Allows an application to read audio files from external storage. Permission: WRITE_EXTERNAL_STORAGE Description: Allows an application to write to external storage. API: System Photo Picker Description: Provides a standard UI for users to select photos and videos from their device. API: Handle Media Files Description: Workflows for handling media files, including access and management. ``` -------------------------------- ### Audit Private Data Access with AppOpsManager Callback in Kotlin Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md This snippet demonstrates how to register an `AppOpsManager.OnOpNotedCallback` within an Android Activity's `onCreate` method. The callback logs private data access operations and their associated stack traces, helping to identify which part of the app or its dependencies invoked the access. ```Kotlin override fun onCreate(savedInstanceState: Bundle?) { val appOpsCallback = object : AppOpsManager.OnOpNotedCallback() { private fun logPrivateDataAccess(opCode: String, trace: String) { Log.i(MY_APP_TAG, "Private data accessed. " + "Operation: $opCode\nStack Trace:\n$trace") } override fun onNoted(syncNotedAppOp: SyncNotedAppOp) { logPrivateDataAccess( syncNotedAppOp.op, Throwable().stackTrace.toString()) } override fun onSelfNoted(syncNotedAppOp: SyncNotedAppOp) { logPrivateDataAccess( syncNotedAppOp.op, Throwable().stackTrace.toString()) } override fun onAsyncNoted(asyncNotedAppOp: AsyncNotedAppOp) { logPrivateDataAccess(asyncNotedAppOp.op, asyncNotedAppOp.message) } } val appOpsManager = getSystemService(AppOpsManager::class.java) as AppOpsManager appOpsManager.setOnOpNotedCallback(mainExecutor, appOpsCallback) } ``` -------------------------------- ### Android Companion Device Manager Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Information on using the companion device manager for pairing with nearby Bluetooth or Wi-Fi devices without requiring location permissions. ```APIDOC https://developer.android.com/guide/topics/connectivity/companion-device-pairing Description: Use the companion device manager for Bluetooth or Wi-Fi pairing, which does not require location permissions. This is an alternative to direct location-based device discovery. Related: Bluetooth permissions, Wi-Fi permissions. ``` -------------------------------- ### Android Storage Access Framework Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Describes the Storage Access Framework (SAF) for accessing files and documents across different apps without requiring broad storage permissions. ```APIDOC Storage Access Framework (SAF): - Purpose: Enables users to select documents and files from various sources (e.g., cloud storage, local files) for your app to access. - Usage: Use SAF to open documents created by other apps or to allow users to select files for your app to manage. - Benefits: Does not require runtime storage permissions like READ_EXTERNAL_STORAGE for accessing files managed by SAF. - Related Contracts: OpenDocument, OpenMultipleDocuments, CreateDocument. ``` -------------------------------- ### Android ADB Permission Management Commands Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Provides essential ADB commands for inspecting and modifying application permissions on Android devices. These commands are crucial for testing permission-related functionality and ensuring apps behave correctly under various permission states. ```APIDOC ADB Permission Management: List Permissions: adb shell pm list permissions [-d] [-g] - Lists installed permissions. - Options: -d: Show disabled permissions. -g: Group permissions by permission controller. - Example: $ adb shell pm list permissions -d -g Grant/Revoke Permissions: adb shell pm [grant|revoke] ... - Grants or revokes one or more permissions for an application. - Arguments: grant|revoke: The action to perform. : The name of the permission to modify (e.g., android.permission.CAMERA). - Example (Grant CAMERA permission): $ adb shell pm grant com.example.app android.permission.CAMERA - Example (Revoke LOCATION permission): $ adb shell pm revoke com.example.app android.permission.ACCESS_FINE_LOCATION Note: Replace 'com.example.app' with the actual package name of the application. ``` -------------------------------- ### Android Scoped Storage Migration Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Information on migrating to scoped storage for apps targeting Android 10 (API level 29) and higher, providing users more control and limiting file clutter. ```APIDOC https://developer.android.com/training/data-storage/use-cases Description: Apps targeting Android 10 (API level 29) or higher automatically have scoped access to external storage. This limits apps to their own directories and media they've created. Learn how to migrate to this model. Related: Data Access Auditing, Package Visibility. ``` -------------------------------- ### Android APIs for Permission-less Features Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md This section details various Android APIs and system intents that enable common functionalities without requiring sensitive permissions like CAMERA, READ_SMS, READ_PHONE_STATE, or BLUETOOTH_ADMIN. It covers device identification, Bluetooth pairing, payment card entry, and call management. ```APIDOC Feature: Taking Photos Description: Allows users to capture images using the device's camera. Permission Required: None (uses system intent). API/Intent: MediaStore.ACTION_IMAGE_CAPTURE Example: Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivity(takePictureIntent); Feature: Recording Videos Description: Allows users to record video clips using the device's camera. Permission Required: None (uses system intent). API/Intent: MediaStore.ACTION_VIDEO_CAPTURE Example: Intent recordVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); startActivity(recordVideoIntent); Feature: Device Identification Description: Obtain a unique identifier for the app's instance on a device. Permission Required: None. Methods: - Instance ID library: https://developers.google.com/instance-id/guides/android-implementation - Custom identifier: Use java.util.UUID.randomUUID() Feature: Bluetooth Pairing Description: Facilitates data transfer with other devices over Bluetooth. Permission Required: None (uses companion device pairing). API: Companion device pairing Link: https://developer.android.com/guide/topics/connectivity/companion-device-pairing Feature: Payment Card Entry Description: Automatically enter payment card numbers using Google Play services. Permission Required: None (uses Google Pay library). API: Debit and credit card recognition library Link: https://developers.google.com/pay/payment-card-recognition/debit-credit-card-recognition Feature: Automatic One-Time Passcode Entry Description: Streamlines two-factor authentication by automatically entering OTPs. Permission Required: None (uses SMS Retriever API or app-specific token). APIs: - SMS Retriever API (Google Play services): https://developers.google.com/identity/sms-retriever/overview - createAppSpecificSmsToken(PendingIntent): android.telephony.SmsManager Feature: Automatic Phone Number Entry Description: Allows users to enter their device's phone number automatically. Permission Required: None (uses Phone Number Hint library). API: Phone Number Hint library Link: https://developers.google.com/identity/phone-number-hint/android Feature: Call Filtering Description: Filters incoming phone calls, e.g., for spam. Permission Required: None (uses CallScreeningService). API: android.telecom.CallScreeningService Link: https://developer.android.com/reference/android/telecom/CallScreeningService Feature: Placing Phone Calls Description: Initiates a phone call by opening the dialer. Permission Required: None (uses ACTION_DIAL intent). API/Intent: Intent.ACTION_DIAL Example: Uri phoneNumber = Uri.fromParts("tel", "1234567890", null); Intent dialIntent = new Intent(Intent.ACTION_DIAL, phoneNumber); startActivity(dialIntent); Feature: Audio Focus Management Description: Manages audio playback focus changes, e.g., during calls or alarms. Permission Required: None (implements audio focus listener). API: AudioManager.OnAudioFocusChangeListener Method: onAudioFocusChange(int focusChange) Link: https://developer.android.com/guide/topics/media-apps/audio-focus Example: AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); AudioManager.OnAudioFocusChangeListener afChangeListener = focusChange -> { /* handle focus changes */ }; audioManager.requestAudioFocus(afChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK); ``` -------------------------------- ### Android Photo Picker Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Explains the Photo Picker, a system UI for selecting media files without requiring runtime permissions, granting temporary read access to selected URIs. ```APIDOC Photo Picker: - Functionality: Allows users to select photos and videos from their device's media library. - Permissions: Does not require any runtime permissions to use. - Access: Grants temporary read access to the URI of the selected media files. - Related Contracts: PickVisualMedia, PickMultipleVisualMedia. ``` -------------------------------- ### Place Phone Call Intent Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md To allow users to initiate a phone call, use the ACTION_DIAL intent action. This intent opens the dialer app with the number pre-filled, avoiding the CALL_PHONE permission. ```Java Uri phoneNumber = Uri.fromParts("tel", "1234567890", null); Intent dialIntent = new Intent(Intent.ACTION_DIAL, phoneNumber); startActivity(dialIntent); ``` ```Kotlin val phoneNumber = Uri.fromParts("tel", "1234567890", null) val dialIntent = Intent(Intent.ACTION_DIAL, phoneNumber) startActivity(dialIntent) ``` -------------------------------- ### Request SCHEDULE_EXACT_ALARMS Permission Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Demonstrates how to check if the SCHEDULE_EXACT_ALARMS permission is granted and request it from the user if not. This involves checking the AlarmManager's capability and launching an intent to system settings if the permission is denied. ```kotlin val alarmManager = getSystemService()!! when { // if permission is granted, proceed with scheduling exact alarms… alarmManager.canScheduleExactAlarms() -> { alarmManager.setExact(...) } else -> { // ask users to grant the permission in the corresponding settings page startActivity(Intent(ACTION_REQUEST_SCHEDULE_EXACT_ALARM)) } } ``` -------------------------------- ### Android Audio Files Permissions Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Permissions for accessing and managing audio files, including recording audio and reading/writing audio files from external storage. ```APIDOC Permission: CAPTURE_AUDIO_OUTPUT Description: Allows an application to capture audio output from the device. Permission: RECORD_AUDIO Description: Allows an application to record audio. Permission: READ_EXTERNAL_STORAGE Description: Allows an application to read from external storage. Permission: WRITE_EXTERNAL_STORAGE Description: Allows an application to write to external storage. API: Handle Media Files Description: Workflows for handling media files, including access and management. ``` -------------------------------- ### Check Device Support for Microphone and Camera Toggles Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Determines if the current device supports hardware toggles for microphone and camera access. This is achieved by querying the SensorPrivacyManager for specific sensor types like MICROPHONE and CAMERA. ```Kotlin val sensorPrivacyManager = applicationContext .getSystemService(SensorPrivacyManager::class.java) as SensorPrivacyManager val supportsMicrophoneToggle = sensorPrivacyManager .supportsSensorToggle(Sensors.MICROPHONE) val supportsCameraToggle = sensorPrivacyManager .supportsSensorToggle(Sensors.CAMERA) ``` ```Java SensorPrivacyManager sensorPrivacyManager = getApplicationContext() .getSystemService(SensorPrivacyManager.class); boolean supportsMicrophoneToggle = sensorPrivacyManager .supportsSensorToggle(Sensors.MICROPHONE); boolean supportsCameraToggle = sensorPrivacyManager .supportsSensorToggle(Sensors.CAMERA); ``` -------------------------------- ### Activity for Data Access Rationale Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Defines an Android activity to display rationale for data access. It includes specific permissions and intent filters to be invoked by the system when users inquire about data usage. The `android:exported` attribute is crucial for Android 12+. ```xml ``` -------------------------------- ### Android Permissions API Reference Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md References to Android system permissions and related API methods for checking access. These are key components for managing app access to sensitive data and device features. ```APIDOC Permissions: - SCHEDULE_EXACT_ALARMS - MANAGE_EXTERNAL_STORAGE - CAMERA - RECORD_AUDIO - ACCESS_COARSE_LOCATION - ACCESS_FINE_LOCATION - ACCESS_BACKGROUND_LOCATION Related Methods: - android.app.AlarmManager#canScheduleExactAlarms() - Description: Checks if the calling app has been granted the SCHEDULE_EXACT_ALARMS permission. - Returns: boolean - true if the app can schedule exact alarms, false otherwise. - android.os.Environment#isExternalStorageManager() - Description: Checks if the calling app has been granted the MANAGE_EXTERNAL_STORAGE permission. - Returns: boolean - true if the app has the permission, false otherwise. - Related to Camera Access: - Permission: CAMERA - Best Practice: Wait to access the device's camera until the user has granted the CAMERA permission. - Related to Microphone Access: - Permission: RECORD_AUDIO - Best Practice: Wait to access the device's microphone until the user has granted the RECORD_AUDIO permission. - Related to Location Access: - Permissions: ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION, ACCESS_BACKGROUND_LOCATION - Best Practice: Request location permissions contextually when the user interacts with a location-requiring feature. Request ACCESS_BACKGROUND_LOCATION only after coarse or fine location permissions are granted. ``` -------------------------------- ### Declare Custom Permissions in AndroidManifest.xml Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Defines custom permissions for Android applications within the `AndroidManifest.xml` file. This allows apps to expose functionality and control access to resources. It requires proper naming conventions and declaration using the `` tag, specifying attributes like `name`, `protectionLevel`, `label`, and `description`. ```APIDOC ... ``` -------------------------------- ### Apply WindowInsets Listener for Privacy Indicators Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Listens for window inset changes to adjust UI elements, ensuring they avoid overlapping with privacy indicators like the camera or microphone access dot. This is crucial for maintaining a good user experience on newer Android versions. ```Kotlin view.setOnApplyWindowInsetsListener { view, windowInsets -> val indicatorBounds = windowInsets.getPrivacyIndicatorBounds() // change your UI to avoid overlapping windowInsets } ``` -------------------------------- ### Handle Special Permission Grant in onResume() Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Provides sample code for handling the user's response to a special permission request. It checks the permission status in the onResume() method after the user returns from system settings and proceeds with the action or gracefully degrades the app experience. ```kotlin override fun onResume() { // ...    if (alarmManager.canScheduleExactAlarms()) {        // proceed with the action (setting exact alarms)        alarmManager.setExact(...)    }    else {        // permission not yet approved. Display user notice and gracefully degrade        // your app experience.        alarmManager.setWindow(...)    } } ``` -------------------------------- ### Manage Permission Requests with Request Codes (Kotlin) Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Shows how to manually request permissions using a request code and `requestPermissions()` in Kotlin. This method requires manual handling of the result via `onRequestPermissionsResult`. ```Kotlin when { ContextCompat.checkSelfPermission( CONTEXT, Manifest.permission.REQUESTED_PERMISSION ) == PackageManager.PERMISSION_GRANTED -> { // You can use the API that requires the permission. performAction(...) } ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.REQUESTED_PERMISSION) -> { // In an educational UI, explain to the user why your app requires this // permission for a specific feature to behave as expected, and what // features are disabled if it's declined. In this UI, include a // "cancel" or "no thanks" button that lets the user continue // using your app without granting the permission. showInContextUI(...) } else -> { // You can directly ask for the permission. requestPermissions(CONTEXT, arrayOf(Manifest.permission.REQUESTED_PERMISSION), REQUEST_CODE) } } ``` -------------------------------- ### Android Manifest Element Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Declares a required system permission for your application. This element specifies permissions that your app needs to access protected features or data. It is a fundamental part of the Android manifest file. ```APIDOC AndroidManifest.xml: Description: Declares a permission that the application must be granted in order to use features that require that permission. Attributes: android:name: The name of the permission to request. This can be a system-defined permission (e.g., android.permission.CAMERA) or a custom permission defined by your app or another app. Example: Related Concepts: - Custom Permissions: Defining your own permissions for inter-app communication. - Signature Permissions: Permissions granted only to apps signed with the same certificate, useful for secure inter-app communication without user prompts. ``` -------------------------------- ### Android Files and Docs Permissions Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Permissions for accessing and managing files and documents on the device, including broad access to external storage. ```APIDOC Permission: READ_EXTERNAL_STORAGE Description: Allows an application to read from external storage. Permission: WRITE_EXTERNAL_STORAGE Description: Allows an application to write to external storage. Permission: MANAGE_EXTERNAL_STORAGE Description: Allows an application to manage all files on the device, including those outside the app's specific directory. API: Data and File Storage Description: Guides and best practices for storing and accessing data and files on Android. API: Data Backup Description: Information on how to implement data backup for applications. ``` -------------------------------- ### Declare Optional Camera Hardware in AndroidManifest Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Declares the camera hardware as optional in the manifest. This allows the app to run on devices without a camera, improving compatibility. ```xml ... ``` -------------------------------- ### WindowInsets getPrivacyIndicatorBounds() Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Provides the API reference for `getPrivacyIndicatorBounds()`, a method used to determine the screen location of privacy indicators (microphone/camera access icons). This helps developers adapt their UI to avoid overlapping with these indicators, especially in immersive or full-screen modes. ```APIDOC WindowInsets.Builder.setPrivacyIndicatorBounds(Rect bounds) // Method to get the bounds of privacy indicators. // This method is part of the WindowInsets API and is used to // understand where system-level privacy indicators (like microphone or camera usage icons) // might appear on the screen. // // Parameters: // bounds: A Rect object representing the area where indicators may be displayed. // // Usage: // Developers can use this information to adjust their UI layout, ensuring that // important elements are not obscured by these indicators, particularly in full-screen // or immersive experiences. // // Related Methods: // - WindowInsets.getPrivacyIndicatorBounds(): Retrieves the current bounds of privacy indicators. ``` -------------------------------- ### Android Package Visibility Declaration Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Guidance on declaring package visibility needs for apps targeting Android 11 or higher, allowing your app to see other apps that are hidden by default. ```APIDOC https://developer.android.com/training/package-visibility/declaring Description: If your app targets Android 11 or higher, the system makes certain apps invisible by default. Learn how to declare your app's needs to make those other apps visible. Related: Data Access Auditing, Scoped Storage. ``` -------------------------------- ### Android Context URI Permission Management Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Manages URI permissions for content providers, allowing fine-grained access control. Includes methods for granting, revoking, and checking permissions on specific URIs, independent of general provider access. ```APIDOC Android Context URI Permission Management: grantUriPermission(String toPackage, Uri uri, int modeFlags) - Grants URI access permission to a specific package. - Parameters: - toPackage: The package to grant permission to. - uri: The URI to grant permission for. - modeFlags: Flags indicating read (Intent.FLAG_GRANT_READ_URI_PERMISSION) or write (Intent.FLAG_GRANT_WRITE_URI_PERMISSION) access. revokeUriPermission(Uri uri, int modeFlags) - Revokes previously granted URI access permission. - Parameters: - uri: The URI for which to revoke permission. - modeFlags: Flags indicating the type of permission to revoke (read/write). checkUriPermission(Uri uri, int uid, int modeFlags) - Checks if a specific UID has been granted permission for a given URI. - Parameters: - uri: The URI to check. - uid: The user ID to check permission for. - modeFlags: Flags indicating the type of permission to check (read/write). - Returns: The mode flags granted, or -1 if no permission is granted. ``` -------------------------------- ### Android Permissions for Location Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Details the Android permissions related to location access, differentiating between coarse and fine location and their use cases. ```APIDOC Manifest.permission: - ACCESS_COARSE_LOCATION description: Allows an app to access approximate location information derived from location services such as cell tower and Wi-Fi. Suitable for use cases needing rough location estimates. protectionLevel: normal - ACCESS_FINE_LOCATION description: Allows an app to access precise location information derived from the device's GPS. Use only when precise location is essential for app functionality. protectionLevel: normal ``` -------------------------------- ### Restrict App Component Interactions via Manifest Permissions Source: https://github.com/gerrithoskins/android-permissions/blob/main/README.md Demonstrates how to use the `android:permission` attribute in the AndroidManifest.xml to protect app components like activities, services, and content providers from unauthorized access by other applications. ```XML ```