Posted by Oscar Rodriguez, Developer Advocate
When designing and developing an app or game, at some point you may ask yourself if you want to monetize it.
If you choose to do so by selling products via Google Play, you will most likely have a store screen that shows available items for sale, and use the Google Play Billing Library to display dialogs that allow your users to complete their purchase.
While there is a more detailed explanation in the documentation and in the Billing Library TrivialDrive samples, the general flow is as follows:
launchBillingFlow()
onPurchasesUpdated()
consumeAsync()
acknowledgePurchase()
If your app is still using the Google Play Billing AIDL API, it is also possible to perform the same task. Keep in mind that the AIDL API is now deprecated, so we strongly recommend you migrate to the Google Play Billing Library as soon as possible.
If you are using the AIDL API, the flow is very similar:
getBuyIntent()
getBuyIntentExtraParams()
startIntentSenderForResult()
Intent
onActivityResult()
getPurchases()
consumePurchase()
Nevertheless, just implementing the above mentioned flow is not enough to correctly handle all types of purchases. There are two main cases in which purchases will not be correctly handled by this flow.
The first case happens when the purchase flow is interrupted before it finishes. The app may have crashed, the user may have killed the app, or the user’s Internet connection may have been lost. In any case, it is possible for the app not to have delivered the item to the user even though Google Play has already processed the payment. In this case, the item is in limbo, because Google Play will not allow an item to be re-purchased until it is consumed, but the app or game won’t consume the item outside of the flow mentioned above.
The second case happens during alternative purchase flows, such as in-app promotions, the recently announced out-of-app subscription surfaces, promo codes for subscriptions, or other promotions in collaboration with Google. In these cases, a user gets an item directly on the Play Store app, while the target app or game may be paused, not running, or even not installed.
For these cases, the Google Play Billing Library and the Google Play Billing AIDL API offer a mechanism to detect purchases that are not acknowledged or consumed.
When using the Google Play Billing API, do the following:
onResume()
queryPurchases()
For the Google Play Billing AIDL API, do the following:
In either case, when you detect and process an unconsumed item in this manner, users will expect the app or game to communicate about it. We suggest that you display a dialog, message box, or notification that tells the user that they have successfully received their item.
Keep in mind that your app’s onResume() callback will be called when its process is started, as well as when it is brought to the foreground, regardless of which screen the app or game was in before it was paused. For example, a game with a home screen, a store screen, and a game screen might get its onResume() called from any of those screens. For an optimal user experience, we suggest you make it so your app or game handles unacknowledged or unconsumed items regardless of the screen you display when onResume() gets called. Thorough testing of this process in each screen is crucial to deliver a great user experience.
Finally, there is one more case your app must handle: when a user acquires an item from the Play Store app, and both the Play Store app and your app are visible at the same time with multi-window mode.
To support this scenario with the Google Play Billing Library, do the following:
PurchasesUpdatedListener
com.android.vending.billing.
PURCHASES_UPDATED
onPause()
Just as before, you should display a dialog, message box, or notification that tells the user that they have successfully received their item.
If you follow these steps, your app or game will be better prepared to robustly handle purchase flow interruptions and alternative purchase flows.
Starting August 1, 2019:
Posted by Sam Spencer, Technical Program Manager, Google Play
The Android Ice Cream Sandwich (ICS) platform is seven years old and the active device count has been below 1% for some time. Consequently, we are deprecating support for ICS in future releases of Google Play services. For devices running ICS, the Google Play Store will no longer update Play Services APK beyond version 14.7.99.
What does this mean as an Application developer:
The Google Play services SDK contains the interfaces to the functionality provided by the Google Play services APK, running as background services. The functionality required by the current, released SDK versions is already present on ICS devices with Google Play services and will continue to work without change.
With the SDK version changes earlier this year, each library can be independently released and may update its own minSdkVersion. Individual libraries are not required to change based on this deprecation. Newer SDK components may continue to support API levels 14 and 15 but many will update to require the higher API level. For applications that support API level 16 or greater, you will not need to make any changes to your build. For applications that support API levels 14 or 15, you may continue to build and publish your app to devices running ICS, but you will encounter build errors when updating to newer SDK versions. The error will look like this:
Error:Execution failed for task ':app:processDebugManifest'. > Manifest merger failed : uses-sdk:minSdkVersion 14 cannot be smaller than version 16 declared in library [com.google.android.gms:play-services-FOO:16.X.YY] Suggestion: use tools:overrideLibrary="com.google.android.gms:play_services" to force usage
Unfortunately, the stated suggestion will not help you successfully run your app on older devices. In order to use the newer SDK, you will need to use one of the following options:
1. Target API level 16 as the minimum supported API level.
This is the recommended course of action. To discontinue support for API levels that will no longer receive Google Play services updates, simply increase the minSdkVersion value in your app's build.gradle to at least 16. If you update your app in this way and publish it to the Play Store, users of devices with less than that level of support will not be able to see or download the update. However, they will still be able to download and use the most recently published version of the app that does target their device.
A very small percentage of all Android devices are using API levels less than 16. You can read more about the current distribution of Android devices. We believe that many of these old devices are not actively being used.
If your app still has a significant number of users on older devices, you can use multiple APK support in Google Play to deliver an APK that uses Google Play services 14.7.99. This is described below.
2. Build multiple APKs to support devices with an API level less than 16.
Along with some configuration and code management, you can build multiple APKs that support different minimum API levels, with different versions of Google Play services. You can accomplish this with build variants in Gradle. First, define build flavors for legacy and newer versions of your app. For example, in your build.gradle, define two different product flavors, with two different compile dependencies for the stand-in example play-services-FOO component:
productFlavors { legacy { minSdkVersion 14 versionCode 1401 // Min API level 14, v01 } current { minSdkVersion 16 versionCode 1601 // Min API level 16, v01 } } dependencies { legacyCompile 'com.google.android.gms:play-services-FOO:16.0.0' currentCompile 'com.google.android.gms:play-services-FOO:17.0.0' }
In the above situation, there are two product flavors being built against two different versions of play-services-FOO. This will work fine if only APIs are called that are available in the 16.0.0 library. If you need to call newer APIs made available with 17.0.0, you will have to create your own compatibility library for the newer API calls so that they are only built into the version of the application that can use them:
After building a release APK for each flavor, you then publish them both to the Play Store, and the device will update with the most appropriate version for that device. Read more about multiple APK support in the Play Store.
Posted by John Posavatz, Product Manager, Android Auto
At Google I/O this past May, we provided a sneak preview of several new media and messaging features for Android Auto. We are happy to announce that these features are now ready in our latest version of Android Auto, and we encourage you to update your Android Auto implementations to take advantage of them!
Several new features make it easier for users to find the media content that they're looking for. Check out the full documentation for them on our Android developer site.
Search results
After performing an Assistant-based search (e.g. "OK Google, play [artist / album / playlist / book / song / genre]"), music auto-plays as before, and in addition you can now provide your own list of categorized results. First, you'll need to declare support for onSearch() in your MediaBrowserServiceCompat implementation, and then override it. Android Auto forwards a user's search terms to this method whenever a user invokes the "Show more results" affordance.
Android Auto calls onSearch with the same Bundle of extras as the one defined for Android Auto's playFromSearch() calls. Unlike playFromSearch(), onSearch() includes a Result> that can be used to return multiple MediaItems back to Android Auto for display.
You can then categorize search results using title items. For example, music apps may include categories such as "Artists", "Albums" and "Songs".
Improved browse
Content has been "brought forward" out of the drawer, and now resides within the main view of the media screen. Within this new layout, you now have an option of either displaying your browse trees as a simple list, or you can optionally display large grids of album art / icons. We recommend using lists wherever the text description is most useful in describing content (e.g. a list of track names or podcast episodes), whereas the larger grid view is most appropriate where the album / icon aids in quick identification and selection.
To start applying content styles, you should set a global default for how your media items are displayed by applying specific constants in the BrowserRoot extras bundle returned by the onGetRoot() function. Android Auto reads the extras associated with each item in the browse tree and looks for specific constants (detailed in our documentation), and then use the presence/value of each key to add the appropriate indicator.
In order to change the default behavior for a specific node, the Content Style API supports overriding the default global hint for any browsable node's children. The same extras as above can be supplied as extras in the MediaDescription. If these extras are present, then the children of that browsable node will have the new Content Style hint.
Finally, you can organize content using title items to group media in a list. To do this, every media item in the group needs to declare an extra in their media description with the same string value, which you can localize. This value is used as the group title. You also need to pass the media items together and in the order you want them displayed.
Additional metadata icons
In both browsing and playback views, you are now able to show icons next to media items which have explicit language, have been downloaded to the user's device, and which are unplayed / partially played / completed (e.g. for audiobooks and podcasts).
Android Auto inspects extras for each item in the browse tree and looks for the specific keys for the indicators, and then uses the presence/value of each key to add the appropriate indicator.
You should add these extras to content returned by your MediaBrowse Service. "Explicit" and "Downloaded" are boolean extras (set to true to show the indicator), while "Completion State" is an integer extra set to the appropriate value. Apps should create an extras bundle that includes one or more of these keys and pass that to MediaDescription.Builder.setExtras().
We are deprecating CarExtender, in favor of the more robust and broadly beneficial MessagingStyle API. Migrating to MessagingStyle is very straightforward, and not only extends messaging support beyond Android Auto (for example, to Google Assistant), but it also brings the following immediate benefits for Android Auto:
Group messaging
Formerly, Android Auto's support for group messages was lacking - in most cases, notifications were never shown. MessagingStyle addresses that, so that your users never miss a message.
MMS / RCS support
Android Auto only supports SMS natively through the system SMS broadcast. MessagingStyle allows support for SMS apps that themselves support RCS and MMS.
To enable your app to provide messaging service for Auto devices, your app must do the following:
By moving to MessagingStyle, your app will not only gain automotive support, but also gain a richer mobile notification experience including inline replying, image preview, and conversation history; all within the notification shade.
An in-depth guide to implementing (or updating to) MessagingStyle can be found in our online developer documentation.
Thanks for continuing to support Android Auto!
The Media Controller Test (MCT) app is a powerful tool that allows you to test the intricacies of media playback on Android, and it's just gotten even more useful. Media experiences including voice interactions via the Google Assistant on Android phones, cars, TVs, and headphones, are powered by Android MediaSession APIs. This tool will help you verify your integrations. We've now added a new verification testing framework that can be used to help automate your QA testing.
The MCT is meant to be used in conjunction with an app that implements media APIs, such as the Universal Android Music Player. The MCT surfaces information about the media app's MediaController, such as the PlaybackState and Metadata, and can be used to test inter-app media controls.
The Media Action Lifecycle can be complex to follow; even in a simple Play From Search request, there are many intermediate steps (simplified timeline depicted below) where something could go wrong. The MCT can be used to help highlight any inconsistencies in how your music app handles MediaController TransportControl requests.
Previously, using the MCT required a lot of manual interaction and monitoring. The new verification testing framework offers one-click tests that you can run to ensure that your media app responds correctly to a playback request.
To access the new verification tests in the MCT, click the Test button next to your desired media app.
The next screen shows you detailed information about the MediaController, for example the PlaybackState, Metadata, and Queue. There are two buttons on the toolbar in the top right: the button on the left toggles between parsable and formatted logs, and the button on the right refreshes this view to display the most current information.
By swiping to the left, you arrive at the verification tests view, where you can see a scrollable list of defined tests, a text field to enter a query for tests that require one, and a section to display the results of the test.
As an example, to run the Play From Search Test, you can enter a search query into the text field then hit the Run Test button. Looks like the test succeeded!
Below are examples of the Pause Test (left) and Seek To test (right).
The MCT now also works on Android TV! For your media app to work with the Android TV version of the MCT, your media app must have a MediaBrowserService implementation. Please see here for more details on how to do this.
On launching the MCT on Android TV, you will see a list of installed media apps. Note that an app will only appear in this list if it implements the MediaBrowserService.
Selecting an app will take you to the testing screen, which will display a list of verification tests on the right.
Running a test will populate the left side of the screen with selected MediaController information. For more details, please check the MCT logs in Logcat.
Tests that require a query are marked with a keyboard icon. Clicking on one of these tests will open an input field for the query. Upon hitting Enter, the test will run.
To make text input easier, you can also use the ADB command:
adb shell input text [query]
Note that '%s' will add a space between words. For example, the command adb shell input text hello%sworld will add the text "hello world" to the input field.
adb shell input text hello%sworld
The MCT currently includes simple single-media-action tests for the following requests:
For a technical deep dive on how the tests are structured and how to add more tests, visit the MCT GitHub Wiki. We'd love for you to submit pull requests with more tests that you think are useful to have and for any bug fixes. Please make sure to review the contributions process for more information.
Check out the latest updates on GitHub!
Posted by Dave Burke, VP of Engineering
After more than a year of development and months of testing by early adopters, we're ready to launch Android 9 Pie, the latest release of Android, to the world.
Android 9 harnesses the power of machine learning to make your phone smarter, simpler, and tailored to you. Read all about the new consumer features here. For developers, Android 9 includes many new ways to enhance your apps and build new experiences to drive engagement.
You've given us tons of feedback along the way--over a thousand bugs and feature requests--thank you! More than 140,000 of you tried our preview builds through the Android Beta program, and seven of our device maker partners also brought our Beta to their flagship devices, enabling users around the world to give their feedback too.
Today we're pushing the source code to Android Open Source Project (AOSP), and starting the Android 9 rollout to all Pixel users worldwide, with Android 9 coming to many more devices in the coming months.
We continue to move Android forward as the premier open platform for developers worldwide to build their businesses. With Android 9 -- together with the powerful new capabilities in Google Play for apps and games -- we're committed to helping you build great experiences, as well as reach and engage the right users safely and cost-effectively around the world.
Android 9 helps your phone learn as you use it, by picking up on your preferences and adjusting automatically. Everything from helping users get the most out of their battery life to surfacing the best parts of the apps they use all the time, right when they need it most, Android 9 keeps things running smoother, longer.
We partnered with DeepMind on a feature called Adaptive Battery that uses machine learning to prioritize system resources for the apps the user cares about most. If your app is optimized for Doze, App Standby, and Background Limits, Adaptive Battery should work well for you right out of the box. If you haven't yet taken optimized your app, make sure to check out the details in the power documentation to see how it works.
Slices can help users perform tasks faster by enabling engagement outside of the fullscreen app experience. It does this by using UI templates that can display rich, dynamic, and interactive content from your app from within the Google Search app and later in other places like the Google Assistant. You can learn more about building Slices to enhance your app here.
App Actions is a new way to raise the visibility of your app and drive engagement. Actions take advantage of machine learning to surface your app to the user at just the right time, based on your app's semantic intents and the user's context.
We'll be sharing more details in the coming weeks on registering your app to handle one or more user intents, so your apps can be enabled for App Actions and surfaced across multiple Google and Android surfaces in response to user queries.
We've extended the ML models that identify entities in content or text input to support more types like Dates and Flight Numbers through the TextClassifier API. Smart Linkify lets you take advantage of the TextClassifier models through the Linkify API, including enriched options for quick follow-on user actions. Smart Linkify also delivers significant improvements in accuracy of detection as well as performance.
Android 9 adds an updated version of the Neural networks API, to extend Android's support for accelerated on-device machine learning. Neural Networks 1.1 adds support for nine new ops -- Pad, BatchToSpaceND, SpaceToBatchND, Transpose, Strided Slice, Mean, Div, Sub, and Squeeze. A typical way to take advantage of the APIs is through TensorFlow Lite.
We're excited about making your smartphone more intelligent. But it's also important that the technology fades to the back for users. In Android 9, we've evolved Android's UI to be simpler and more approachable -- for developers, these changes help improve the way users find, use, and manage your apps.
Android 9 introduces a new system navigation that we've been working on for more than a year. The new design helps make Android's multitasking more approachable and makes discovering apps much easier. You can swipe up from anywhere to see full-screen previews of recently used apps and simply tap to jump back into one of them.
Now your app can take full advantage of the latest edge-to-edge screens through display cutout support in Android 9. For most apps, supporting display cutout is seamless, with the system managing status bar height to separate your content from the cutout. If you have immersive content, you can use the display cutout APIs to check the position and shape of the cutout and request full-screen layout around it. To help with development and testing, we've added a Developer Option that simulates several cutout shapes on any device.
Apps with immersive content can display content fullscreen on devices with a display cutout.
Android 9 makes notifications even more useful and more actionable. Messaging apps can take advantage of the new MessagingStyle APIs to show conversations, attach photos and stickers, and even suggest smart replies. You'll soon be able to use ML Kit to generate smart reply suggestions for your app.
MessagingStyle notifications with conversations and smart replies [left], images and stickers [right].
In Android 9 we've added a Magnifier widget to improve the user experience of selecting text. The Magnifier widget lets users precisely position the cursor or the text selection handles by viewing zoomed text through a draggable pane. You can attach it to any view that is attached to a window, so you can use it in custom widgets or during custom text-rendering. The Magnifier widget can also provide a zoomed-in version of any view or surface, not just text.
Check out our recent blog post for more about this and other Text features, such as PrecomputedText and line height and baseline text alignment.
With a range of biometric sensors in use for authentication, we've made the experience more consistent across sensor types and apps. Android 9 introduces a system-managed dialog to prompt the user for any supported type of biometric authentication. Apps no longer need to build their own dialog--instead they use the BiometricPrompt API to show the standard system dialog. In addition to Fingerprint (including in-display sensors), the API supports Face and Iris authentication.
If your app is drawing its own fingerprint auth dialogs, you should switch to using the BiometricPrompt API as soon as possible. See this post for more information.
Android 9 introduces Android Protected Confirmation, which uses the Trusted Execution Environment (TEE) to guarantee that a given prompt string is shown and confirmed by the user. Only after successful user confirmation will the TEE then sign the prompt string, which the app can verify.
We've added StrongBox as a new KeyStore type, providing API support for devices that provide key storage in tamper-resistant hardware with isolated CPU, RAM, and secure flash. You can set whether your keys should be protected by a StrongBox security chip in your KeyGenParameterSpec.
Android 9 adds built-in support for DNS over TLS, automatically upgrading DNS queries to TLS if a network's DNS server supports it. Users can manage DNS over TLS behavior in a new Private DNS Mode in Network & internet settings. Apps that perform their own DNS queries can use a new API, LinkProperties.isPrivateDnsActive(), to check the DNS mode. More in this post.
As part of a larger effort to move all network traffic away from cleartext (unencrypted HTTP) to websites secured with TLS (HTTPS), we're changing the defaults for Network Security Configuration to block all cleartext traffic. You'll now need to make connections over TLS, unless you explicitly opt-in to cleartext for specific domains. See the details here.
In Android 9 we've expanded our use of compiler-level mitigations to harden the platform through run-time detection of dangerous behavior. Control Flow Integrity (CFI) techniques help to prevent code-reuse attacks and arbitrary code execution. In Android 9 we've greatly expanded CFI usage within the media framework and other security-critical components, such as NFC and Bluetooth. We've also introduced CFI kernel support into the Android common kernel when building with LLVM.
We've also expanded our use of Integer overflow sanitizers to mitigate memory-corruption and information-disclosure vulnerabilities. We've prioritized sanitizers in libraries with past vulnerabilities or where complex untrusted input is processed, such as libui, libnl, libmediaplayerservice and others. See this post for details.
Android 9 safeguards privacy in a number of new ways. The system now restricts access to mic, camera, and all SensorManager sensors from apps that are idle. While your app's UID is idle, the mic reports empty audio and sensors stop reporting events. Cameras used by your app are disconnected and will generate an error if the app tries to use them. In most cases, these restrictions should not introduce new issues for existing apps, but we recommend removing these requests from your apps.
Android 9 also gives the user control over access to the platform's build.serial identifier by putting it behind the READ_PHONE_STATE permission. To access the build.serial identifier, you should use the Build.getSerial() method.
build.serial
Read more about all of the privacy changes here.
With Android 9 you can now open streams from two or more physical cameras simultaneously on devices that support the multi-camera API. On devices with either dual-front or dual-back cameras, you can create innovative features not possible with just a single camera, such as seamless zoom, bokeh, and stereo vision. The API also lets you call a logical or fused camera stream that automatically switches between two or more cameras.
Other improvements in camera include new Session parameters that help to reduce delays during initial capture, and Surface sharing that lets camera clients handle various use-cases without the need to stop and start camera streaming. We've also added APIs for display-based flash support and access to OIS timestamps for app-level image stabilization and special effects.
Android 9 adds built-in support for HDR VP9 Profile 2, so you can now deliver HDR-enabled movies to your users on HDR-capable devices.
We're excited to add HEIF (heic) image encoding to the platform. HEIF is a popular format for photos that improves compression to save on storage and network data. With platform support on Android 9 devices, it's easy to send and utilize HEIF images from your backend server. Once you've made sure that your app is compatible with this data format for sharing and display, give HEIF a try as an image storage format in your app. You can do a jpeg-to-heic conversion using ImageDecoder or BitmapFactory to obtain a bitmap from jpeg, and you can use HeifWriter in the AndroidX library to write HEIF still images from YUV byte buffer, Surface, or Bitmap.
The Dynamics Processing API lets you use a new audio effect to isolate specific frequencies and lower loud or increase soft sounds to enhance the acoustic quality of your app. For example, you can improve the sound of someone who speaks quietly in a loud, distant or otherwise acoustically challenging environment. The API gives you access to a multi-stage, multi-band dynamics processing effect that includes a pre-equalizer, a multi-band compressor, a post-equalizer and a linked limiter.
An ImageDecoder API gives you an easier way to decode images to bitmaps or drawables. You can create a bitmap or drawable from a byte buffer, file, or URI. The API offers several advantages over BitmapFactory, including support for exact scaling, single-step decoding to hardware memory, support for post-processing in decode, and decoding of animated images. You can read more here.
Android 9 lets you build indoor positioning features into your apps through platform support for the IEEE 802.11mc Wi-Fi protocol -- also known as Wi-Fi Round-Trip-Time (RTT). On Android 9 devices with hardware support, location permission, and location enabled, your apps can use RTT APIs to measure the distance to nearby Wi-Fi Access Points (APs). The device doesn't need to connect to the APs to use RTT, and to maintain privacy, only the phone is able to determine the distance, not the APs.
Knowing the distance to 3 or more APs, you can calculate the device position with an accuracy of 1 to 2 meters. With this accuracy you can support use-cases like in-building navigation; fine-grained location-based services such as disambiguated voice control (e.g. 'Turn on this light'); and location-based information (e.g. 'Are there special offers for this product?').
JobScheduler is Android's central service to help you manage scheduled tasks or work across Doze, App Standby, and Background Limits. In Android 9, JobScheduler handles network-related jobs better for the user, coordinating with network status signals provided separately by carriers. Jobs can now declare their estimated data size, signal prefetching, and specify detailed network requirements—carriers can report networks as being congested or unmetered. JobScheduler then manages work according to the network status. For example, when a network is congested, JobScheduler might defer large network requests. When unmetered, it can run prefetch jobs to improve the user experience, such as prefetching headlines.
Android 9 adds an implementation of the GlobalPlatform Open Mobile API to Android. On supported devices, apps can use the OMAPI API to access secure elements (SE) to enable smart-card payments and other secure services. A hardware abstraction layer (HAL) provides the underlying API for enumerating the variety of Secure Elements (eSE, UICC, and others) available.
Android 9 brings performance and efficiency improvements to all apps through the ART runtime. We've expanded ART's use of execution profiles to optimize apps and reduce the in-memory footprint of compiled app code. ART now uses profile information for on-device rewriting of DEX files, with reductions up to 11% across a range of popular apps. We expect these to correlate closely with reductions in system DEX memory usage and faster startup times for your apps.
Kotlin is a first-class language on Android, and if you haven't tried it yet, you should! We've made an enduring commitment to Kotlin in Android and continue to expand support including optimizing the performance of Kotlin code. In Android 9, you'll see the first results of this work--we've improved several compiler optimizations, especially those that target loops, to extract better performance. We're also continuing to work in partnership with JetBrains to optimize Kotlin's generated code. You can get all of the latest Kotlin performance improvements just by keeping Android Studio's Kotlin plugin up-to-date.
Today, we are also releasing an update to the Android 9 - API 28 SDK (rev. 6), which contains nullability annotations in some of the most frequently used APIs. We'll provide more details about this in an upcoming post.
As part of Android 9 we are modernizing the foundations of Android and the apps that run on it, as part of our deep, sustained investments in security, performance, and stability.
As we announced last year, Google Play will require all app updates to target Android Oreo (targetSdkVersion 26 or higher) by November 2018. In line with that, if your app targets a platform earlier than Android 4.2 (API level 17), users installing it will see a warning dialog the first time your app is run. Here's a checklist of resources for help and support as you migrate -- we're looking forward to seeing your apps getting the most from modern Android.
With Android 9 coming to Pixel users starting today, and to other devices in the months ahead, it's important to test your app for compatibility as soon as possible. Just install your current app from Google Play on a device or or emulator running Android 9. As you work through the flows, make sure your app runs and looks great, and that it handles the Android 9 behavior changes properly.
Also watch for uses of non-SDK interfaces in your app. Android 9 restricts access to selected non-SDK interfaces, so you should reduce your reliance on them. See our recent post for details.
After you've made any necessary updates, we recommend publishing to Google Play right away. without changing the app's platform targeting. This lets you ensure a great experience for Android 9 users while you work on enhancing your app with Android 9 APIs and targeting.
When you're ready, dive into Android 9 and build with the new features and APIs in Android 9.
To get started, just download the official API 28 SDK and the latest tools and emulator images into Android Studio 3.1, or use the latest version of Android Studio 3.2. Then update your project's compileSdkVersion and targetSdkVersion to API 28. When you change your targeting, make sure your app supports all of the applicable behavior changes.
As soon as you're ready, publish your APK updates to Google Play. A common strategy is to use Google Play's beta testing feature to get early feedback from a small group of users and then do a staged rollout to production.
Visit the Android 9 site for details and developer documentation. Also check out this video and the Google I/O Android Playlist for more on what's new in Android 9 for developers.
Starting today, an over-the-air update to Android 9 will begin rolling out to Pixel phones. And devices that participated in the Beta program from Sony Mobile, Xiaomi, HMD Global, Oppo, Vivo, OnePlus, and Essential, as well as all qualifying Android One devices, will receive this update by the end of this fall! We are also working with a number of other partners to launch or upgrade devices to Android 9 this year.
As always, the system images for Pixel devices are available here for manual flash and download. If you're looking for the Android 9 source, you'll find it here in the Android Open Source Project repository under the Android 9 branches.
Now that we've reached the official release, we're bringing the Developer Preview to a close. We'll soon be closing the Developer Preview issue tracker to new issues, so if you have feedback, feel free to file a new issue against Android 9 in the AOSP issue tracker.
Thanks again to the many developers and early adopters who participated in the Android 9 Developer Preview and public beta. Your contributions have been critical to making the Android 9 platform a great one for developers and consumers.
Posted By Megan Potoski, Product Manager, Android System UI
Smartphones are quickly moving towards smaller bezels and larger aspect ratios. On these devices, display cutouts are a popular way to achieve an edge-to-edge experience while providing space for important sensors on the front of the device. There are currently 16 cutout devices from 11 OEMs already released, including several Android P beta devices, with more on the way.
These striking displays present a great opportunity for you to showcase your app. They also mean it's more important than ever to make sure your app provides a consistently great experience across devices with one or two display cutouts, as well as devices with 18:9 and larger aspect ratios.
Examples of cutout devices: Essential PH-1 (left) and Huawei P20 (right).
With many popular and upcoming devices featuring display cutouts, what can you do to make sure your app is cutout-ready?
The good news is, for the most part your app should work as intended even on a cutout device. By default, in portrait mode with no special flags set, the status bar will be resized to be at least as tall as the cutout and your content will display in the window below. In landscape or fullscreen mode, your app window will be letterboxed so that none of your content is displayed in the cutout area.
However, there are a few areas where your app could have issues on cutout devices.
Here are a few guidelines describing what issues to look out for and how to fix them.
Rendering your app content in the cutout area can be a great way to provide a more immersive, edge-to-edge experience for users, especially for content like videos, photos, maps, and games.
An example of an app that has requested layout in the display cutout.
In Android P we added APIs to let you manage how your app uses the display cutout area, as well as to check for the presence of cutouts and get their positions.
You can use layoutInDisplayCutoutMode, a new window layout mode, to control how your content is displayed relative to the cutout. By default, the app's window is allowed to extend into the cutout area if the cutout is fully contained within a system bar. Otherwise, the window is laid out such that it does not overlap with the cutout. You can also set layoutInDisplayCutoutMode to always or never render into the cutout. Using SHORT_EDGES mode to always render into the cutout is a great option if you want to take advantage of the full display and don't mind if a bit of content gets obscured by the cutout.
If you are rendering into the cutout, you can use getDisplayCutout() to retrieve a DisplayCutout that has the cutout's safe insets and bounding box(es). These let you check whether your content overlaps the cutout and reposition things if needed.
<style name="ActivityTheme"> <item name="android:windowLayoutInDisplayCutoutMode"> default/shortEdges/never </item> </style>
Attribute for setting layoutInDisplayCutoutMode from the Activity's theme.
For devices running Android 8.1 (API 27), we've also back-ported the layoutInDisplayCutoutMode activity theme attribute so you can control the display of your content in the cutout area. Note that support on devices running Android 8.1 or lower is up to the device manufacturer, however.
To make it easier to manage your cutout implementation across API levels, we've also added DisplayCutoutCompat in the AndroidX library, which is now available through the SDK manager.
For more about the display cutout APIs, take a look at the documentation.
We strongly recommend testing all screens and experiences of your app to make sure that they work well on cutout devices. We recommend using one of the Android P Beta Devices that features a cutout, such as the Essential PH-1.
If you don't have a device, you can also test using a simulated cutout on any device running Android P or in the Android Emulator. This should help you uncover any issues that your app may run into on devices with cutouts, whether they are running Android 8.1 or Android P.
Android P introduces official platform support for display cutouts, with APIs that you can use to show your content inside or outside of the cutout. To ensure consistency and app compatibility, we're working with our device manufacturer partners to mandate a few requirements.
First, devices must ensure that their cutouts do not negatively affect apps. There are two key requirements:
Second, devices may only have up to one cutout on each short edge of the device. This means that:
Within these constraints, devices can place cutouts wherever they want.
Some devices running Android 8.1 (API level 27) or earlier may optionally support a "special mode" that lets users extend a letterboxed fullscreen or landscape app into the cutout area. Devices would typically offer this mode through a toggle in the navigation bar, which would then bring up a confirmation dialog before extending the screen.
Devices that offer "special mode" allow users to optionally extend apps into the cutout area if supported by the app.
If your app's targetSdkVersion is 27 or higher, you can set the layoutInDisplayCutoutMode activity theme attribute to opt-out of special mode if needed.
While you are working on cutout support, it's also a great time to make sure your app works well on devices with 18:9 or larger aspect ratios, especially since these devices are becoming increasingly common and can feature display cutouts.
We highly encourage you to support flexible aspect ratios so that your app can leverage the full display area, no matter what device it's on. You should test your app on different display ratios to make sure it functions properly and looks good.
Here are some guidelines on screens support to keep in mind as you are developing, also refer to our earlier post on larger aspect ratios for tips on optimizing. If your app can't adapt to the aspect ratios on long screens, you can choose to declare a max aspect ratio to request letterboxing on those screens.
Thanks for reading, and we hope this helps you deliver a delightful experience to all your users, whatever display they may have!
Join us in congratulating the latest apps and games entering the Android Excellence program on Google Play. This diverse group of apps and games is recognized for their high quality, great user experience, and strong technical performance. Whether you're interested in learning meditation or a new language, or are looking for a game about butterflies or warships, we're excited to dive in to these new collections.
Check out a few of our highlighted apps.
Test your skills with these highlighted games.
See the full list of Android Excellence apps and games.
Explore other great apps and games in the Editors' Choice section on Google Play and discover best practices to help you build quality apps and games.
How useful did you find this blogpost?
★ ★ ★ ★ ★