Third post with Google I/O recap. Time for Android developer perspective.

I’m not even going to try listing all changes. If you specialize in some field, you probably already know the details that are the most interesting to you. This is high level view for you average, or rather median, programmer. But if you think there is something missing, don’t hesitate to let me know! I’m still catching up talks from Google I/O.

In my opinion every programmer should know and understand user perspective so if haven’t already, go read my previous post about Android Q from user perspective. Don’t worry, I try to be on point.

Again, when it makes sense I link section to source, so you can check it out on your own.

New gesture control

This is the biggest change: controlling smartphone with finger gestures instead of buttons at the bottom.

You can see how it works below:

And this is definitely one of the most important talks in the whole Google I/O. Watch it!

At first I thought - no big deal, why do I care how user is navigating their phone? The problem is, every UI needs to take new navigation into account.

  • If you have swipes anywhere - do they start near the edge? Can they be mistaken with back gesture?
  • You need to make sure that no clickable elements are near the edge.
  • Your bottom navigation panel must have proper bottom padding.
  • What? You have menu slided from side ? Let’s hope Google does good job adjusting how it works or if you have custom solution - let’s hope you do a good job!

There is a lot to consider, but maybe you are lucky and you have carefully designed UI that has clickable elements far from edges. Fingers crossed!

BTW Immersive mode (full screen) is the new default, so be prepared.

On the positive node, other changes are only better.

Dark theme

Dark theme

Yeah, dark theme is coming and it has been known for a while. It might mean a lot of work, depending on your app’s UI. If it’s mostly dark, you are lucky.

First thing that you need to do is to inherit main app theme from Theme.AppCompat.DayNight or Theme.MaterialComponents.DayNight. Then you can create values for colors, that depends on current mode. By default you can use colors for non-dark theme and values that will be overriden in dark theme should go to directory res/values-night.

Alternatively, you can dynamically change theme colors base on system settings. To get it you should (I didn’t find “official” way) retrieve value from Configuration class:

Configuration config = getResources().getConfiguration();
int currentNightMode = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK

Now currentNightMode can be one of: UI_MODE_NIGHT_NO, UI_MODE_NIGHT_YES or UI_MODE_NIGHT_UNDEFINED

Alternatively, for quick-and-dirty fix, take a look at “Force dark”. Setting it for app’s theme will force dark theme, which means graphic engine will automatically try flipping colors and making everything dark and readable. Sounds scary, because it is. But for temporary fix this might be good enough.

Introducing dark theme might be painful, but you really don’t want your app to be painful for users’ eyes.

Bubbles

Bubbles

Messenger bubbles - one of the few thing that Facebook did well on Android. Bubbles were great success and found ways in many different applications. They are liked and are regarded as good mechanism. The problem is, they require SYSTEM_ALERT_WINDOW permission and that permission is a lot. It uses excessive memory and allows to capture and/or intercept pretty much all user interaction with phone. Sounds scary, right? But bubbles!

So now Google wants to remove SYSTEM_ALERT_WINDOW, but doesn’t want to take bubbles away. And that’s how new Bubbles API came to be.

It is tied to Notifications API, but it’s more than that - it should also allow to multitask more easily. Interestingly, Google says that valid use case is showing bubble when your app is in foreground. But still it should be only used when user explicitly asked for it or notification is really important and ongoing - like chat.

From technical perspective, bubble contains activity and because of bubble intricacies it should be lightweight activity. Important thing to consider is that user can disable bubbles for your app, but it’s not that surprising. In that case they will be shown as regular notifications.

Read more here.

Support for foldables

Smart action

Oh boy, that’s complicated. There is a high chance your app is ready to go, but if is doing something unusual or complicated then you need to check a few things. Let me just cite Android Developers:

To get your app ready for Foldables, you should test how your app reacts to:

  • Configuration changes
  • Multi-window and multi-resume
  • Resizing and new screen ratios

Configuration changes should be handled well since always, so that should not be a problem. Multi-window and resizing - if you care about latest devices then you are probably covered as well. Multi-resume is new and screen ratios can change in the runtime (app might be moved to another display). Oh, and these screen ratios will be weirder than ever, because with foldables rules of ergonomy don’t apply the same way as for phones.

So what is multi-resume? It’s not as bad as it sounds. Previously, only one app could be in “resumed” state, even there were a few apps visible. It was big change, because you no longer want to pause everything when app is in “paused” state - it might be still visible after all. Now it changes and in multi-windows mode, all activities will be in “resumed” state. Which makes much more sense to me.

And just in case lifecycle is not complicated enough (sadly, it will always be) there is new lifecycle callback onTopResumedActivityChanged.

External Storage

As usual - if you don’t do anything unusual, you should be good. Otherwise… now storage for app is sandboxed. Which means, that app can read write only to its default directories, i.e. Context.getDataDir(), Context.getExternalFilesDir() etc.

