Android Q 测试版

Privacy in Android Q

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.

CHECK YOUR APP

Top privacy changes

SCOPED STORAGE

New limits on access to files in shared external storage. Complete most work with files in app-specific directories or strongly-typed media collections.

LEARN MORE

DEVICE LOCATION

New user option to allow access to device location only while your app is in the foreground.

LEARN MORE

BACKGROUND APP STARTS

New restrictions on launching activities from the background without user interaction.

LEARN MORE

HARDWARE IDENTIFIERS

New restrictions on access to device hardware identifiers such as IMEI, serial number, MAC, and similar data.

LEARN MORE

CAMERA AND CONNECTIVITY

New restrictions on access to full camera metadata, and FINE location permission now required for many connectivity workflows.

LEARN MORE

Get started with privacy updates 

  1. Review the privacy features — Learn about what's changing and assess your app.
  2. Test your app on Android Q — Get the Beta as soon as possible, test, migrate as needed.
  3. Update your app — Targeting Q if possible, test with users via beta channels or other groups.

Android Q privacy checklist

Android Q privacy features extend the transparency and control that users have over their data and the capabilities they give to apps. These features might mean that specific behaviors or data that your app is depending on may no longer be available. This checklist gives you an overview of the key features to test for, as well as other privacy changes to keep in mind.

The impacts on your app can be minimized if your app is following current best practices for handling user data. We recommend getting started as soon as possible with testing and updating your apps.

For complete details, see the documentation for each feature. Also see the release notes for changes at each beta build.

Key behavior changeApps affectedMitigation strategyHow to enable
 Scoped storage
New sandbox view into external storage, giving access to app-specific files and media collections
Apps that access and share files in external storageWork in app-specific directory and media collection directories 
Learn more
Target Android Q
 More user control over location permissions
New foreground-only permission that gives users more control over app access to device location
Apps that request the user's location while in the backgroundEnsure graceful degradation in the absence of background location updates
Use new permission to access location in the background 
Learn more
Install app on device running Android Q
 Background activity starts
New restrictions on launching activities from the background
Apps that launch activities without user interactionUse notification-triggered activities 
Learn more
Enabled by default; turn on Allow background activity starts developer option to disable restrictions
 Non-resettable hardware identifiers
New restrictions on accessing device serial and IMEI
Apps that access device serial or IMEIUse an identifier that the user can reset 
Learn more
Install app on device running Android Q
 Permission for wireless scanning
Access to some Wi-Fi, Wi-Fi Aware, and Bluetooth scanning methods requires fine location permission
Apps using Wi-Fi and Bluetooth APIsRequest ACCESS_FINE_LOCATIONpermission for related use cases 
Learn more
Target Android Q

Other privacy changes 

Android Q introduces many other privacy changes that you should keep in mind when testing and updating your app:

Data & identifiersCamera & connectivityPermissions

Android Q places the following
restrictions on accessing data
and system identifiers.

Contacts affinity

MAC addresses

/proc/net file system

Non-resettable device identifiers

Clipboard data

USB serial

 

Android Q privacy change: Scoped storage

As of Android Q Beta 3, apps that target Android 9 (API level 28) or lower see no change, by default, to how storage works from previous Android versions. As you update your existing app to work with scoped storage, you can use a new manifest attribute to enable the new behavior for your app on Android Q devices, even if your app is targeting Android 9 or lower.

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 theREAD_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 sandboxed view into external storage.

Note: The permissions specific to media collections that were introduced in earlier beta releases—READ_MEDIA_IMAGESREAD_MEDIA_AUDIO, and READ_MEDIA_VIDEO—are now obsolete.

This guide describes the files included in the sandboxed view, as well as how to update your app so that it can continue to share, access, and modify files that are saved on an external storage device. This guide also explains several considerations related to location information in photographs, media access from native code, and use of column names in content queries.

To learn more about changes to external storage in Android Q, see the section that discusses Improvements in creating files on external storage.

Note: If you encounter issues with using this feature, send us a bug report using this hotlist.

Sandboxed view of files in external storage

By default, if your app targets Android Q, it has a sandboxed view of the files that are on an external storage device. The app can store files intended for itself under an app-specific directory in the sandbox usingContext.getExternalFilesDir().

