Random Musings on the Android 15 Beta 2

When Google releases a new beta, I rummage through the API differences report, 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 update contained a surprising amount of stuff for a second beta release. Usually by now I have no more random musings, because there is little to review. Technically, though, the first “platform stability” release is June’s, so Google just has some late-breaking changes.

What Might Break You

All apps ought to get private spaces, though most should not have an issue. If you deal with work profiles, are a launcher, or are an app store, you may have additional work to do. You might be interested in the new ACTION_PROFILE_AVAILABLE and ACTION_PROFILE_UNAVAILABLE broadcasts.

If you use NDK code (yourself or via libraries), the 16KB page size support needs to be investigated.

There is a new restriction on activity launches from back in a task’s stack. This appears to be opt-in via android:allowCrossUidActivitySwitchFromBelow. While it is in the “only affects you if you target Android 15” documentation, it is unclear if that affects the app doing the blocking, the app that might be blocked, both, or none (i.e., the docs are in the wrong spot). There are a variety of other restrictions on semi-background activity starts that hopefully won’t affect you.

screenWidthDp and screenHeightDp on Configuration now include the depth of the system bars.

What Might Break You Next Year

The 6-hour-maximum foreground service status for dataSync and mediaProcessing services will only kick in once you target Android 15 or higher.

Similarly, the boot-time restrictions on what foreground services you can start only appear when you target Android 15 or higher.

Your TextViews may add more end padding once you target Android 15, to better accommodate varying fonts and languages.

What Makes Me Go 🤨

They tightened some unsafe Intent structures, but made it opt in via StrictMode and possibly targeting Android 15.

There is a new contentSensitivity attribute for View, though it is unclear what it controls.

There is a new shouldDefaultToObserveMode attribute, probably for <service>… but we are not told what “observe mode” is.

There is a new systemUserOnly attribute for all components (activities, services, etc.). This feels like it is tied to private spaces, to have some component be ineligible for use in a private space, but that’s just a guess, because it is poorly documented.

There is a new form of requestPermissions() that takes a device ID, and it is unclear what the “device” is in this context.

There is a new registerResourcePaths() method on Resources, which seems like it allows for dynamically adding new resources, such as from some sort of library.

PowerMonitor “represents either an ODPM rail (on-device power rail monitor) or a modeled energy consumer”, which I am certain makes some sense to somebody.

There is a new form of RemoteViews that works off of DrawInstructions, but it is completely non-obvious how you create those instructions.

What Else Helps with Security

You can place an android:requireContentUriPermissionFromCaller attribute on your <activity> element to enforce that the activity that starts yours and passes a Uri has certain permissions with respect to that Uri. Similarly, you can use checkContentUriPermissionFull() on Context to see if some other app and/or user has rights to a particular Uri.

What Seems Nice

You can positively state what language your plain res/values/strings.xml file is in via a defaultLocale attribute. Presumably this goes on <application> given its scope, but as is all too typical, that is undocumented.

You now finally can find out what activity created yours, via getInitialCaller(). There is also getCurrentCaller(), which handles both onNewIntent() and onActivityResult() cases. Finally, there is a getCaller() method, but it is unclear how that differs from getInitialCaller().

You can create customized previews for your app widgets via methods like setWidgetPreview() on AppWidgetManager.

You can opt into custom vibration effects on a NotificationChannel.

You can add up to 32 “debug tags” to a JobScheduler job.

What Is Back From the Dead, Only To Die Again

Slices – a new UI option added several years ago that nobody every really seemed to use – got some API changes! Alas, those changes are deprecation notices. I once again apologize to those who attended a conference presentation on slices that I delivered years ago.

What Else Caught My Eye

There are a bunch of new permissions related to device policy controllers, such as MANAGE_DEVICE_POLICY_BLOCK_UNINSTALL.

There are new options on WindowManager for “small cover screen” UIs.