Random Musings on the 7.1 Developer Preview 1
Each time Google releases a new developer preview, I try to
talk about the changes that may not be obvious when reading the
That’s particularly important now, as we literally have no time to
react to Android 7.1. While the development community only has
this Developer Preview 1, 7.1 devices are shipping, in the form
of the new Pixel phones. Every Android OS update has had bugs reported
by the community, and 7.1 is unlikely to be an exception.
So, let’s see what’s in store.
Round Icon Oddities
For what feels like little end-user value, I worry that the round icons
are going to cause above-average angst, due to the way that they were
The right answer, IMHO, would be that:
the round icons would be exposed via
PackageManager, as a distinct
icon from the regular app icons, and that
the decision of whether to use the regular or round icons would be
made by the home screen implementation, and potentially the user (via
some setting in the home screen)
Neither of those appear to be true. There is nothing in
and related classes that exposes the round icon separately. Worse,
the decision of whether to use regular or round icons is not made
by the home screen, or the user, but rather by the device manufacturer
(or custom ROM developer):
When a launcher requests an app icon, the framework returns either
android:roundIcon, depending on the device build configuration.
Note that the documentation there has at least one bug: this is not
limited to launchers. Any request for the app icon will return either
regular or round depending on a hardware setting.
This means that, out of the box, home screens cannot specifically work
with regular or round icons, but simply “get what they get” from the
platform. With luck, the developer community will settle on some standard
<meta-data> elements, where developers can specifically point out
their regular and round icons, so home screens can go with one or the
other based upon decisions made by the home screen developer and user.
When you add your own round icon, be sure not only to test your home
screen look, but anywhere else that your app might be using its own
icon. In particular, rather than just referencing a resource directly,
you may want to use
getApplicationInfo().loadIcon(), to ensure
that you get the same icon that the rest of the system uses.
Also, when you start trying to set up round icons,
Android Studio 2.2.2 will yell at you.
Just pat your IDE on the head and move along.
Limits on Revising targetSdkVersion
The release notes indicate:
Once you publish an app with
targetSdkVersion set to 23 or higher, you can’t later publish a version of the app with a higher
versionCode that targets 22 or lower. This restriction applies in alpha and beta channels as well as production channel.
I am not terribly shocked that they are imposing this constraint. It
does suck from the standpoint of making tactical fixes for addressing
bugs, as it removes one possible workaround from the toolbox.
Effects on Existing Bugs
Android 7.0 has an as-yet-unfixed bug where
services can get foreground priority without a visible
This appears to be fixed.
Also, at least one of
Dan Lew’s drag-and-drop bugs
was somewhat addressed,
reverting back to the original behavior for apps with a
targetSdkVersion below 24.
Since Android 7.0 still has the regression, though, this
7.1 change may make things worse.
Note that notification sounds are still messed up.
The app shortcuts
feature is supported by both the Google Now Launcher (available on the
Play Store) and the Pixel Launcher. Hence, more people will get access
to this capability more quickly. Static shortcuts (using the
<meta-data> element) in theory could work on pre-7.1
devices, since there is no strict API change. That does not seem to be
the case at the moment. Similarly, third-party home screens could
support static app shortcuts prior to Android 7.1, so this may be
something you want to opt into sooner, as there is potential for
more “bang for the buck”.
Note that when you create app shortcuts, you must provide an
android:action in the
<intent> element inside the
This is required even if the action string is meaningless
android:action="why.is.this.required") and will be ignored.
If you leave off this attribute, your app shortcut will not work.
There are four new
KeyEvent values, of the form
KEYCODE_SYSTEM_NAVIGATION_DOWN (plus equivalents for the other
three cardinal directions). It is unclear exactly what “system
navigation” means here. The description is “Consumed by the system
for navigation down”, which begs the question of when we might
KeyEvent for something that was already consumed.
—Oct 20, 2016
Freeform Multi-Window, Like It or Not
Android 7.0 offers a freeform multi-window mode.
We do not have an official freeform test environment.
And, since Google has not yet published a
Compatibility Definition Document
for Android 7.0, it is unclear to what extent device manufacturers are
authorized to enable freeform multi-window mode.
However, you – and perhaps power users of your app – can play around
with freeform multi-window on Android 7.0 devices, with the help of
the Android SDK or the combination of a developer setting and
Developers can enable platform-level freeform multi-window support by
running the following
adb shell settings put global enable_freeform_support 1
(UPDATE 2016-10-12: many thanks to Mike Evans for pointing out the typo in an earlier edition of this post!)
(UPDATE 2016-10-19: also, you then need to reboot)
Note: this works without root. At that point, you will have the same
freeform mode that we could play with on N Developer Preview environments.
Pressing the RECENTS button brings up the overview screen, where the cards
will now have a button in their title bars to move that app into freeform
However, even non-developers can play around with this, courtesy of apps
like Braden Farmer’s Taskbar…
or the Freecar sample app
from my latest book update.
These apps rely on power users enabling developer mode (i.e., the Seven
Build Number Taps to Glory) and toggling on “Force activities to be resizable”.
Then, from the home screen or overview screen, a third-party app can launch
an activity into freeform mode. In the case of Taskbar, it does this via
an always-available floating bar; in the case of Freecar, it does this via
a notification shade tile.
Will many power users do this? No. I would expect it to be roughly on par
with the number of power users who force your app into multi-window mode, possibly even with multiple instances of your activities.
However, some might play with your app this way, particularly if your
app has a large user base. I would not be surprised if third-party home
screen app developers elect to integrate these sorts of features, either
in baseline functionality or in some sort of “experimental mode”.
How close is this freeform multi-window behavior to the “real thing”? I
have no clue. This freeform mode is very limited, and so it is difficult for me
to believe that Google really wants manufacturers employing it in this state.
But, since Google has released what we have without much guidance, we have
no good way to know right now.
But, since some users will start playing with it, like it or not, you
may need to consider spending a bit of time trying it yourself. You
may want to understand
how your app behaves and whether there is anything that you want to do
to help those power users use your app in freeform mode… and perhaps set
yourself up to handle freeform better when it is more widely available.
—Oct 11, 2016
The Busy Coder's Guide to Android Development Version 8.0 Released
Subscribers now have
access to the latest release of The Busy Coder’s Guide to Android Development,
known as Version 8.0, in all formats. Just log into
your Warescription page and download
away, or set up an account and subscribe!
This update is fairly substantial, as it:
Covers Android Studio 2.2, with updated instructions and screenshots
Updates the coverage of the classic containers:
Adds two chapters on
ConstraintLayout, though more material is planned
for sometime after
ConstraintLayout ships “for realz”
Revamps the tutorials, taking Android Studio 2.2 into account, updating
the dependencies, etc.
Adds new sections on the Layout Inspector, the APK Analyzer, the graphical
menu and preference XML resource editors, and the
merged manifest viewer, all new to Android Studio 2.2
Adds a section on Evernote’s
android-job library to
the chapter on
Updates the drag-and-drop chapter,
including material on an Android 7.0
nested-drop-target regression, plus using the local state to try to detect
Adds sections to the chapter on multi-window to address
how third-party apps can force your exported activity into multi-window
mode, plus more material on freeform multi-window (in its limited
Android 7.0 incarnation) and information about the “transient HOME”
state and its impact on activity lifecycle methods
Updates the chapter on memory leaks to cover LeakCanary 1.4
Adds material to the chapter on keyboard/mouse support
for dealing with focus modes
Revises a chapter on content providers to address
the latest edition of
Adds an example of using
LocationManager to the chapter on location tracking
Revises the chapter on event buses to deal with
Otto’s discontinued status
Adds a section in the chapter on advanced notifications
on Android 7.0’s
Updates the chapter on Internet access to cover
Moves the material on vector drawables to a dedicated chapter,
just after the chapter on the action bar
Also, the APK edition of the book has new appinars on event buses
and Android 7.0’s network security configuration.
There will be another book update before the end of the year, though
the exact timing will depend a lot on what the heck is going on with
the Android 7.1 that is supposed to be shipping in a couple of weeks.
I expect Version 8.1 of the book to come out either mid-November or
—Oct 10, 2016
In Split-Screen, Your Orientation Flips
Many of you have no doubt discovered this already, but for those who
have not: whether you get portrait or landscape resources is dependent
upon the aspect ratio of the window, not the device, on
Android 7.0. So, if the
device is in portrait, and your activity is being shown in normal mode,
you will have portrait resources. But, if the user then moves the device
into split-screen mode, putting your activity into one pane, you will
undergo a configuration change, and now use landscape resources, even
though the device itself did not rotate. The same holds true for
the inverse case (device in landscape, with entry into split-screen
switching your activity from landscape to portrait resources).
This is not terribly shocking, though it was not something that I had
considered when Android 7.0’s multi-window was announced. I only infrequently
-land resources (and never
-port), preferring instead to
tie orientation and screen size together (e.g.,
-w640dp). So, I was
focusing on the smaller window size, not so much its orientation.
However, this is another example of where we need to take care to ensure
that the switch from normal to split-screen mode (or back again) is
a smooth one. Having a radically different UI in one orientation versus
the other means that the user will see a radically different UI when
she switches between normal and split-screen mode, which may not be a good
idea. Worse, if and when the mythical freeform multi-window mode becomes
available, the user may see a radical UI change just by a small window
resize operation, one that happens to move the window between
portrait and landscape aspect ratios.
—Oct 06, 2016
In Split-Screen, Not All HOMEs Are Created Equal
Multi-window modes, such as split-screen on mobile devices, are shaping
up to be a never-ending source of unfortunate behavior in edge cases.
This Stack Overflow question
is yet another edge case, where your activity’s behavior when the user
presses HOME differs, depending on whether the device is in normal mode,
in split-screen mode with your activity in the left/top pane, or in split-screen
mode with your activity in the right/bottom pane.
We are used to the notion that when the user presses HOME, we are called
onStop(). In fact,
onStop() is even more important than before
with Android 7.0, as our activities will be paused (but not stopped)
a lot more with multi-window. So, whereas we might have used
onPause() for setting up and tearing down foreground work, we might
now switch to
onStop() is not always called when the user presses HOME.
If the device is in normal, non-split-screen mode, and the user presses
HOME, your foreground activity moves to the background, and
If the device is in split-screen mode, and your activity is in the bottom
or right pane (depending on device orientation), and the user presses HOME,
your activity is stopped, so you get an
onStop() call. Visually, the
activity animates off-screen fully, and if the user presses the RECENTS
button, the pane you had been occupying is replaced with the recent-tasks
So far, so good.
But what the Stack Overflow question –
and July’s bug report –
point out is that if your activity is in the top or left pane of split-screen,
and the user presses HOME, your activity is not stopped. Arguably, this
is because a thin slice of the activity is still visible along that edge,
as a hint to the user that they are not really at their home screen.
Instead, they are in a state that I will call the “transient home” state.
Since your activity is not called with
onStop(), your code keeps chugging
along. The quintessential example, cited in the Stack Overflow question,
is the video player: the video player keeps playing.
Google’s assertion is that this “transient home” state should indeed
we see the transition to the home screen as a very quick action is being performed to launch another app and the device will only be in that state for a very short amount of time
(from this issue comment)
I know, it feels weird, but it is supposed to be a mode that users are in only briefly
(from Ian Lake’s comment on his own answer to the Stack Overflow question)
The problem with this theory is that users are not automatons. They will
do whatever they like. Some percentage of users will be oblivious to the
differences between HOME-in-split-screen and HOME-otherwise. In particular,
they will press HOME, and then not continue on to run some other app,
but instead just leave their device.
For the video players, games, and other apps that use
setKeepScreenOn() to hold a full wakelock while they are visible…
well, that wakelock stays in force, and the device continues draining the
This is bad.
For interactive activities that use full wakelocks, like games, you can kinda
work around this. Rather than rely upon
onStop() exclusively, also
“stop” the activity if the user has not tapped the screen after some number
However, this approach does not work for a video player or
other activities that are not interactive. You will probably need to
release the wakelock in
onPause(), and then hope the device screen turns
off of its own accord, triggering more lifecycle methods in your activity.
I filed a feature request
to get notified either about entering/leaving this “transient home”
state or to be notified that the user seems to have abandoned their
device in that state, so we can take appropriate steps in our activity.
—Sep 28, 2016