An app that has a sandboxed view always has access to the files that it creates, both inside and outside its app-specific directory. However, your app can access files that other apps have created only if these files reside in one of the following well-defined media collections:

In order to access any other file that another app has created, including files in a "downloads" directory, your app must use the Storage Access Framework, which allows the user to select a specific file.

The sandboxed view also imposes the following media data restrictions:

To access media files in native code, retrieve the file using MediaStore in your Java-based or Kotlin-based code, then pass the corresponding file descriptor into your native code. For more information, see the section on how to access media files from native code.

Preserve your app's files after uninstall

If an app has a sandboxed view into external storage and the app is then uninstalled, all files within the app-specific directory are cleaned up. To preserve these files after an uninstall, save them to a directory within the MediaStore.

Opt out of sandboxed view

Warning: Scoped storage will be required in next year's major platform release for all apps, independent of target SDK level. Therefore, you should ensure that your app works with scoped storage well in advance. To do so, make sure that the behavior is enabled on Android Q devices running your app.

Most apps that already follow storage best practices should work with scoped storage after making minimal changes. Before your app is fully compatible or tested, you can temporarily opt out of the scoped storage behavior based on your app's target SDK level or a new manifest attribute called "allowExternalStorageSandbox":

  • Target Android 9 (API level 28) or lower.

  • If you target Android Q, the value of "allowExternalStorageSandbox" is true by default.

    Note: A future beta release of Android Q uses a different name for this attribute.

    You can opt out by changing this value to false in your app's manifest file:

    <manifest ... >
      <!-- This attribute is "true" by default on apps targeting Android Q. -->
      <application android:allowExternalStorageSandbox="false" ... >
        ...
      </application>
    </manifest>
    

     

Note: To test how an app targeting Android 9 or lower works with scoped storage, you can opt in to the behavior by setting the value of "allowExternalStorageSandbox" to true.

Set up a virtual external storage device

On devices without removable external storage, use the following command to enable a virtual disk for testing purposes:

adb shell sm set-virtual-disk true

 

Summary of sandboxed view file access

The following table summarizes how an app that has a sandboxed view can access files in external storage:

