What’s New in Android 10 and the Impact on Zebra Developers

This document details the developer impact of moving to Zebra devices running Android 10 (API level 29), and is a follow-up to my previous posts about what’s new in Android Pie, Oreo, Nougat and Marshmallow.  If you are moving from an earlier version of Android directly to 10, I recommend you read the documents in sequence since all the earlier information is pertinent to subsequent releases.

Audience for This Document

Zebra’s newly released TC21/26, TC52x/TC57x and MC3300x all ship with Android 10 as their base OS and many existing Zebra devices will also receive the upgrade to Android 10 in due course.  Any developers targeting deployments featuring at least one Android 10 device or devices that will be updated to 10 should be aware of the changes detailed here.

Overview

Android 10 introduces many new features, changes and enhancements that developers should be aware of before transitioning their applications to this new OS. Google emphasises a continued focus on users in 10 giving them more control over application permissions as well as their own privacy.

Google has published an overview and highlights of the Android 10 changes on its developer portal and has broken down the changes as follows:

Google also has published information about changes to Android enterprise features in 10 but those are applicable only to EMM developers.

This document does not replace recommendations from Google; it is designed to supplement those recommendations for enterprise use cases.

Scoped Storage

In Android versions prior to 10, applications had unrestricted access to the device filesystem so long as they were granted the appropriate storage permissions by the user. Android 10 introduces scoped storage as a default. This means that applications are given access only to an app-specific directory on external storage. Scoped storage was designed to provide greater data isolation for applications, but means that it is not possible to share files via external storage, with some limited exceptions.

Scoped storage was unquestionably the most controversial feature when the Android 10 beta was first announced, and pushback from the developer community resulted in a less aggressive rollout of the feature when it came to the final release.

As detailed in the Google docs for Scoped Storage compatibility, Your application can opt-out of scoped storage by either:

  • Targeting Android 9 (API level 28) or lower.
  • Specifying requestLegacyExternalStorage=”true” in your manifest:
<manifest ... >
  <!-- This attribute is "false" by default on apps targeting
       Android 10 or higher. -->
    <application android:requestLegacyExternalStorage="true" ... >
      ...
    </application>
</manifest>

It should be emphasised that the Google-provided ability to opt-out of scoped storage is temporary; Android 11 will mandate scoped storage.

From Android 11, developers are required to transition to the scoped storage model by using one of the storage / sharing mechanisms described in the Android data storage guide.  Specifically, an application’s sharing options are limited to the Media API for videos, audio and pictures, and the Storage Access Framework, which requires user interaction via a file picker, but handles all file types.

Many enterprise application developers are choosing to opt out of scoped storage in Android 10 and will address any changes required for Android 11, when more is known.  Zebra have not ruled out offering capabilities for Enterprise developers in Android 11 to make the transition to scoped storage easier but no details are yet available.

Enterprise implications of Scoped Storage

Any Enterprise use case that involves reading files from external storage will be affected by scoped storage, for example deploying configuration files or exporting log data for later analysis.

For more background and detail on the scoped storage feature, please refer to the session Google presented on scoped storage at their 2019 Android Dev Summit, which is available on YouTube.

User Control over Background Location

Android 10 allows a user to choose whether an application can be granted access to the device location at any time or just while that app is in the foreground.  Previously, if the user granted the location permission, the app would be given access to device location at any time.

A new permission, ACCESS_BACKGROUND_LOCATION, has been added to allow applications to request permission to receive location updates when in the background.  The behavior of your application when running on Android 10 will differ depending on the target SDK as follows:

  • Applications targeting API 28 (Pie) or lower will be given both foreground and background access so long as the user grants the appropriate location permission.
  • Applications targeting API 29 or higher need to specifically request the ACCESS_BACKGROUND_LOCATION permission in order to be able to access location in the background. The ability to access background location can be revoked by the user via the app’s permission settings.

More information is available from Google in their guide to receiving periodic location updates  as well as a really good short article from a third-party advocate that dives into the code.

Foreground Service Location Type

Foreground service types were introduced in Android 10 and can be assigned to foreground services.  Most notably, a foreground service that retrieves the device location needs to be of the ‘location’ type but while others are defined e.g. accessing the camera or microphone, only the location type is mandatory in Android 10.

Enterprise implications of Background Location Changes

Location is used in a high percentage of enterprise applications, so it is worth understanding the implications to enterprise apps:

  • Android Pie severely restricts the frequency with which location updates are received in the background and as a result, many developers might choose to adopt a foreground service to process frequent location changes.  Applications retrieving location via a foreground service in Android 10 should specify the foregroundServiceType as ‘location,’ as detailed in Google’s docs for Android location.
  • Many enterprise developers are being encouraged to update their target SDK to align with Play Store requirements and doing so means that the ACCESS_BACKGROUND_LOCATION permission must be added for targetSDK 29 or higher to access location in the background.
  • Typically, runtime permissions are automatically approved in enterprise apps, either because they were installed with an EMM or because they were installed with StageNow.  Automatically granted permissions will be the most permissive that the app has requested:
    • For example, if an application targeting SDK 29 requests ACCESS_BACKGROUND_LOCATION, it will be automatically granted permission to retrieve location in the background.
      • Failing to request ACCESS_BACKGROUND_LOCATION means that same app will be granted permission to access location only in the foreground.
    • If an application targeting SDK 28 requests a location permission, it will be granted access to the location in both the foreground and background.
  • Defensive programming is always recommended – check which permissions your app has been granted and do not make assumptions.

