Random Musings on the P Developer Preview 2
Whenever Google publishes a new developer preview, I wander through through the API differences report and the high-level overviews, to see if there are things that require more attention from developers, with an emphasis on mainstream features that any developer might reasonably use. I also tend to emphasize things that may not get quite as much attention, because they are buried in the JavaDocs.
On the whole, Android P Developer Preview 2 (P DP2) did not make that many changes, certainly none that are “big ticket” user-facing items. As with P DP1, I’m at a loss to tell my mother what she’ll be getting if she elects to replace her Nexus 5X with something newer that will get Android P.
In my P DP1 random musings, I suggested that perhaps the reason for the lack of changes was “a focus on cleaning things up in preparation for future versions of Android”. Certainly we are seeing elements of that come out of Google I|O, specifically the AndroidX repackaging of Google’s libraries and the new Jetpack initiative. I’ll blog more about those tomorrow, as neither are really tied to Android P.
However, just because there were no big changes does not mean that there were no changes. Here are some things that I found that may be of interest to you. These are incremental changes in P DP2 — see my P DP1 random musings for other Android P changes.
What Works Now, That Didn’t Before
One of the security benefits that was touted for Android P was that cleartext
Internet traffic — http
instead of https
, for example — would
be banned by default. However, in my tests, this did not work, either for
WebView
or for
HttpURLConnection
. The
underlying bug has now been fixed. You will now start seeing exceptions due
to cleartext traffic that you had not seen in P DP1, let alone previous versions
of Android. Ideally, you switch to encrypted connections. If you need to support
http
URLs, though, you will need to set up
network security configuration
and set up cleartextTrafficPermitted="true"
for the domain(s) for which you
still need http
support.
Android P was documented to require a FOREGROUND_SERVICE
permission for you
to use startForeground()
. This is a normal
permission, so you merely need
the <uses-permission>
element, not runtime permission support. However, in P
DP 1, this did not work. Now
it does, so you will need to add this permission.
I wrote about AppComponentFactory
in
my P DP1 random musings.
It’s a way for you to override the default reflection-based way that the framework
creates instances of your activities, services, manifest-registered receivers,
and providers. However, it was completely broken on P DP1. But,
it works now, at least for
activities — I have not yet tried other components.
What’s New in the War on Background Processing
I thought that Google had declared victory already. Apparently, they are adopting a “take no prisoners” approach to the War on Background Processing, introducing a bunch of changes in P DP2.
The worst is the “app standby buckets”. In Android 6.0-8.1, your app would move into an “app standby” category if the user had not visited the app’s UI recently, and while in “app standby”, it was pretty much as if Doze mode was on all the time for your app. Now, there are four major “buckets”: active, working set, frequent, and rare, with progressively stronger restrictions placed on app operation. In particular:
-
FCM high-priority messages — formerly Google’s recommended approach for getting your app to react to external data changes — will be capped in the “frequent” and “rare” buckets
-
Device manufacturers can decide for themselves when and how to categorize apps into these buckets
The user can also elect to manually restrict background operations for your app. If the user does, basically nothing works: no jobs, no alarms, no network. There are no “idle maintenance windows” or anything of the sort. The only thing that works when you are restricted this way are FCM high-priority messages, and app standby means that they might not work either. The user can enable background restrictions on their own by visiting Settings > Apps > (your app) > Advanced > Battery > Background Restriction. However, Android P is documented to prompt the user about misbehaving apps:
-
Those that use partial wakelocks for more than an hour, and
-
Those with a
targetSdkVersion
of 26 or lower that have “excessive background services” (whatever that means).
There is a new isBackgroundRestricted()
method on ActivityManager
.
Based on the documentation, it appears that this will return true
if the
user goes
and elects to restrict your background operation manually.
There is a table of what the effects are for different types of scenarios, such as the four app standby buckets.
The power change documentation also has:
Android P makes a number of improvements to battery saver mode. The device manufacturer determines the precise restrictions imposed.
IMHO, Google has a bizarre definition of “improvements”, if “random behavior based on device manufacturer whim” is an “improvement”.
As I have been recommending for the past few years, do not write apps that need to have reliable background work.
What Works as Before, Strangely
If your app’s targetSdkVersion
is 16 or lower, the user gets a warning dialog
on the first run of the app, indicating that the app is really old. This may
be a prelude to an outright ban on running such apps.
Frankly, if it will be a ban, it would be nice if Google would clarify that point, and adjust the preview’s dialog to reflect that fact. If, on the other hand, the plan is for this dialog to be the only effect (at least for Android P), that too would be good to know.
What Changed from Before, Strangely
In P DP1, FingerprintManager
was more-or-less deprecated and replaced with
FingerprintDialog
. In P DP2, FingerprintDialog
is gone, replaced with
BiometricPrompt
. The docs indicate that BiometricPrompt
will support a
range of biometric forms of authentication, including face recognition and
iris scanning. I sincerely hope that it largely stops there, as “swab the
inside of your cheek with your phone so we can collect a DNA sample”
will be challenging for users of phablets. Also, ew.
P DP1 added a Person
class for use with the improved MessagingStyle
form of Notification
. P DP2 also has Person
, but Person
got upgraded out
of the Notification
classes and now is android.app.Person
.
After 10 years, Google finally admitted that onCreateThumbnail()
in Activity
never really worked, and so it is now deprecated.
If you experimented with the “key fallback” options in P DP1, note that those
View
methods are now addOnUnhandledKeyEventListener()
and
removeOnUnhandledKeyEventListener()
.
If you experimented with the “tracing” stuff added to WebView
in P DP1, you
realized that little of it would even compile. That’s OK, as it is
significantly changed
now in P DP2. I have not had a chance to try any of it to see if it works.
What Else Caught My Eye
ImageDecoder
has been slightly improved, in that it now supports assets as
well as files and content. However, Google has indicated that it will not
support streams.
BatteryManager
now offers a computeChargeTimeRemaining()
method, returning
the estimated number of milliseconds before the device runs out of power.
You might use this for your own in-app warnings regarding power levels,
if your app consumes a lot of power (e.g., video player).
Settings
now has ACTION_DATA_USAGE_SETTINGS
, to lead the user to the data
usage screen in the Settings app, where available.
UiAutomation
now has grantRuntimePermission()
and revokeRuntimePermission()
,
for improved testing in the world of runtime permissions.