File locationPermissions neededMethod of accessing (*)Files removed when app uninstalled?
App-specific directoryNonegetExternalFilesDir()Yes
Media collections
(photos, videos, audio)
READ_EXTERNAL_STORAGE
only when
accessing other apps' files
MediaStoreNo
Downloads
(documents and
e-books)
NoneStorage Access Framework
(loads system's file picker)
No

*You can use the Storage Access Framework to access each of the locations shown in the preceding table without requesting any permissions.

Adapt specific types of usage patterns to the change

This section provides advice for several specific types of media-based apps to adapt to the storage behavior change taking place in apps that target Android Q.

It's a best practice to use the sandboxed view unless your app needs access to a file that doesn't reside in either the app-specific directory or the MediaStore.

Share media files

Some apps allow users to share media files with each other. For example, social media apps give users the ability to share photos and videos with friends.

To access the media files that users want to share, use the MediaStore API. You can use this same API to store any files that the user receives through the app, taking advantage of the improvements introduced in Android Q.

In cases where you provide a suite of companion apps—such as a messaging app and a profile app—set up file sharingusing content:// URIs. We already recommend this workflow as a security best practice.

Work in documents

Some apps use documents as the unit of storage in which users enter data that they might want to share with peers or import into other documents. Several examples include a user opening a business productivity document or opening a book that's saved as an *.epub file.

In these cases, allow the user to choose the file to open by invoking the ACTION_OPEN_DOCUMENT intent, which opens the system's file picker app. To show only the types of files that your app supports, include the Intent.EXTRA_MIME_TYPESextra in your intent.

The ActionOpenDocument sample on GitHub shows how to use ACTION_OPEN_DOCUMENT to open a file after getting the user's consent.

Manage groups of files

File management and media creation apps typically manage groups of files in a directory hierarchy. These apps can invoke the ACTION_OPEN_DOCUMENT_TREE intent to allow the user to grant access to an entire directory tree. Such an app would be able to edit any file in the selected directory, as well as any of its sub-directories.

Using this interface, users can access files from any installed instance of DocumentsProvider, which any locally-backed or cloud-based solution can support.

The ActionOpenDocumentTree sample on GitHub shows how to use ACTION_OPEN_DOCUMENT_TREE to open a directory tree after getting the user's consent.

Note: When using ACTION_OPEN_DOCUMENT_TREE, your app only gains access to the files in the directory that the user selects. You don't have access to other apps' files that reside outside this user-selected directory. This user-controlled access allows users to choose exactly what content they're comfortable sharing with your app.

Access and edit media content

This section provides best practices for loading and storing media files in external storage so that your app continues to provide a good user experience in Android Q.

Note: In a future release, when apps that have a sandboxed view of external storage request the Storage runtime permission, they can view a file only if the file resides in the app-specific directory or one of the media collections: MediaStore.Audio,MediaStore.Images, or MediaStore.Video. Even with the Storage permission, such an app that accesses the raw file-system view of an external storage device has access only to the app's raw, package-specific path.

If an app attempts to open files outside of its package-specific path using a raw file-system view, an error occurs: either aFileNotFoundException (in managed code) or an EPERM error (in native code).

Access files

Don't load media files using the deprecated DATA columns. Instead, call one of the following methods from ContentResolver:

  • For the thumbnail of a single media file, use loadThumbnail(), passing in the size of the thumbnail that you want to load.
  • For a single media file, use openFileDescriptor().
  • For a collection of media files, use query().

Note: You can view the set of pending media files by calling MediaStore.setIncludePending().

The following code snippet shows how to access media files:

// Load thumbnail of a specific media item.
val mediaThumbnail = resolver.loadThumbnail(item, Size(640, 480), null)

// Open a specific media item.
resolver.openFileDescriptor(item, mode).use { pfd ->
    // ...
}

// Find all videos on a given storage device, including pending files.
val collection = MediaStore.Video.Media.getContentUri(volumeName)
val collectionWithPending = MediaStore.setIncludePending(collection)
resolver.query(collectionWithPending, null, null, null).use { c ->
    // ...
}

 

Access from native code

You might encounter situations where your app needs to work with a particular media file in native code, such as a file that another app has shared with your app or a media file from the user's media collection. In these cases, begin your media file discovery in your Java-based or Koltin-based code, then pass the file's associated file descriptor into your native code.

The following code snippet shows how to pass a media object's file descriptor into your app's native code:

KOTLINJAVA

Uri contentUri = ContentUris.withAppendedId(
        android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
        cursor.getLong(Integer.parseInt(BaseColumns._ID)));
String fileOpenMode = "r";
ParcelFileDescriptor parcelFd = resolver.openFileDescriptor(uri, fileOpenMode);
if (parcelFd != null) {
    int fd = parcelFd.detachFd();
    // Pass the integer value "fd" into your native code. Remember to call
    // close(2) on the file descriptor when you're done using it.
}

 

To learn more about accessing files in native code, see the Files for Miles talk from Android Dev Summit '18, starting at 15:20.

Update other apps' media files

Note: Expect the following behavior to take effect in a future beta release of Android Q.

To modify a given media file that another app originally saved to an external storage device, catch theRecoverableSecurityException that the platform throws. You can then request that the user grant your app write access to that specific item.

Location information in pictures

Some photographs contain location information in their Exif metadata, which allows users to view the place where a photograph was taken. Because this location information is sensitive, Android Q by default hides this information from your app if it has a sandboxed view into external storage. This restriction to location information is different from the one that applies to camera characteristics.

If your app needs access to a photograph's location information, complete the following steps:

  1. Add the new ACCESS_MEDIA_LOCATION permission to your app's manifest.
  2. From your MediaStore object, call setRequireOriginal(), passing in the URI of the photograph.

An example of this process appears in the following code snippet:

KOTLINJAVA

Uri photoUri = Uri.withAppendedPath(
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
        cursor.getString(idColumnIndex));

final double[] latLong;

// Get location data from the ExifInterface class.
photoUri = MediaStore.setRequireOriginal(photoUri);
InputStream stream = getContentResolver().openInputStream(photoUri);
if (stream != null) {
    ExifInterface exifInterface = new ExifInterface(stream);
    double[] returnedLatLong = exifInterface.getLatLong();

    // If lat/long is null, fall back to the coordinates (0, 0).
    latLong = returnedLatLong != null ? returnedLatLong : new double[2];

    // Don't reuse the stream associated with the instance of "ExifInterface".
    stream.close();
} else {
    // Failed to load the stream, so return the coordinates (0, 0).
    latLong = new double[2];
}

 

Column names in content queries

If your app's code uses a column name projection, such as "mime_type AS MimeType", keep in mind that Android Q requires column names that are defined the MediaStore API.

If your code depends on a library that expects a column name that's undefined in the Android API, such as "MimeType", use CursorWrapper to dynamically translate the column name in your app's process.

Android Q privacy change: Restrictions to background activity starts

As of Android Q Beta 3, this change has the following properties:

  • Affects your app if you launch activities without user interaction
  • Mitigate by using notification-triggered activities
  • Disable restrictions by turning on the Allow background activity starts developer option

We're interested in hearing your feedback! Report issues you find when using this feature during the Android Q beta program.

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.

This behavior change applies to all apps running on Android Q, even those that target Android 9 (API level 28) or lower. In addition, even if your app targets Android 9 or lower and is originally installed on a device running Android 9 or lower, the behavior change still takes effect after the device is upgraded to Android Q.

As long as your app starts activities as a direct result of user interaction, however, your app most likely isn't affected by this change. In fact, the majority of apps are unaffected by this change.

Note: If you find that your app is affected, send us feedback.

Conditions that allow for activity starts

Apps running on Android Q can start activities only when one or more of the following conditions are met:

  • The app has a visible window, such as an activity in the foreground.

    Note: For the purposes of activity starts, foreground services don't qualify an app as being in the foreground.

  • The app has an activity in the back stack of the foreground task.

  • The app has a service that is bound by the system. This condition applies only for the following services, which might need to launch a UI: AccessibilityServiceAutofillServiceCallRedirectionService,HostApduServiceInCallServiceTileServiceVoiceInteractionService, and VrListenerService.

  • The app has a service that is bound by a different, visible app. Note that the app that is bound to the service must remain visible for the app in the background to start activities successfully.

  • The app receives a notification PendingIntent from the system. In the case of pending intents for services and broadcast receivers, the app can start activities for a few seconds after the pending intent is sent.

  • The app receives a PendingIntent that is sent from a different, visible app.

  • The app receives a system broadcast where the app is expected to launch a UI. Examples includeACTION_NEW_OUTGOING_CALL and SECRET_CODE_ACTION. The app can start activities for a few seconds after the broadcast is sent.

  • The app is associated with a companion hardware device through the CompanionDeviceManager API. This API allows the app to start activities in response to actions that the user performs on a paired device.

  • The app is a device policy controller running in device owner mode. Example use cases include fully managed enterprise devices, as well as dedicated devices like digital signage and kiosks.

Note: In a future beta release of Android Q, apps that have been granted the SYSTEM_ALERT_WINDOW permission by the user can start activities in the background. Keep in mind, though, that apps running on Android Q (Go edition) cannot receive this permission.

Warning messages

If your app is running the latest beta version of Android Q and tries to launch an activity from the background, the platform sends a warning message to logcat and displays the following warning toast message:

Background activity start from package-name blocked.

 

The restrictions associated with starting activities in the background in Android Q are similar to how the system blocks activity launches after the device has entered a screen pinning state.

Note: The warning toast will not appear in the public release of Android Q.

Create notifications for time-sensitive events

In nearly all cases, apps that are in the background should create notifications to provide information to the user instead of directly starting an activity.

In specific cases, your app might need to get the user's attention urgently, such as an ongoing alarm or incoming call. You might have previously configured your app to launch a background activity for this purpose. To provide the same behavior on a device running Android Q, complete the steps shown in the following sections.

Create a high-priority notification

When creating the notification, make sure that you include a descriptive title and message. Optionally, you can also provide a full-screen intent.

An example notification appears in the following code snippet:

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)

    // 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 in order for the
    // platform to invoke this notification.
    .setFullScreenIntent(fullScreenPendingIntent, true)