Permissions with legacy applications

Runtime permissions were first introduced in Android Marshmallow as a way of ensuring the user had knowledge of which permissions an application was using, when and why.  All developers were required to rethink their permission model and ensure the user granted the appropriate permissions to their app e.g. location, storage, call logs etc.  Prior to Marshmallow, permissions were automatically granted, and the user was only told about these permissions during download.

Android 10 addresses the very small percentage of apps continuing to circumvent runtime permissions by targeting an earlier SDK.  A dialog will be shown to the user when an application that targets Lollipop or earlier is first launched which will clearly show the permissions used by the app as well as offer the option to disable those permissions.

Screenshot from Google’s documentation on permissions

Enterprise implications of Permission Changes

The application installation model is often different for enterprise and so there are some unique considerations:

  • Although Google states that only a small minority of apps still target Lollipop or earlier, this may not be the case in the enterprise, where we see many customers still with large Lollipop deployments due to the longer lifecycle of Zebra devices.  As customers on Android L undergo hardware refreshes, it would not be uncommon for line-of-business applications written to target Lollipop to find themselves running on Android 10.
  • As referenced previously, applications installed via EMM can typically have their runtime permissions automatically granted.  The same is true for applications installed via StageNow, where runtime permissions will typically be granted automatically, and no dialog is presented to the user.    Applications targeting API level 22 or below (Lollipop) can no longer have their permissions silently and automatically granted when running on Android 10.  Developers are advised to rebuild their application with a higher API level to avoid having to manually grant permissions per the screenshot above.
  • Google continues to push for applications to target a recent API level in order to be allowed in the Play Store.  This will affect greater numbers of enterprise deployments as more organizations use the managed Play Store for app distribution.

Warnings for apps targeting older Android versions

Another warning presented to the user on Android 10 when launching an application with a targetSDK of Lollipop or earlier cannot be circumvented.  This warning just notifies the user that the app was built with an old target SDK

To ensure a seamless upgrade experience, Zebra recommends updating the target SDK.  Remember, updating the target SDK can change the application’s behaviour, and it is important to understand the implications of doing this by reading through this post series and Google’s detailed change documentation.

Changes to the Google Play Store

In 2018, Google began requiring that applications posted to the Play Store target a recent Android API level.  The target SDK level has been updated annually and it is expected that this trend will continue, with announcements made every February.  The latest requirements are detailed on the Android developer support page, but in summary:

  • Aug 3. 2020: New applications added to the Play Store must target API level 29 (Android 10) or higher.
  • Nov 2. 2020: Updates to existing applications must target API level 29 (Android 10) or higher.

These rules affect only the target SDK; you can still assign any minimum SDK level.  Google provides additional documentation for developers whose applications will run on devices with earlier versions of Android than the target SDK

Further, as we see greater adoption of managed Android and the managed Play Store as the distribution channel for enterprise, more customers will be impacted by this rule.

Though at the time of writing this restriction is not in place for applications solely delivered through the managed Play Store as private apps, there is no guarantee that this will continue to be the case in the future.

Restrictions on Non-SDK Interfaces

Restrictions on non-SDK interfaces (i.e. non-public APIs) have been around since Pie.  Google’s goal is to cut down on an application’s ability to call non-SDK methods via reflection or the JNI while providing a path forward for those apps such as by making additional APIs public.

Google offers dedicated documentation for this and I also wrote an article on how these restrictions affect Zebra developers. For a more thorough discussion, I recommend reading either of those two sources.  Android 10 has changed the nomenclature when compared to Pie and there is now only a single ‘greylist’ and the lists of allowed APIs have been updated.  For more detail on the list changes specifically for Android 10, I recommend Google’s documentation on the deltas.

Starting Activities from the Background

Activities cannot be started from another app when that app is running in the background, and apps are encouraged to use notifications instead.  This restriction is explained more in the Android docs. And while not plainly stated, this was primarily designed to address misbehaving consumer apps that would pop up full page advertisements from the background and disrupt user workflow.

Most enterprise apps are already using notifications to alert users from the background, so minimum impact is expected from this change. 

Although Zebra’s DataWedge utility runs in the background and can be configured to call startActivity() when a barcode is scanned, it is exempted from this restriction since DataWedge is a system app.  I have heard from a small number of customers who have implemented their own version of DataWedge to help run cross-platform, and such customers will need to avoid calling startActivity() from the background.

Access to Device Identifiers

