Random Musings on the Android 14 Developer Preview 2

When Google releases a new developer preview, 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.

So… what does DP2 have in store for us?

What Got Top-Line Coverage

You can no longer kill app processes other than your own. I am stunned it took them this long to address this. Mishaal Rahmann has more on this.

You will not be able to install apps with a targetSdkVersion below 23. My hope is that Google, or somebody, uses hypervisor techniques (or something similar) to allow running older apps in a sandbox.

MediaStore tracks who owns what, but you might not be able to access that information.

What Changed with Screen Captures

There is a new DETECT_SCREEN_CAPTURE permission. This ties into registerScreenCaptureCallback() on Activity. As you might guess, this lets you find out when this activity is subject to a screen capture. It is unclear what sorts of screen captures are covered:

  • Screenshots only, or also screencasts?
  • Only from MediaProjection, or also from built-in OS mechanisms?
  • Does it include screen captures from development tools, like Android Studio?

Also note that the callback does not allow you to block the screen capture, just find out that it happened. You can block screen captures using FLAG_SECURE, at least to some extent.

There is also ACTION_LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE. This captures a screenshot, allows the user to edit it, and gives you the screenshot back via the Uri delivered to onActivityResult(). However, you will need to hold the LAUNCH_CAPTURE_CONTENT_ACTIVITY_FOR_NOTE permission, which is only available for apps in the ROLE_NOTES role.

What Is Choosy

For the “share sheet” (ACTION_CHOOSER), there are two new extras:

What Got Highlighted

TextView got highlighted. Specifically, there is a new setSearchResultHighlights() method to allow you to specify ranges for highlighting text. And, as Thomas Künneth noted there are new Highlights and Highlights.Builder classes for more sophisticated highlighting, with setHighlights() on TextView to apply them.

What Permissions Changed

There is a whole suite of new MANAGE_DEVICE_POLICY_* permissions, such as MANAGE_DEVICE_POLICY_CAMERA and MANAGE_DEVICE_POLICY_DEVICE_IDENTIFIERS. Presumably, this ties into DevicePolicyManager.

There is a new EXECUTE_APP_ACTION permission, limited to assistants.

What Is Not Long For This World

The “long jobs” stuff in JobScheduler is now “user-initiated jobs”. So, for example, the RUN_LONG_JOBS permission is now RUN_USER_INITIATED_JOBS.

What Changed with Broadcasts

A BroadcastReceiver can call getSentFromUid() and getSentFromPackage() to find out where the broadcast came from.

In related news, sendBroadcast() and sendOrderedBroadcast() now have variants that take a Bundle that you can build using BroadcastOptions. Right now, the only such option is whether or not the identity-sharing mentioned in the previous paragraph is enabled.

What Else Caught My Eye

There is a new overrideActivityTransition() method on Activity. The JavaDocs may make your head spin, as it ties into the older overridePendingTransition() method and “predictive back” navigation.

Health Connect got its own family of packages.

WindowManager has an addProposedRotationListener() method. Your callback gets a rotation value (e.g., Surface.ROTATION_180). “This listener gives application an opportunity to selectively react to device orientation changes”.

The USE_FULL_SCREEN_INTENT permission was added a few years ago, to control whether you can raise a full-screen notification. Now, there is ACTION_MANAGE_APP_USE_FULL_SCREEN_INTENT, which you can use to launch an activity to allow the user to grant your app permission to use “full screen intents”. And there is canSendFullScreenIntent() on NotificationManager to find out the status of that permission.

PowerManager now offers isAllowedInLowPowerStandby(), which will tell you if low power standby is disabled for one reason or another. You can also react to these changes, it appears, by registering a receiver for ACTION_LOW_POWER_STANDBY_POLICY_CHANGED.

JobScheduler now has the notion of namespaces.

While by default you can no longer create mutable PendingIntent objects wrapping an implicit Intent, FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT. might let you bypass that restriction.