val incomingCallNotification = notificationBuilder.build()

 

Display the notification to the user

When displaying your notification to the user, they can then choose, based on their current context, whether to acknowledge or dismiss your app's alert or reminder. For example, the user can choose whether to accept or reject an incoming phone call.

If your notification is an ongoing one, such as an incoming phone call, associate the notification with a foreground service. The following code snippet shows how to display a notification that's associated with a foreground service:

// Provide a unique integer for the "notificationId" of each notification.
startForeground(notificationId, notification)

 

Note: The system UI may choose to display a heads-up notification, instead of launching your full-screen intent, while the user is using the device.

Benefits of notifications

This notification-based alert and reminder system provides several advantages for users:

  • When using the device, the user is shown a heads-up notification that allows them to answer or reject the call, or to dismiss the alarm. The user maintains their current context and has control over the content that they see on the screen.
  • Your incoming call or alarm respects the user's Do Not Disturb rules. For example, users might permit calls only from specific contacts, or repeat callers, when Do Not Disturb is enabled.
  • When the device's screen is off, your full-screen intent is launched immediately.
  • In the device's Settings screen, the user can see which apps have recently sent notifications, including from specific notification channels. From this screen, the user can control their notification preferences.

Disable the behavior change

It's recommended that you keep this behavior change enabled. That way, you can be more confident that users can continue interacting with your app as expected when Android Q is installed on their devices.

