Evaluate whether your app needs to declare permissions

Before you declare permissions in your app, consider whether you need to do so. Every time the user tries an app feature that requires a runtime permission, your app has to interrupt the user's work with a permission request. The user then must make a decision. If the user doesn't understand why your app requests a particular permission, they could deny the permission or even uninstall your app.

Consider whether another installed app might be able to perform the functionality on your app's behalf. In these cases, you should delegate the task to another app using an intent. In doing so, you don't need to declare the necessary permissions because the other app declares the permission instead.

Alternatives to declaring permissions

This section describes several use cases that your app can fulfill without declaring the need for any permissions.

Show nearby places

Your app might need to know the user's approximate location. This is useful for showing location-aware information, such as nearby restaurants.

Some use cases require a rough estimate of a device's location, to within about 1.25 miles (2 km). In these situations, you can declare the ACCESS_COARSE_LOCATION permission. It's better to not declare the permission, and instead ask the user to enter an address or a postal code.

Other use cases require a more precise estimate of a device's location. Only in those situations, it's OK to declare the ACCESS_FINE_LOCATION permission.

Take a photo

Users might take pictures in your app, using the pre-installed system camera app.

In this situation, don't declare the CAMERA permission. Instead, invoke the ACTION_IMAGE_CAPTURE intent action.

Record a video

Users might record videos in your app, using the pre-installed system camera app.

In this situation, don't declare the CAMERA permission. Instead, invoke the ACTION_VIDEO_CAPTURE intent action.

Open another app's media or documents

Your app might show content that another app created, such as photos, videos, or text files.

In this situation, don't declare the READ_EXTERNAL_STORAGE permission. Also, don't directly access shared or external storage devices using methods like getExternalStorageDirectory(), which are deprecated as of Android 10 (API level 29). Instead, use the device's media store to open media files, and the Storage Access Framework to open documents and other files.

Identify the device that is running an instance of your app

A particular instance of your app might need to know which device it's running on. This is useful for apps that have device-specific preferences or messaging, such as different playlists for TV devices and wearable devices.

In this situation, don't access the device's IMEI directly. In fact, as of Android 10 (API level 29), you cannot do so. Instead, do one of the following:

  • Get a unique device identifier for your app's instance using the Instance ID library.
  • Create your own identifier that's scoped to your app's storage. Use basic system functions, such as randomUUID().

Pair with a device over Bluetooth

Your app might offer an enhanced experience by transferring data to another device over Bluetooth.

To support this functionality, don't declare the ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATIION, or BLUETOOTH_ADMIN permissions. Instead, use companion device pairing.

Pause media when your app is interrupted

If the user receives a phone call, or if a user-configured alarm occurs, your app should pause any media playback until your app regains audio focus.

To support this functionality, don't declare the READ_PHONE_STATE permission. Instead, implement the onAudioFocusChange() event handler, which runs automatically when the system shifts its audio focus. Learn more about how to implement audio focus.

Filter phone calls

To minimize unnecessary interruptions for the user, your app might filter phone calls for spam.

To support this functionality, don't declare the READ_PHONE_STATE permission. Instead, use the CallScreeningService API.