With very limited exceptions for EMMs,  device identifiers such as the serial number, IMEI, device id, MEID, SIM serial number and subscriber ID are  unavailable to enterprise apps .  In Android 9 these identifiers were protected behind the READ_PHONE_STATE runtime permission. But in Android 10, they are protected by the READ_PRIVILEGED_PHONE_STATE permission, the latter being only granted to apps signed with the platform key and privileged system apps.  Applications built with an earlier target SDK also are unable to access these identifiers.

Zebra exposes the ability to access the device serial number and IMEI on Android devices running 10 and higher through the OEM Info content provider.  For more information on accessing device identifiers on Zebra devices see my sample app at https://github.com/darryncampbell/EMDK-DeviceIdentifiers-Sample

Google does also have a detailed guide for dealing with unique identifiers.  Applications are not able to use unique hardware identifiers and should instead use a self-generated GUID or an advertising ID, the former of which is more appropriate for most enterprise apps.

Settings Panels

Settings panels allow your application to show key system settings via a floating UI at the bottom of the screen.  The settings panel can be configured to show internet connectivity, NFC and audio volume, and are designed to allow the user to quickly resolve  issues such as Wi-Fi  disconnection without leaving the application to drill into the settings screen.

Screenshots generated using the following 3rd party app, which is not endorsed by Zebra and shown for information only: https://github.com/hitherejoe/Android-Q-Playground/tree/master

The ability to quickly surface pertinent settings is useful for consumer applications, but in most enterprise scenarios the user’s access to settings is blocked.  Zebra strongly recommends that your application NOT rely on settings panels when running in an enterprise environment.

The introduction of Settings panels coincided with the deprecation of the Android API to enable or disable Wi-Fi.  Developers (and administrators) who wish to control the Wi-Fi state on Zebra devices should use the MX Wi-Fi Enable / Disable feature.

Move to AndroidX

While  not related to Android 10 specifically, one big change for Android Developers has been the move toward AndroidX, which replaces the old support library and delivers the functionality of Android Jetpack.  Developers should start familiarizing themselves with Android JetPack and AndroidX; I have heard varying stories on how easy the migration is.  For some developers the migration process is no more difficult than running the wizard in Android Studio. Others are dependent on libraries that do not yet support AndoridX.

API level 29 has started to deprecate features (e.g. android.preference) and the recommendation is to use their AndroidX equivalents; if this trend continues it’s a good idea to update to the AndroidX libraries sooner rather than later.

Smart Replies

Android 10 guidance will suggest contextual actions in notifications, such as smart replies for messages or opening a map for an address in the notification. 

Screenshot from Google’s documentation on Smart Replies

Although enabled by default, I would personally recommend disabling this feature in enterprise apps using setAllowGeneratedReplies() and setAllowSystemGeneratedContextualActions():

  • I have seen some irrelevant or inappropriate suggested replies both online and when using my personal phone.
  • Google maps or other apps to handle the contextual actions might not be enabled.
  • Because on-device machine learning is used to generate the smart replies, the replies and their order can be unpredictable.

Dark Theme

Android now natively supports a dark theme that can be accessed from Settings à Display à Dark Theme.  Applications can choose to offer a dark theme through the standard theming mechanism. And while this feature offers improved power consumption regardless of display technology, there are no plans to offer a Zebra-proprietary mechanism to enable Dark Theme.

For more information on Google’s analysis of power consumption with light vs. dark theming, please refer to the Android Dev Summit 2018 video on ‘Optimizing battery power.’  Zebra also offers design resources on our dedicated design website that include suggested theming.

Removal of SHA-1

Android 10 devices are not able to connect to servers presenting a SHA-1 certificate, see the official Google docs for more information.

Neural Networks API 1.2

Android 10 has updated the Neural Networks API to version 1.2.  This API is not yet supported on the SD660 chipset and Qualcomm has instead opted to include its own SDK for the “Snapdragon Neural Processing Engine.

For more information about implementing machine learning on Zebra devices, you should see the following resources:

Google Play system updates

Project Mainline enables Google to update core OS components through Google Play in a similar manner to how applications are updated. This avoids the need to perform a full OTA update from the device manufacturer.  This is currently aimed solely at consumer devices.

Zebra customers should refer to our lifeguard program and OTA updates available from your EMM for more information on updating Zebra devices.

Android Beam

Android Beam has been deprecated.  This was an older feature for initiating data sharing across devices through Near Field Communications (NFC).  We did not see Android Beam used in the enterprise, but please be aware that this announcement this has no impact on NFC or our implementation of Secure NFC.

Conclusion

The primary changes that are likely to affect enterprise apps in Android 10 are access to device identifiers, scoped storage and access to location in the background.  Most apps use either external storage or location, and you should be aware of the impact of these changes regardless of your target SDK. 

The other changes around how Android 10 treats apps with a target SDK of API 21 or below could affect the provisioning experience for some customers, and Zebra recommends updating your target SDK if this affects you, most likely owing to a hardware refresh.

All the other changes covered in this document — changes to the Play Store requirements or restrictions on non-SDK interfaces—are likely to have a relatively minor impact for most customers, especially since many are evolutions of changes already introduced.