If this change prevents you from testing a core workflow in your app, however, you can disable the behavior change during testing by completing one of the following tasks:

  • Navigate to Settings > Developer options, and enable the Allow background activity starts option.
  • In a terminal window, run the following command:

    adb shell settings put global background_activity_starts_enabled 1
    

     

Note: After Android Q is released to the public, this developer option will continue to be available.

 

Android Q privacy change: User control over app access to device location

As of Android Q Beta 3, this change has the following properties:

  • Affects your app if you request access to device location while in the background
  • The user might receive a reminder after giving an app access to device location in the background
  • Mitigate by using new permission to access location in the background and by ensuring graceful degradation in the absence of background location updates
  • Behavior is always enabled on Android Q

We're interested in hearing your feedback! Report issues you find when using this feature during the Android Q beta program.

Screen capture of user-facing dialog

Figure 1. Dialog requesting user consent for location

Android Q gives users more control over when apps can get access to device location. 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 in use (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 a new location permission,ACCESS_BACKGROUND_LOCATION. Unlike the existing ACCESS_FINE_LOCATION andACCESS_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.

Request background location

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:

<manifest>
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
</manifest>

 

If your app runs on Android Q but targets Android 9 (API level 28) or lower, the following behavior applies:

Caution: Although your app can request and receive the ACCESS_BACKGROUND_LOCATION permission, the user can revoke this permission by choosing that your app should access location information only in the foreground.

Request background location access

Note: This section applies to all apps running on Android Q, regardless of which version they target.

If your app's use case requires access to location information when running in the background, it's important to consider the extent to which you need this access:

  • Your app's use case relies on a continuation of a user-initiated action, such as navigation or a smart home action. In that case, configure your foreground service so that it can retain access to a device's location after the user presses the Home button on their device or turns their device display off, even if the user has requested that your app have access to device location only in the foreground.
  • Your app's use case relies on periodic checks of a device's location all the time, such as geofencing or location sharing. In that case, your app should explain to the user that they need to give your app access to device location all the time in order to operate correctly, then request access to background location.

Continuation of user-initiated action

Note: If your app doesn't require location access while running in the background, it's a best practice to target Android Q and not request the new background location permission. That way, your app only receives location updates while it's in use.

An example of such an app appears in the LocationUpdatesForegroundService project on GitHub.

In cases where the user has given your app foreground-only access to location, the user might still launch a workflow that requires your app to access their location, even after the user presses the Home button on their device or turns their device's display off.

To retain access to the device's location in this specific use case, start a foreground service that you've declared as having a foreground service type of "location" in your app's manifest:

<service
    android:name="MyNavigationService"
    android:foregroundServiceType="location" ... >
    ...
</service>

 

Before starting the foreground service, make sure that your app still has access to the device's location:

KOTLINJAVA

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);
}

 

