Random Musings on Q Beta 4
Each time Google releases a new
developer preview beta, I putter around
the API differences report
the high-level overviews,
and even the release blog post,
to see if there are things that developers should pay more attention to.
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 are now up to Beta 4, so this extends upon my notes for Beta 1, Beta 2, and Beta 3.
Q Beta 4 is supposed to have the final APIs. However, I was surprised as to how much is different in Q Beta 4.
Hey, Can We Call It API Level 29 Now?
Yes, we can. We no longer have to dance around the API level.
has the proper value instead of the
10000 placeholder. And you are able to
publish apps with
targetSdkVersion set to
29 if you so choose… though you
may or may not be ready for that just yet.
So, What’s Up with Scoped Storage?
In a nutshell, it changed again, based on the description in the docs.
The sandboxes are gone. Instead, there is one unified external storage location that all apps and the user sees. However, apps only see their own files in external storage, in general. So, instead of scoped storage being sandboxed, it is filtered instead.
From the user’s standpoint, this should be simpler. Now files that apps write to external storage will be where they had been previously. This is really important for legacy apps that are not being regularly updated and which might never adapt to the Storage Access Framework. Yet, at the same time, apps should still unable to manipulate other apps’ files through the filesystem, meaning that users still get enhanced security.
Also, apps are still able to opt out of the filtered view, at least until next
year sometime, when
targetSdkVersion 29 becomes required for the Play Store
and select other app distribution channels.
My biggest fear right now is that there have been so many changes over the past three months that we are at risk of more bugs than we might otherwise have had.
are now deprecated, to further steer developers towards using the Storage Access
I will be “kicking the tires” on this stuff today and will write up more about the current state of scoped storage tomorrow.
What Else Got Deprecated or Removed?
The biggest surprise — and a pleasant one — is that
is deprecated. Moreover, it is planned to be dropped entirely in some future
release. For device manufacturers,
android:sharedUserId was a handy shortcut
for data sharing, but even there it really was not a particularly good practice.
For ordinary app developers,
android:sharedUserId was a
footgun, one that I have been advising
against people using since the very beginning. Having an app suite is awesome,
but please use IPC for data sharing, not some sort of shared file that may or may
not be managed properly for simultaneous multi-process access.
DownloadManager deprecated some things, as a side effect of scoped storage:
Items listed in the new
MediaStore.Downloads collection will be what appears
in the Downloads UI now. So, if you have content that was not downloaded to the
Downloads/ directory by
DownloadManager, and you want it to appear in the Downloads
UI, you need to write it to a
Uri supplied by
MediaStore.Downloads, I guess.
A bunch of fields from
MediaStore.MediaColumns were removed, including
DATE_TAKEN. If your app has been querying on those columns, they
may no longer be available to you.
MediaPlayer2 and related classes vanished without a trace.
They Didn’t Add Anything New, Did They?
Well, yes, they did, a lot more than I would expect at this late stage. Here are a few things of note:
DirectActionis an opaque identifier of something that somebody can do with or in the activity. The idea is that an activity can supply the available actions in
onGetDirectActions(), and a
VoiceInteractorcan let the user act upon one. The chosen action then gets delivered to
onPerformDirectAction(), for the activity to go do something. Unfortunately, there isn’t a lot to go on in terms of how all of this is supposed to work. Hopefully, more documentation is forthcoming.
setIdentifier(). The identifier “is an arbitrary identity of the
Intentto distinguish it from other
Intents”. My assumption is that this does not affect
Intentrouting and is basically a specific “extra” bit of data that gets passed along. It is unclear what the value of this is over, well, extras.
CATEGORY_APP_FILESto identify file managers.
There are four new
DisplayMetricsscreen densities: 140, 180, 200, 220. Those are the first new low-end densities we have had in years, and it is unclear what hardware would have such screens. It’s possible this is tied to desktop mode, if those are meant to be used for certain external displays. Regardless, most developers will not need to worry about these, as Android will scale
hdpidrawables for you. But, if you have other code that cares about these
DisplayMetrics, you have four more to deal with.
android:hasFragileUserDatais a new manifest setting (I’m guessing on
truethe user is prompted to keep the app’s data on uninstall”. This seems ripe for abuse, but I can see where it might be useful for some apps.
What Was Renamed?
One common thing late in the beta sequence is to have classes and methods be renamed, as somebody lost a fight in a code review or something. Of particular note:
They Must Be Done With Changes Now, Right?
There is still a reference to
RecoverableSecurityException being enabled in a future beta.
Certain types of I/O might throw that exception,
which contains a
RemoteAction that you can use to bring up some UI to help
recover from that exception. In particular, if you do not have rights to modify
some media, you might get a
RecoverableSecurityException, where the
would bring up UI to allow the user to grant you write access. It is unclear if
this might show up in a future Q beta, whether it already is in Beta 4 (without
the docs being changed), or what.
OK, So Where Do We Go From Here?
In theory, there should be few changes from here on out in terms of the API. There may yet be bug fixes, which is good, as a bunch of the bugs that I filed are still reproducible on Q Beta 4. But if you have been holding off testing your app with Android Q, waiting for things to stabilize, you should not wait any longer. I expect Android Q to ship in final form to end users in 2-4 months, and you will want to make sure that your app will survive that upgrade.
As for me, I will update Elements of Android Q shortly to reflect some of these changes and explore more dusty corners of this release, such as desktop mode.