Random Musings on the Android 6.0 SDK
Each time Google releases a new SDK platform, I rummage through
the API differences report,
and the high-level overviews (which are missing at the moment),
to see if there are things that warrant more attention from
developers, with an emphasis on mainstream features that any developer
might reasonably use.
Android 6.0 extends what we had in the M Developer Preview. A quick scan indicates that most of my interests and concerns from the original M Developer Preview SDK are still there, so I recommend that you start by reviewing my original four(!) posts:
- Random Musings on the M Developer Preview: The Good
- Random Musings on the M Developer Preview: the Bad
- Random Musings on the M Developer Preview: the Ugly (Part One)
- Random Musings on the M Developer Preview: the Ugly (Part Two)
Beyond those, here are some things that I noted in the Android 6.0 SDK that either were not in the M Developer Preview or I glossed over back in June:
A whole mass of permissions and permission groups were removed, not merely marked as deprecated. This should not affect your manifests, but if you were referring to the symbols in Java code, you’ll have to implement some workarounds. More importantly, any apps that use any of the removed permissions will need to determine what the right course of action is to be able to go forward with Android 6.0. The roster of removed permissions includes:
If you have been using
ACTION_INSTALL_PACKAGEto ask the installer to install an app, and your
targetSdkVersionis 22 or higher, you now must hold the
REQUEST_INSTALL_PACKAGEpermission. It is unclear if “22 or higher” is a typo or if this really was a requirement for Android 5.1 that perhaps was itself undocumented.
PendingIntentnow has a
FLAG_IMMUTABLEoption. This indicates that you do not want the extras in the underlying
Intentto be modified by anyone invoking this
PendingIntent. I can see this being very useful, from a security standpoint, in many
Several interesting new Settings screens are now accessible via
Settingsaction strings. One that will get a lot of attention is
ACTION_MANAGE_WRITE_SETTINGS, where users can indicate whether apps can write to system settings or not. If your app requests the
WRITE_SETTINGSpermission, you may appear on this list, and you can call
Settings.Systemto see if you were granted permission. There is also
ACTION_MANAGE_OVERLAY_PERMISSION, where users can control which apps can “draw over other apps” (chatheads?). It is unclear how apps get on this list — I would have expected it to be tied to the
SYSTEM_ALERT_WINDOWpermission (akin to the
WRITE_SETTINGSscenario above), though if that is the case, it is not documented that I can see. UPDATE: An eagle-eyed developer noticed
Settings, and so the
SYSTEM_ALERT_WINDOWflow is akin to the
Settingsactions pertain to “app standby” and the whitelist whereby users can grant your app the right to continue running normally even if you have not been used for a while.
ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGSleads to the Settings screen where users can generally toggle on and off who is on the whitelist, and
ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONSfor apps to beg to be put on the whitelist. Note, though, that to use
ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, you have to hold the
REQUEST_IGNORE_BATTERY_OPTIMIZATIONSpermission, though at present this is a
normalpermission and should be granted.
Also related to the above are some methods on
isDeviceIdleMode()indicates if the device has not been used in a while, indicating that we might drop into Doze mode soon, and apps in “app standby” status may also stop running. A broadcast (
ACTION_DEVICE_IDLE_MODE_CHANGED) will go out when this status changes.
isIgnoringBatteryOptimizations()will tell you if the user has indeed put you on the “app standby” whitelist.
The “App Assist” stuff that powers “Now on Tap” has a modest amount of documentation, stemming from the new
android.app.assistpackage, and the
BatteryManagernow defines broadcast action strings for
ACTION_DISCHARGING. No word on whether these can be registered for in the manifest (as opposed to
ACTION_BATTERY_CHANGED), though presumably they can, as that status should not flip too frequently. There is also a simplified
isCharging()method to determine if the battery is charging or not.
As part of the overhaul of the permission system, the concept of
signature|systempermissions are deprecated. Instead, we have a bunch of new
protectionLevelflags that I am sure that a lot of folks who root devices will be experimenting with soonish.
Pretty much the whole
Browserprovider has been removed. This, at least in theory, would allow you to access bookmarks and such from a browser. Other than the original AOSP Browser app, I am not aware of other browsers actually supporting this, and the fact that it is removed (not deprecated) is telling.
detectResourceMismatches(). It is designed to catch places where the resource system would do conversions for you that you could avoid. The cited example is having an resource that you retrieve via a call to
Resourcesobject. While this works, it would be more efficient to have an int resource.
detectResourceMismatches()will report these to you. I am rather surprised that the instrumentation for this does not swamp the performance savings from doing the conversion, but, hey, they didn’t ask me…
TextViewnow offers greater controls over the line-break strategy and hyphenation, via XML attributes (
android:hyphenationFrequency) and corresponding accessors. Line-break strategies are: simple, high-quality, balanced, where “high-quality” is the only one that cites using hyphenation. Hyphenation strategies are: none, less-frequent, and standard. The default strategy for
TextViewis high-quality, while the default strategy for
WebViewnow offers support for HTML5 “MessageEvent” interfaces, by means of classes like
WebMessageand methods like
Of interest to analytics folks is the new
ActivityOptions. This allows you to register a
PendingIntentthat, when invoked, will hand you a couple of extras containing information about how long the user used the app that you are launching.
There are now hooks for dealing with “captive portals”, those aggravating interstitial pages that you encounter when you have to request access to a network at a hotel, coffee shop, etc. For example,
ConnectivityManagerhas an activity action named
ACTION_CAPTIVE_PORTAL_SIGN_IN, designed for apps to help users sign in (saved credentials, perhaps?). There is a
CaptivePortalclass that comes along for the ride.
There are now hooks for apps to be able to request that users replace the dialer (presumably with their app), plus configure and switch to different phone accounts, as part of a beefed-up
TelecomManager. Plus, the
android.telecompackage got substantially expanded, with hooks to all sorts of new capabilities through the
TelecomManager. We have new classes regarding calls, conferences, gateways, phone accounts, and so forth.
We finally get a type-safe implementation of
MODE_MULTI_PROCESSwas deprecated. This was a mode flag used for opening
SharedPreferencesto allow multiple proceses to read and write those
SharedPreferencessimultaneously. Mostly, this was to support having components run in separate processes via the
SharedPreferencesbetween processes was always described as unreliable, and they are making that more official now by getting rid of support for it. As the documentation suggests, please use a real IPC API (broadcasts,
ContentProvider, etc.) for communication between multiple processes that represent your app. Or, stick to a single process.
Build.VERSION_CODESvalue is still
M. It is unclear if this is a mistake (and
MARSHMALLOWwill show up later) or whether the new convention is to stick with the single-letter values. It also contains no significant JavaDocs, which is rather surprising considering that Android 6.0 is a major version update.