Periodic checks of device's location

Your app might have a use case that requires access to the device's location all the time. Such use cases include geofencing and location sharing with friends and family.

If these conditions apply to your app, you can continue requesting location updates without any changes, as long as the user grants your app all-the-time access to their location:

<!-- It's unnecessary to include a foreground service type for services that must have
     access to the device's location "all the time" in order to run successfully.-->
<service
    android:name="MyFamilyLocationSharingService" ... >
    ...
</service>

 

An example of such an app is the LocationUpdatesPendingIntent project on GitHub.

Screen capture of system notification

Figure 2. Notification reminding user that they've granted an app "all-the-time" access to device location

Each time the user chooses to allow your app all-the-time access to device location, the system schedules a notification to send to the user. This notification reminds the user that they've allowed your app to access device location all the time. An example notification appears in Figure 2.

Although your app can request access to location in the background, the user has the option to reduce your app's access to foreground only or revoke access entirely. For this reason, whenever your app starts a service, check whether the user still allows your app to access location information in the background.

If the user has requested that your app access location only in the foreground, it's a best practice for your app to display a custom dialog, alerting the user that a workflow within your app cannot function properly without access to their location all the time. After the user acknowledges this dialog, you can request background location, at which time the system dialog shown in Figure 3 appears:

Screen capture of user-facing dialog

Figure 3. Dialog requesting user consent for all-the-time access to location

An example of this permission-checking logic appears in the following code snippet:

KOTLINJAVA

boolean permissionAccessCoarseLocationApproved =
    ActivityCompat.checkSelfPermission(this, permission.ACCESS_COARSE_LOCATION)
        == PackageManager.PERMISSION_GRANTED;

if (permissionAccessCoarseLocationApproved) {
   boolean backgroundLocationPermissionApproved =
           ActivityCompat.checkSelfPermission(this,
               permission.ACCESS_BACKGROUND_LOCATION)
               == PackageManager.PERMISSION_GRANTED;

   if (backgroundLocationPermissionApproved) {
       // App can access location both in the foreground and in the background.
       // Start your service that doesn't have a foreground service type
       // defined.
   } else {
       // App can only access location in the foreground. Display a dialog
       // warning the user that your app must have all-the-time access to
       // location in order to function properly. Then, request background
       // location.
       ActivityCompat.requestPermissions(this, new String[] {
           Manifest.permission.ACCESS_BACKGROUND_LOCATION},
           your-permission-request-code);
   }
} else {
   // App doesn't have access to the device's location at all. Make full request
   // for permission.
   ActivityCompat.requestPermissions(this, new String[] {
        Manifest.permission.ACCESS_COARSE_LOCATION,
        Manifest.permission.ACCESS_BACKGROUND_LOCATION
        },
        your-permission-request-code);
}

 

Design for device upgrade scenarios

If a user completes the following steps:

  1. Installs your app on a device running Android 9 (API level 28).
  2. Grants your app access to device location – either ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION.
  3. Upgrades their device from Android 9 to Android Q.

...then the system automatically updates your app's default location permission state based on its target SDK version and its defined permissions, as shown in the following table:

Table 1. Changes in location permission state after device upgrade to Android Q

Target SDK versionCoarse or fine
permission granted?
Background permission
defined in manifest?
Updated default permission state
Android QYesYesForeground and background access
Android QYesNoForeground access only
Android QNo(Ignored by system)No access
Android 9 or lowerYesAutomatically added by the system at device upgrade timeForeground and background access
Android 9 or lowerNo(Ignored by system)No access

Note: Even after the system automatically updates your app's access to device location, the user has the option to change this level of access. The user might reduce your app's access to foreground only or revoke access entirely.

For this reason, before accessing the device's location updates, follow best practices to check whether the user still allows your app to receive this location information.

Follow location best practices

By checking and requesting location permissions in the ways shown in this guide, your app can successfully keep track of its level of access to device location.

