The CommonsBlog

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 high-level descriptions.

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 implemented.

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 PackageManager 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:icon or 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 Notification. 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.

Other Curiosities

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 <shortcut>. This is required even if the action string is meaningless (e.g., android:action="") 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 get a 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 third-party apps.

Developers can enable platform-level freeform multi-window support by running the following adb command:

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 mode.

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: LinearLayout, RelativeLayout, and TableLayout

  • 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 JobScheduler

  • 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 cross-app drag-and-drop

  • 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 FileProvider

  • 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 setSound() bug

  • Updates the chapter on Internet access to cover Retrofit 2.x

  • 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 early December.

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 use -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 with 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 onResume() and onPause() for setting up and tearing down foreground work, we might now switch to onStart() and onStop().

However, 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 onStop() is called.

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 list.

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 be transient:

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 android:keepScreenOn or setKeepScreenOn() to hold a full wakelock while they are visible… well, that wakelock stays in force, and the device continues draining the battery.

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 of minutes.

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

Older Posts