Random Musings on the Android 15 Developer Preview 2

When Google releases a new developer preview, I rummage through the API differences report (even when Google does not seem to link to them 🙃), the high-level overviews, and even the release blog post, to see if there are things that warrant more attention from developers. I try to emphasize mainstream features that any developer might reasonably use, along with things that may not get quite as much attention, because they are buried in the JavaDocs.

This release is much larger than was the previous developer preview. It feels like Developer Preview 1 was “low-hanging fruit”, to give developers an additional month or so on the major changes for Android 15.

What Might Break You This Year

If your app is force-stopped, all pending intents are cancelled. This change affects all apps, not just those targeting Android 15. I thought this was already the behavior, but apparently it is not. For some devices that ship with “task managers” that apply force-stop logic instead of only terminating app processes, this change may really impact your users. Fortunately, at least, you will now get ACTION_BOOT_COMPLETED broadcast to your app so you can re-establish anything that was canceled. However, there also is a new ACTION_PACKAGE_UNSTOPPED broadcast that you might consider. PackageManager also now has an isPackageStopped() function, so external parties can see if your app was force-stopped.

FINGERPRINT_SERVICE was removed from Context, further impacting the already-deprecated FingerprintManager.

What Might Break You Next Year

Once you target Android 15, you will not be allowed to start some types of foreground services at boot time. I can see this causing problems for a fair number of apps.

Also, once you target Android 15, if your app supports Arabic, Lao, Myanmar, Tamil, Gujarati, Kannada, Malayalam, Odia, Telugu or Thai, then Android will use a taller font by default. This may cause UI glitches, such as text being cut off due to lack of sufficient vertical space.

What I Like of the Prominent Changes

Google taking PDF rendering seriously is a nice improvement. PdfRenderer was designed for use in print previews, but developers have been trying to use it for arbitrary PDFs, with varying results. And since many developers really do not want to use the user’s preferred PDF reader, we were stuck with various workarounds. The fact that the improved PdfRenderer is being backported and apparently will be wrapped in a Jetpack library also helps a great deal.

Support for deeplink filtering on query parameters and fragments is something that developers have been requesting for several years, so it is good that we are getting it, even if that is not something that can be backported.

Granular line-break controls, so we can keep titles contiguous, is a long-awaited text rendering improvement.

Similarly, developers have been asking for how to find out why the app was started for quite some time.

Screen recording detection provides a nice middle ground between being oblivious to screen recording and using FLAG_SECURE to block it entirely. Note that you need a new normal permission to enable this capability.

What Makes Me Go “Hmmmmm…”

Resources now has a registerResourcePaths() method. “This will collect the package resources’ paths from its ApplicationInfo and add them to all existing and future contexts while the application is running”.

Getting and setting the system bar colors is now deprecated.

What Else You Might Have Missed

Your manifest components (activities, services, receivers, and providers) can be protected with android:systemUserOnly="true". This is supposed to limit that component to at most one instance, and that instance can only be interacted with by the system user. My hope is that we can use this for specific places where we want to plug into the framework but want to preclude arbitrary other apps from trying to use the component.

Through DevicePolicyManager, eligible apps can mandate “content protection” or can allow user choice. In this case, “content protection” means “scanning for deceptive apps”. Similarly, a device owner or policy owner can block NFC for certain users.

For app stores, ACTION_UNARCHIVE_PACKAGE might prove interesting. Also, PackageInstaller now has a new set of APIs related to archiving apps.

There are new KeyEvent key code values for dedicated emoji picker and screenshot keys.

We can now limit drag-and-drop to be just within our app, even if we have multiple windows. We can also specify an activity IntentSender to use for unhandled drops.