For more information about how to keep your users' data safe, see the permissions best practices guide.

Ask only for the permissions you need

Ask for permissions only when needed. For example:

  • Don't request a location permission at app startup unless absolutely necessary.
  • If your app targets Android Q and needs access to location information only when running in the foreground, don't request ACCESS_BACKGROUND_LOCATION.

Support graceful degradation if permission isn't granted

To maintain a good user experience, design your app so that it can gracefully handle the following situations:

  • Your app doesn't have any access to location information.
  • Your app doesn't have access to location information when running in the background.

Additional resources

For more information about changes regarding an app's access to device location, see the following additional resources:

Samples

 

Android Q privacy: Changes to data and identifiers

This document describes several restrictions placed on accessing data and system identifiers. These changes help protect users' privacy.

Some of these changes affect all apps running on Android Q while other changes affect only apps that target Android Q.

Changes affecting all apps

The following changes affect all apps running on Android Q, even if they target Android 9 (API level 28) or lower.

Contacts affinity

Starting in Android Q, the platform no longer keeps track of contacts affinity information. As a result, if your app conducts a search on the user's contacts, the results are no longer ordered by frequency of interaction.

The Contacts Provider guide contains a notice describing the specific fields and methods that are obsolete on all devices as of Android Q.

Randomized MAC addresses

Devices running on Android Q transmit randomized MAC addresses by default. If your app handles an enterprise use case, the platform provides several new APIs:

  • Obtain randomized MAC address: Device owner apps and profile owner apps can retrieve the randomized MAC address assigned to a specific network by calling getRandomizedMacAddress().
  • Obtain actual, factory MAC address: Device owner apps can retrieve a device's actual hardware MAC address by calling getWifiMacAddress(). This method is useful for tracking fleets of devices.

Access to /proc/net filesystem

Android Q removes access to /proc/net, which includes information about a device's network state. Apps that need access to this information, such as VPNs, should refer to the NetworkStatsManager and ConnectivityManagerclasses.

Non-resettable device identifiers

Starting in Android Q, apps must have the READ_PRIVILEGED_PHONE_STATE privileged permission in order to access the device's non-resettable identifiers, which include both IMEI and serial number. Many use cases don't need non-resettable device identifiers. 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 target SDK version:

  • If your app targets Android Q, a SecurityException occurs.
  • If your app targets Android 9 (API level 28) or lower, the method returns null or placeholder data if the app has the READ_PHONE_STATE permission. Otherwise, a SecurityException occurs.

Note: If your app is the device or profile owner app, you need only the READ_PHONE_STATE permission to access non-resettable device identifiers, even if your app targets Android Q. Also, if your app has special carrier permissions, you don't need any permissions to access the identifiers.

If your app uses non-resettable device identifiers for ad-tracking or user analytics purposes, create an Android Advertising ID for those specific use cases instead. To learn more, see best practices for unique identifiers.

Access to clipboard data

Unless your app is the default input method editor (IME) or is the app that currently has focus, your app cannot access clipboard data.

Changes affecting apps targeting Android Q

The following change affects apps only if they target Android Q.

Access to USB serial requires user permission

If your app targets Android Q, your app can only read the serial number after the user has granted your app permission to access the USB device or accessory.

 

Android Q privacy: Changes to camera and connectivity

This document describes several restrictions placed on accessing camera and connectivity information. These changes help protect users' privacy.

Some of these changes affect all apps running on Android Q while other changes affect only apps that target Android Q.

Changes affecting all apps

The following change affects all apps running on Android Q, even if they target Android 9 (API level 28) or lower.

Access to all camera information requires permission

Android Q changes the breadth of information that the getCameraCharacteristics() method returns by default. In particular, your app must have the CAMERA permission in order to access potentially device-specific metadata that is included in this method's return value.

