Getting your app ready for SplashScreen API, Approximate Location, PendingIntent Mutability and much more …
Google announced Android 12 (L) on October 2021 and by March 2022 the stable build was released starting with the Pixel phones and soon followed by other major brands.
Android 12 comes with some big visual and user experience changes, also focusing on Privacy and Performance.
I thought that this article was necessary as now Google Play Store has enforced to update all the applications to target to API Level 31 (i.e. Android 12) by November 2022 and as I was still getting queries from many of you on how to migrate to Android 12, so here it is!
In this article, we will quickly start with the important stuff first and later will be reviewing some enhancements that are worth mentioning and deprecations of existing APIs and features.
So let’s quickly jump to what all changes you need to do to target your application to Android 12 and the things to keep in mind.
Whenever you define any component (like Activity, Service and Broadcast Receiver) in the manifest, you must have seen/used some thing like
By default this attribute is set to
true, which means that the component can be accessed from outside of your application. For example, If an activity in your app includes intent filters, set this element to “true” to allow other apps to start it.
From API 31 onward, you have to explicitly set a value to this attribute.
A common rule of thumb is: If the app component includes the LAUNCHER category, set
true. In most other cases, set
<service android:name="com.example.app.backgroundService" android:exported="false"> <intent-filter> <action android:name="com.example.app.START_BACKGROUND" /> </intent-filter> </service>
Failing to do so might throw a compile time:
Manifest merger failed : Apps targeting Android 12 and higher are required \ to specify an explicit value for android:exported when the corresponding \ component has an intent filter defined.
Pending intents mutability
API level 31 onward, you will have to specify the mutability of each PendingIntent object that your app creates.
val updatedPendingIntent = PendingIntent.getActivity( applicationContext, NOTIFICATION_REQUEST_CODE, updatedIntent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT )
Failing to do so the system throws an
PACKAGE_NAME: Targeting S+ (version 31 and above) requires that one of \ FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent. Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if \ some functionality depends on the PendingIntent being mutable, e.g. if \ it needs to be used with inline replies or bubbles.
Starting in Android 12, users can now chose to provide either Precise location or Approximate Location, even when your app requests the ACCESS_FINE_LOCATION runtime permission.
You will have to handle for both the scenarios now in order to respect users’ privacy, however if your apps use-case is such that requires Precise Location then make sure that the same is prompted to the user and handled in your app accordingly. Read more on asking for Precise location.
I recommend that you read the Best Practices on Requesting Location Permissions.
Earlier most of us used to create a custom Splash screens by using an Activity or setting a window theme on an Activity.
If you have previously implemented a custom splash screen in Android 11 or lower, you’ll need to migrate your app to the
SplashScreen API to ensure that it displays correctly starting in Android 12.
On devices running on Android 11, this won’t be a problem but if you have targeted API level 31 and still not migrated to SplashScreen API, the system will throw a Runtime Exception on Android 12 devices.
It’s also worth noting that the system always applies the new Android system default splash screen on cold and warm starts for all apps. By default, this system default splash screen is constructed using your app’s launcher icon element and the
windowBackground of your theme (if it’s a single color).
Read more about Android Splash Screens
Bonus: Along with the new SplashScreen API, you can also make use of App Startup library to initialize components at application startup.
Exact alarm permission
To create an Exact alarm, your app needs have have access to the “Alarms & reminders” capability that appears within the Special app access screen in system settings.
To obtain this special app access, request the
SCHEDULE_EXACT_ALARM permission in the manifest.
Failing to do so, system will throw
But the catch here is that to obtain this special permission and get approval by Google Play store, your app must be of one of the following type:
1. Clock or Timer application
2. Calendar or Reminder application
Web intent resolution
Starting in Android 12 (API level 31), your app’s Activity can no longer resolve to generic web intents, the system will redirect them to the default browser, until your app is approved to handle that web intent.
Read more about how your app can get this approval.
Also read more about App Links verification changes.
Foreground service launch restrictions
Starting from API Level 31, system will throw an Exception if your app tries to trigger a Foreground Service while running in the background.
However there are few exemptions to that, some of the interesting exemptions are:
- The user turns off battery optimizations for your app. You can help users find this option by sending them to your app’s App info page in system settings. To do so, invoke an intent that contains the
ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS intent action.
- The user performs an action on a UI element related to your app. For example, they might interact with a bubble, notification, widget, or activity.
- Your app can start an activity from the background, except for the case where the app has an activity in the back stack of an existing task.
- Your app receives a high priority message using Firebase Cloud Messaging.
If you used Custom Notification in your app, starting from Android 12, notifications with custom content views will no longer use the full notification area; instead, the system applies a standard template.
Notification Template. (Source)
This is to make the notification visually consistent for all apps and in all states like collapsed and expandable.
Notification Collapsed and Expanded state. (Source)
The change in Android 12 affects apps that define custom subclasses of
Notification.Style, or which use
If you are not using the above methods, then you are all good.
Read more about Custom Notifications.
Other improvements/ features worth Mentioning
Till now we have covered the main things that you need to migrate your app to Android 12, but there are a few things that you should know.
Restricted App Standby Bucket
We read about the App Standby Buckets before, simply put, these buckets help the system prioritize apps’ requests for resources based on how recently and how frequently the apps are used.
Now a new App Standby Bucket is introduced: Restricted.
According to the documentation, The system considers your app’s behavior, in addition to usage patterns, to decide whether to place your app in the restricted bucket. Your app is less likely to be placed in the restricted bucket if your app uses system resources more responsibly. Also, the system places your app in a less restrictive bucket if the user interacts directly with your app.
Read more about Restricted App Standby Bucket.
Microphone and camera indicators and toggle
Camera and Microphone indicators on the status bar. (Source)
Just like in Apple products, Android too has this feature now where you will get to see an indicator on the status bar whenever your device’s Camera or Microphone is in use.
Also, supported devices that run Android 12 or higher allow users to enable and disable camera and microphone access for all apps on the device, by pressing a single toggle option.
Read more about the best practices to access to more sensitive permissions.
Root launcher activities are no longer finished on Back press
If your activity is the root activity (ie. the last activity on the task stack), on press of the back button, it wont be killed but simply put to background. Just like how the press the home button.
Also, it is recommended using the AndroidX Activity APIs for providing custom back navigation, rather than overriding
Read more about this.
Bouncy Castle implementation removed
Android 12 removes many BouncyCastle implementations of cryptographic algorithms that were previously deprecated, including all AES algorithms. The system instead uses the Conscrypt implementations of these algorithms.
Read more about this.
Display#getRealSize and getRealMetrics : deprecated
The following methods are deprecated:
Display.getSize() — Deprecated: Android 11 onward
Display.getMetrics() — Deprecated:Android 11 onward
Display.getRealSize() — Deprecated:Android 12 onward
Display.getRealMetrics() — Deprecated:Android 12 onward
Apps can’t close system dialogs
Starting with Android 12, you won’t be able to close system dialogs as the
ACTION_CLOSE_SYSTEM_DIALOGS intent action is deprecated. If you try to launch this intent, the system will simply throw a
SecurityException . On Android 11 devices, the system will ignore the intent.
However there are few special cases, Read more about this change.
- About Android 12
- Migrate Apps to Android 12
- Behavior changes in Android 12 for All apps and for apps targeting Android 12.
- Target API level requirements for Google Play apps
Let me know your suggestions and if you think I missed mentioning an important change in Android 12.
Now that you know everything to migrate your amazing app to Android 12, what are you waiting for?
See you next time.
This article was originally published on proandroiddev.com on July 17, 2022