Random Musings on the Android 14 Developer Beta 1

Random Musings on the Android 14 Developer Beta 1

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.

We’ve moved out of developer previews and into beta releases. That slows down
the pace of change, but still there some things worth mentioning. My focus is
on the developer side; see Mishaal Rahman’s Twitter thread for a broader look at Beta 1.

What Got Top-Line Attention?

One trend with these musings is that I cover something before Google does, for
one reason or another. Some stuff from my DP2 musings
that were announced this time were:

Also, Path is no longer a largely write-only API,
which has been a large pain point for developers over the years.

Something I noticed in DP2 but didn’t understand enough to write about is the
new limitation on accessibility services. Apps can indicate certain UI elements
that are only available to “true” accessibility services, those that actually
help people with accessibility. Mishaal Rahman wrote more about that.
or android:accessibilityDataSensitive
to enable this.

What Else At Least Was Announced

The concept of “non-dismissable notifications” was always a bit scary, insofar
as apps can really annoy users with those. They have been slowly becoming more
dismissable, and Android 14 makes them mostly dismissable.

While dynamic code loading via PathClassLoader and kin might get you banned from
the Play Store, it’s still a technique used by many an app. Android 14
requires that code to be marked as read-only,
once you are targeting Android 14.

Eight years ago, I published some safe unZIP code
to avoid path traversal attacks.
Android 14 now enforces that at the system level,
for apps targeting Android 14. I really hope safe unZIP code becomes available in a Jetpack
library, so it can be used by all apps on more OS versions.
Bonus points if they also stop ZIP bombs.

One hole in the background activity start limitation was IPC. Other apps could arrange
to start activities by convincing some other app to start them, such as via a
PendingIntent. Android 14 makes that opt-in,
for apps targeting Android 14.

What’s Outta Here

overridePendingTransition() on Activity
is deprecated, replaced by overrideActivityTransition().

Google removed the “data transfer” type of JobInfo.

What Could Be Kinda Wild

The IntentFilter class appears to now allow filtering by extras.
Since the parameter is a PersistableBundle, this is not merely filtering based on the
existence of extras by name, but presumably they also must match on value. Prior to
this, extras were purely “payload” of an Intent and were not something that you could
filter upon. It will be interesting to see where Google puts this to use.

What Else Caught My Eye

View continues to get handwriting recognition APIs.

Google’s ill-documented HttpEngine now supports a bi-directional stream
API, backed by a BidirectionalStream class.

The NetworkCapabilities API now explicitly supports Thread,
of particular interest to those working with Matter.

I had not realized this, but apparently getType() on a ContentProvider was
not defended by read permissions. Since that could leak information (the MIME type
for a particular Uri), they added getTypeAnonymous().
getType() will be protected by read permissions for providers that also implement

In DP1, Google stated that context-registered receivers might not receive broadcasts
in real time
They have now added some APIs for the reverse direction: a broadcast itself,
via BroadcastOptions, can have a deferral policy. The description of
sounds a lot like their DP1 announcement… except this would be opt-in by the
sender. 🤔

Broadcasts now have some form of “delivery group” semantics,
though the documentation on this is confusing.

And, there is now a dedicated exception
if you try to startForeground() a service that is not actually started.