If your app doesn't have the CAMERA permission, it cannot access the following fields:

  • ANDROID_LENS_POSE_ROTATION
  • ANDROID_LENS_POSE_TRANSLATION
  • ANDROID_LENS_INTRINSIC_CALIBRATION
  • ANDROID_LENS_RADIAL_DISTORTION
  • ANDROID_LENS_POSE_REFERENCE
  • ANDROID_LENS_DISTORTION
  • ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE
  • ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE
  • ANDROID_SENSOR_REFERENCE_ILLUMINANT1
  • ANDROID_SENSOR_REFERENCE_ILLUMINANT2
  • ANDROID_SENSOR_CALIBRATION_TRANSFORM1
  • ANDROID_SENSOR_CALIBRATION_TRANSFORM2
  • ANDROID_SENSOR_COLOR_TRANSFORM1
  • ANDROID_SENSOR_COLOR_TRANSFORM2
  • ANDROID_SENSOR_FORWARD_MATRIX1
  • ANDROID_SENSOR_FORWARD_MATRIX2

Changes affecting apps targeting Android Q

The following changes affect apps only if they target Android Q.

Restriction on enabling and disabling Wi-Fi

Apps targeting Android Q cannot enable or disable Wi-Fi. The WifiManager.setWifiEnabled() method always returns false.

If needed, use a settings panel to prompt users to enable and disable Wi-Fi.

Wi-Fi network configuration restrictions

To protect user privacy, manual configuration of the list of Wi-Fi networks is now restricted to system apps and device policy controllers (DPCs). A given DPC can be either the device owner or the profile owner.

If your app doesn't fall into one of these categories and targets Android Q, the following methods no longer return useful data:

  • The getConfiguredNetworks() method always returns an empty list.
  • Each network operation method that returns an integer value—addNetwork() and updateNetwork()—always returns -1.
  • Each network operation that returns a boolean value—removeNetwork()reassociate()enableNetwork()disableNetwork()reconnect(), and disconnect()—always returns false.

If your app needs to connect to Wi-Fi networks, use the following alternative methods:

Fine location permission needed for telephony, Wi-Fi, Bluetooth APIs

Unless your app has the ACCESS_FINE_LOCATION permission, your app cannot use several methods within the Wi-Fi, Wi-Fi Aware, or Bluetooth APIs when running on Android Q. The following list shows the affected methods.

Note: If your app is running on Android Q but targets Android 9 (API level 28) or lower, you can use the affected APIs as long as your app has the ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission.

Telephony

Wi-Fi

Bluetooth

  • BluetoothAdapter
    • startDiscovery()
    • startLeScan()
    • LeScanCallback()Android Q privacy: Changes to permissions
  • This document describes several changes to the permissions model. These changes serve to enhance user privacy.

    The following changes affect all apps running on Android Q, even if they target Android 9 (API level 28) or lower.

    Restricted access to screen contents

    To protect users' screen contents, Android Q prevents silent access to the device's screen contents by changing the scope of the READ_FRAME_BUFFERCAPTURE_VIDEO_OUTPUT, and CAPTURE_SECURE_VIDEO_OUTPUT permissions so that they're signature-access only.

    Apps that need to access the device's screen contents should use the MediaProjection API, which displays a prompt asking the user to provide consent.

    User-facing permission check on legacy apps

    If your app targets Android 5.1 (API level 22) or lower, users see a permissions screen when running your app on Android Q for the first time, as shown in Figure 1. This screen gives users the opportunity to revoke access to permissions that the system previously granted to your app at install time.

    Caution: If you want to publish your app on Google Play, you must target Android 8.0 (API level 26) or higher. To learn more, see the guide on how to meet Google Play's target API level requirement.

    Screen capture of dialog

    Figure 1. User-facing dialog that allows review of legacy permissions

    Physical activity recognition

    Android Q introduces a new ACTIVITY_RECOGNITION runtime permission for apps that need to detect the user's movement, such as walking, biking, or in a vehicle. This is designed to give users visibility of how device sensor data is used in Settings.

    If your app targets Android 9 (API level 28) or lower and specifies thecom.google.android.gms.permission.ACTIVITY_RECOGNITION permission in its manifest file, the system auto-grants this permission to your app if needed. However, the user can revoke this permission at any time in system settings.

    Note: Some libraries within Google Play services, such as the Activity Recognition API, don't provide results unless the user has granted your app this permission.

    Permission groups removed from UI

    As of Android Q, apps cannot look up how permissions are grouped in the UI.

  •  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值