If you want to save media files that can be access you can save them using MediaStore. And you don’t need any permission for that. What you need permission for is reading media files that were created by other apps. Then you need READ_EXTERNAL_STORAGE. BUT you can’t simply read metadata that can uncover photo location, you need another permission for that - ACCESS_MEDIA_LOCATION.

The default way to get access to non-media files from other apps is via system file picker. And if you are doing file manager kind of app, you need to ask user for access to main phone storage.

See more details in this talk and read more here

Better permissions

Location controls

Remember good old times when user either gives access to location or doesn’t? Now user has to explicitly allow app to have access to your location when it is in background.

There is new permission: ACCESS_BACKGROUND_LOCATION. Of course it determines if your app can access location when it is not visible, so now being granted location permission is not the end of story. Important thing is: you should assume you might not access location when in background.

If you don’t target Android Q, ACCESS_BACKGROUND_LOCATION is added to your app automatically with other location permissions.

Read more here.

Camera X

I haven’t done complex stuff with Camera API but I can imagine how hard it might be to support any camera feature. There are so many different devices with so many different camera with so many different lenses with so many different capabilities… it’s not easy.

Thus I think this might be lifesaver for some people - Camera X, which is adapter for all different camera features for all different manufacturers. Of course I don’t believe that even Google can cover all cases, but probably they will do better job than your average developer. That’s nice.

Fingerprinting device gets harder

In case you don’t know, fingerprinting means being able to recognize device with repetitive usage and being able to pinpoint which device/user did what. So fingerprint might mean associating app instance with device IMEI. Now when you see that IMEI you know you what that user did previously and you can build its profile.

Fingerprinting might be used for good or for bad and that means it will be used mainly for bad things. Google is limiting ability to fingerprint user. It still can be done easily, but you need permission READ_PRIVILEGED_PHONE_STATE for that.

App can’t switch Wi-Fi state

Bad thing - app can’t switch Wi-Fi state. Good thing - now you can open sliding panel that will do this and user doesn’t have to leave app to turn on Wi-Fi. This new way of accessing settings is called…

Settings panel

Settings panel

Settings panel is great. It lets app show panel sliding from the bottom, that contains chosen system settings. You don’t need to ask user to go to settings and then pray that they will come back correctly. There are panels for: all internet connections, only Wi-Fi connection, NFC, volume. So most bases are covered. I think this really improves user experience.

android.preference is deprecated

Whole android.preference package is deprecated. No, it’s not SharedPreferences, it has to do with preferences screen in you app. It contains such interfaces/classes like PreferenceFragment, PreferenceActivity, CheckBoxPreference, OnPreferenceChangeListener. Now, you should use androidx.preference instead.

Better share sheet

First of all, there is now preview for shared data - it can even include image.

Share sheet

Secondly, you should use new Sharing Shortcuts API - it has priority over old API but more importantly, it means apps are registering direct share targets not every time share sheet is created. Which means much better performance of share sheet which is known for poor performance. Profit!

I doubt this concerns most of the developers but in case you are interested - read more here.

Watch for phone overheating

This is just interesting feature and will be used mostly in games. You can observe “thermal status” of phone and if it goes in wrong direction, act accordingly - e.g. decrease graphic details.

Smart reply

Smart reply suggests reply content based on message content. You can think about it as one-click reply. In Android Q it’s available to all apps, so you don’t need to write your own AI.

Smart action

Next to suggested replies you might also see suggested action. E.g. if someone sends you an address, you might want to open it directly in maps.

Warning about targeting pre-Marshmallow Android

This is not totally new, but very important. If you app targets Android SDK lower than 23 (6.0 Marshmallow) user will be shown warning that app might be incompatible. That’s terrible user experience and no high-quality app would allow this to happen.

Kotlin is the way to go

Kotlin is now not only officially supported by Google, but also officially preferred. If you don’t use Kotlin, it’s really high time to switch.

Jetpack Compose

Quick mention - Jetpack Compose might change a lot. I don’t want to write about all changes in Jetpack, but Compose is totally new way of creating layouts. It is similar to Flutter, where you can create layouts declariatively in your code. I’m really excited about that - I was never a big fan of XMLs. At the same time it’s really big challenge to do it right, generate preview correctly and so on. It’s definitely something worth checking out.

The end

As always, there is A LOT more and even this post turned out larger than I expected. But above are the things that you should be at least aware of when dealing with new Android Q - and you will deal with it sooner or later. Some of them can be delayed simply by not targeting Android Q (e.g. scoped storage) but some - like dark theme - it’s better to start working on right away.

If you really want the whole (and big and long) picture - you can read all changes in new Android on Android Developers.

This post was mostly about new and/or changing API and features in Android Q but there is also quite a lot about improving developer productivity. So be sure to watch other talks - Android Jetpack is getting richer!

Good luck in updating your app!