Adaptation of your app for Android 11
Privacy — a focus area of Android 11. Android security is always a hot topic and almost always for the wrong reason, including Google’s failure to prevent malicious apps from being distributed through the Play Store, over-claim of permissions by apps, and privacy leakages.
According to Google’s latest announcement, the latest Android 11 OS includes a few new built-in measures designed to keep users’ data secure by default, increase transparency, and offer better control.
So what do developers need to do by switching to the SDK 30 target?
1. One-time Permissions
The first one is the One-time Permissions, this feature allows users to grant apps single-use access to the device’s most sensitive permissions, such as location, microphone, and camera.
Thus, the apps are required to retake permissions before re-assessing the sensors. This feature is not new in Android but was earlier only available to use while downloading a new app from the Google Play Store.
Some apps may trigger the same permission prompt after installing and others while accessing sensors for the first time, increasing a layer of privacy.
2. Auto-Reset Permissions for unused apps
This one is new. If suddenly, you have not interacted with an installed application for several months or completely forgot about it after downloading and granting the necessary permissions.
In addition to threatening your privacy, such applications may continue to use your device’s hardware resources or access your data in the background.
At one point, the application can revoke all permissions, but what to do if your application needs to use permissions while it may not be launched often, for example, a House Alarm security app?
If needed, you can ask the user to prevent the system from resetting your app’s permissions. This is useful in situations where users expect your app to work primarily in the background, even without the user interacting with your app, such as in the following use cases:
- Provide family safety.
- Sync data.
- Smart device connectivity app.
- Pair to companion devices.
To direct the user to your app’s page in system settings, invoke an intent that includes the Intent.ACTION_AUTO_REVOKE_PERMISSIONS
intent action. From this screen, users can prevent the system from resetting your app's permissions by doing the following:
- Tap Permissions, which loads the App permissions settings screen.
- Turn off the option called Remove permissions if app isn’t used
Determine whether auto-reset is disabled
For checking whether auto-reset functionality is disabled for your app, call isAutoRevokeWhitelisted()
. If this method returns true
, then the system doesn't auto-reset your app's permissions.
3. Background Location Access
One of the most significant privacy changes in Android 11 is to limit access to the device’s background location.
If a feature in your app accesses location from the background, verify that such access is necessary. Consider getting the information that the feature needs in other ways, as described on the page about how to access location in the background.
And also you should perform incremental location requests. If your app targets Android 11 or higher, the system enforces this best practice. If you request a foreground location permission and the background location permission at the same time, the system ignores the request and doesn’t grant your app either permission.
To enable background location access, users must set the ‘Allow all the time’ option for the app’s location permission on a settings page.
Besides this, Google also requires Android app developers to explain why their app needs background location access in the first place.
4. Data Access Auditing APIs
To provide more transparency on how your app and its third-party dependencies access user’s personal data, data access auditing is implemented in Android 11. By analyzing this process, you can better identify potentially unexpected data access.
Your app can register an AppOpsManager.OnOpNotedCallback
instance that can take action every time one of the following events occurs:
- Your app’s code accesses private data. To help you determine which logical part of your app invoked the event, you can audit data access by attribution tag.
- Code in a dependent library or SDK accesses private data.
Data access auditing is invoked on the thread on which the data request is made. This means that if a third-party SDK or library in your application calls an API that accesses personal data, data access auditing allows your OnOpNotedCallback
to validate the call information. Typically, this callback object can determine if the call came from your application or SDK by looking at the current status of the application, such as the stack trace of the current thread.
The onAsyncNoted()
and onSelfNoted()
methods are called in specific situations:
onAsyncNoted()
is called if the data access doesn't happen during your app's API call. The most common example is when your app registers a listener and the data access happens each time the listener's callback is invoked.- The
AsyncNotedOp
the argument that's passed intoonAsyncNoted()
contains a method calledgetMessage()
. This method provides more information about data access. In the case of the location callbacks, the message contains the system-identity-hash of the listener. onSelfNoted()
is called in the very rare case when an app passes its own UID intonoteOp()
.
5. Foreground services in Android 11
Android 10 was introduced access to private data in foreground services, where the platform relies on foreground service-type attribute in a manifest.
Apps can declare their intentions to access this information within their foreground services.
One of the enforced types is location. To access in foreground service you must declare the location
foreground service type as an attribute of your <service>
component.
In Android 11, there’s a couple of new types, camera, and microphone.
At runtime, if the foreground service only needs access to a subset of the types declared in the manifest, you can limit the service’s access using the logic in the following code snippet:
6. Package Visibility And Interaction
To provide better accountability for access to installed apps on a device, Android 11 includes some changes to how apps can query and interact.
We usually check if the application is installed on the system in this way:
But in android 11, you get an NameNotFoundException
regardless of whether the specified package is installed.
Let’s go through a few cases and ways to handle them.
Query and interact with specific packages
If you need to explicitly interact with another app, for e.g., bind or service, use the new elements in a manifest:
Query and interact with apps based on intent filters
Your application may need to query or interact with a set of applications that serve a specific purpose, but you may not know the specific names of the packages to include. In this situation, you can list the intent filter signatures
Interacting with all apps
However, the system also provides query or packages permission, which would allow certain use cases to read all installed packages.
This can be done by declaring QUERY_ALL_PACKAGES
permission in the manifest:
Approved application categories for using QUERY_ALL_PACKAGES
permission:
- Launcher apps
- Accessibility apps
- Browsers
- Peer-to-peer (P2P) sharing apps
- Device management apps
- Security apps
Look for upcoming guidance from Google Play for apps
that need this permission.
7. Let non-browser apps handle URLs
Sometimes, if an app sends a view intent with a certain URL, you may want to take the user directly to the default native app instead of a web browser.
If you just did this, your user may get a disambiguation dialog
box, not the most direct way.
If you want to prevent the browser from opening the link, add the FLAG_ACTIVITY_REQUIRE_NON_BROWSER
intent flag:
If an intent includes this flag, a call to startActivity()
causes an ActivityNotFoundException
to be thrown when either of the following conditions occurs:
- The call would have launched a browser app directly.
- The call would have shown a disambiguation dialog to the user, where the only options are browser apps.
8. Scoped Storage
And of course a few words about the storage.
After you update your app to target Android 11, the system ignores the requestLegacyExternalStorage
flag, which was added in Android 10 for a smooth migration. Best practice and more info about scope storage on the link
Deprecation and changes in API 30
IntentService
Starting from API Level 30 IntentService
is deprecated.
Alternatively, Google suggests using WorkManager
and JobIntentService
.
AsyncTask
AsyncTask
is also deprecated, use Coroutines API instead.
Toast
In Android 11, Google implements the following changes on Toast
:
- Background customized Toast is prohibited
- Customization is not allowed
- Functions
setView()
getView()
is DEPRECATED - Newly added callback —
Toast.Callback
setMarging()
andsetGravity()
is a no-op
Handler
Non-looper constructors of Handler
is deprecated because it can lead to bugs where operations are silently lost (if the Handler is not expecting new tasks and quits), crashes (if a handler is sometimes created on a thread without a Looper active), or race conditions, where the thread a handler is associated with is not what the author anticipated.
Instead, use an Executor
or specify the Looper explicitly, using Looper.getMainLooper()
, or similar. If the implicit thread-local behavior is required for compatibility, use new Handler(Looper.myLooper())
to make it clear to readers.
Conclusions
So, this was a quick overview of what you will have to face in adapting your application to the updated security and privacy policies of Android 11. Make your applications better, use the best practices approved by Google.
If you feel there is something important that I missed out on, let me know in the comment below. If you found the article helpful, please applause the article and follow me on twitter at @Shadyrover