Android Q extends the transparency and control that users have over data and app capabilities. For developers, these features can affect specific behaviors or data that your app may be depending on. All developers should review the privacy features and test their apps. Impacts can vary based on each app’s core functionality, targeting, and other factors.
Android Q gives users more control over when apps can get access to devise locations. When an app running on Android Q requests location access, users see the dialog shown in Figure 1. This dialog allows users to grant location access to two different extents: while using the app (foreground only) or all the time (foreground and background). To support the additional control that users have over an app’s access to location information, Android Q introduces new location permission, ACCESS_BACKGROUND_LOCATION. Unlike the existing ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION permissions, the new permission only affects an app’s access to location when it’s running in the background. An app is considered to be in the background unless one of its activities is visible or the app is running a foreground service.
If your app targets Android Q and needs to access the device location when running in the background, you must declare the new permission in your app’s manifest file:
If your app runs on Android Q but targets Android 9 (API level 28) or lower, the following behavior applies:
...
Before starting the foreground service, make sure that your app still has access to the device’s location:
boolean permissionAccessCoarseLocationApproved = ActivityCompat.checkSelfPermission(this, permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED; if (permissionAccessCoarseLocationApproved) { // App has permission to access location in the foreground. Start your // foreground service that has a foreground service type of "location". } else { // Make a request for foreground-only location access. ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.ACCESS_COARSE_LOCATION}, your-permission-request-code); }
To give users more control over their files and to limit file clutter, Android Q changes how apps can access files on the device’s external storage, such as the files stored at the path /sdcard. Android Q continues to use the READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions, which correspond to the Storage user-facing runtime permission.
However, apps targeting Android Q by default (as well as apps that opt into the change) are given a filtered view into external storage. Such apps can see only their app-specific directory and specific types of media, so the apps don’t need to request any additional user permissions.
For apps that handle files that users expect to be sharable with other apps (such as photos) and be retained after the app has been uninstalled, use the MediaStore API. There are specific collections for common media files: Audio, Video, and Images. For other file types, you can store them in the new Downloads collection. To access files from the Downloads collection, apps must use the system picker.
If your app is designed to handle files not meant to be shared with other apps, store them in your package-specific directories. This helps keep files organized and limit file clutter as the OS will manage cleanup when the app is uninstalled. Calls to Context.getExternalFilesDir() will continue to work.
Android Q places restrictions on when apps can start activities. This behavior change helps minimize interruptions for the user and keeps the user more in control of what’s shown on their screen.
For creating time-sensitive notifications, make sure that you include a descriptive title and message by setting the notification flag with HIGH_PRIORITY. Optionally, you can also provide a full-screen intent.
val fullScreenIntent = Intent(this, CallActivity::class.java) val fullScreenPendingIntent = PendingIntent.getActivity(this, 0, fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT) val notificationBuilder = NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.notification_icon) .setContentTitle("Incoming call") .setContentText("(919) 555-1234") .setPriority(NotificationCompat.PRIORITY_HIGH) .setCategory(NotificationCompat.CATEGORY_CALL) .setFullScreenIntent(fullScreenPendingIntent, true) val incomingCallNotification = notificationBuilder.build()
Use a full-screen intent only for the highest-priority alerts where you have an associated activity that you would like to launch after the user interacts with the notification. Also, if your app targets Android Q, you need to request the USE_FULL_SCREEN_INTENT permission for the platform to invoke this notification.
Android Q makes several restrictions placed on accessing data and system identifiers. These changes help protect users’ privacy.
Starting in Android Q, apps must have the READ_PRIVILEGED_PHONE_STATE privileged permission to access the device’s non-resettable identifiers, which include both IMEI and serial number. If your app doesn’t have the permission and you try asking for information about the identifiers anyway, the platform’s response varies based on the target SDK version: