Tag Archives: AndroidX

AndroidX moving to minSdkVersion 19

Posted by Aurimas Liutikas, Software Engineer on AndroidX

AndroidX libraries are moving to a default minimum supported Android API level 19 (previously 14) starting with releases in October, 2023. According to Play Store check-in data, nearly all Android users have devices on API 19 or newer, so it’s no longer necessary to support legacy versions. This change will help AndroidX libraries maximize the potential number of users for app developers and aligns with Google Play Services and Android NDK.

If you are currently supporting a lower minSdkVersion, we recommend increasing that value to 19 and cleaning up any code to support prior versions or if you are unable to do so for business reasons you should stay on the previous versions of AndroidX.

Creating custom Tiles on Wear OS by Google with the Jetpack Tiles library

Posted by Jolanda Verhoef, Developer Relations Engineer

Wear OS header

We introduced Tiles in 2019, and since then, Tiles have become one of the most helpful and useful features on Wear OS by Google smartwatches. They are fast to access, convenient, and designed to provide users with swipeable access to the things they need to know and get done right from their wrist. This also gives users control over what information and actions they want to see.

Today, we're excited to announce that the Jetpack Tiles library is in alpha. This library enables developers to create custom Tiles on Wear OS smartwatches. These custom Tiles will become available to users later this Spring when we roll out the corresponding Wear OS platform update.

Wear OS interface

Tiles can be designed for many use cases, like tracking the user’s daily activity progress, quick-starting a workout, starting a recently played song, or sending a message to a favorite contact. While apps can be immersive, Tiles are fast-loading and focus on the user's immediate needs. If the user would like more information, Tiles can be tapped to open a related app on the watch or phone for a deeper experience.

Tile designs from Figma

Getting started

Tiles are built using Android Studio, as part of your Wear OS application. Start by adding the Wear OS Tiles dependencies:

dependencies {
  implementation "androidx.wear:wear-tiles:1.0.0-alpha01"
  debugImplementation "androidx.wear:wear-tiles-renderer:1.0.0-alpha01"
}

The first dependency includes the library you need to create a Tile, while the second dependency lets you preview the Tile in an activity.

Next, provide the information to render the Tile using the TileProviderService:

class MyTileService : TileProviderService() {
  override fun onTileRequest(requestParams: RequestReaders.TileRequest) =
    Futures.immediateFuture(Tile.builder()
      .setResourcesVersion("1")
      .setTimeline(Timeline.builder().addTimelineEntry(
         // For more information about timelines, see the docs
         TimelineEntry.builder().setLayout(
           Layout.builder().setRoot(
             Text.builder().setText("Hello world!")
           )
         )
      )
    ).build())

  override fun onResourcesRequest(requestParams: ResourcesRequest) =
    Futures.immediateFuture(Resources.builder()
      .setVersion("1")
      .build()
    )
}

There are two important parts to this code:

  • onTileRequest() creates your Tile layout. This is where most of your code goes. You can use multiple TimelineEntry instances to render different layouts for different points in time.
  • onResourcesRequest() passes any resources needed to render your Tile. If you decide to add any graphics, include them here.

Create a simple activity to preview your Tile. Add this activity in src/debug instead of src/main, as this activity is only used for debugging/previewing purposes.

class MainActivity : ComponentActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val rootLayout = findViewById<FrameLayout>(R.id.tile_container)
    TileManager(
      context = this,
      component = ComponentName(this, MyTileService::class.java),
      parentView = rootLayout
    ).create()
  }
}

Now you’re ready to publish your Tile. For more information on how to do that, and to learn more about Tiles, read our new guide and take a look at our sample Tiles to see them in action.

The Jetpack Tiles library is in alpha, and we want your feedback to help us improve the API. Happy coding!

Lockscreen and authentication improvements in Android 11

Android graphic

As phones become faster and smarter, they play increasingly important roles in our lives, functioning as our extended memory, our connection to the world at large, and often the primary interface for communication with friends, family, and wider communities. It is only natural that as part of this evolution, we’ve come to entrust our phones with our most private information, and in many ways treat them as extensions of our digital and physical identities.

This trust is paramount to the Android Security team. The team focuses on ensuring that Android devices respect the privacy and sensitivity of user data. A fundamental aspect of this work centers around the lockscreen, which acts as the proverbial front door to our devices. After all, the lockscreen ensures that only the intended user(s) of a device can access their private data.

This blog post outlines recent improvements around how users interact with the lockscreen on Android devices and more generally with authentication. In particular, we focus on two categories of authentication that present both immense potential as well as potentially immense risk if not designed well: biometrics and environmental modalities.

The tiered authentication model

Before getting into the details of lockscreen and authentication improvements, we first want to establish some context to help relate these improvements to each other. A good way to envision these changes is to fit them into the framework of the tiered authentication model, a conceptual classification of all the different authentication modalities on Android, how they relate to each other, and how they are constrained based on this classification.

The model itself is fairly simple, classifying authentication modalities into three buckets of decreasing levels of security and commensurately increasing constraints. The primary tier is the least constrained in the sense that users only need to re-enter a primary modality under certain situations (for example, after each boot or every 72 hours) in order to use its capability. The secondary and tertiary tiers are more constrained because they cannot be set up and used without having a primary modality enrolled first and they have more constraints further restricting their capabilities.

  1. Primary Tier - Knowledge Factor: The first tier consists of modalities that rely on knowledge factors, or something the user knows, for example, a PIN, pattern, or password. Good high-entropy knowledge factors, such as complex passwords that are hard to guess, offer the highest potential guarantee of identity.

    Knowledge factors are especially useful on Android becauses devices offer hardware backed brute-force protection with exponential-backoff, meaning Android devices prevent attackers from repeatedly guessing a PIN, pattern, or password by having hardware backed timeouts after every 5 incorrect attempts. Knowledge factors also confer additional benefits to all users that use them, such as File Based Encryption (FBE) and encrypted device backup.

  2. Secondary Tier - Biometrics: The second tier consists primarily of biometrics, or something the user is. Face or fingerprint based authentications are examples of secondary authentication modalities. Biometrics offer a more convenient but potentially less secure way of confirming your identity with a device.

    We will delve into Android biometrics in the next section.

  3. The Tertiary Tier - Environmental: The last tier includes modalities that rely on something the user has. This could either be a physical token, such as with Smart Lock’s Trusted Devices where a phone can be unlocked when paired with a safelisted bluetooth device. Or it could be something inherent to the physical environment around the device, such as with Smart Lock’s Trusted Places where a phone can be unlocked when it is taken to a safelisted location.

    Improvements to tertiary authentication

    While both Trusted Places and Trusted Devices (and tertiary modalities in general) offer convenient ways to get access to the contents of your device, the fundamental issue they share is that they are ultimately a poor proxy for user identity. For example, an attacker could unlock a misplaced phone that uses Trusted Place simply by driving it past the user's home, or with moderate amount of effort, spoofing a GPS signal using off-the-shelf Software Defined Radios and some mild scripting. Similarly with Trusted Device, access to a safelisted bluetooth device also gives access to all data on the user’s phone.

    Because of this, a major improvement has been made to the environmental tier in Android 10. The Tertiary tier was switched from an active unlock mechanism into an extending unlock mechanism instead. In this new mode, a tertiary tier modality can no longer unlock a locked device. Instead, if the device is first unlocked using either a primary or secondary modality, it can continue to keep it in the unlocked state for a maximum of four hours.

A closer look at Android biometrics

Biometric implementations come with a wide variety of security characteristics, so we rely on the following two key factors to determine the security of a particular implementation:

  1. Architectural security: The resilience of a biometric pipeline against kernel or platform compromise. A pipeline is considered secure if kernel and platform compromises don’t grant the ability to either read raw biometric data, or inject synthetic data into the pipeline to influence an authentication decision.
  2. Spoofability: Is measured using the Spoof Acceptance Rate (SAR). SAR is a metric first introduced in Android P, and is intended to measure how resilient a biometric is against a dedicated attacker. Read more about SAR and its measurement in Measuring Biometric Unlock Security.

We use these two factors to classify biometrics into one of three different classes in decreasing order of security:

  • Class 3 (formerly Strong)
  • Class 2 (formerly Weak)
  • Class 1 (formerly Convenience)

Each class comes with an associated set of constraints that aim to balance their ease of use with the level of security they offer.

These constraints reflect the length of time before a biometric falls back to primary authentication, and the allowed application integration. For example, a Class 3 biometric enjoys the longest timeouts and offers all integration options for apps, while a Class 1 biometric has the shortest timeouts and no options for app integration. You can see a summary of the details in the table below, or the full details in the Android Android Compatibility Definition Document (CDD).

1 App integration means exposing an API to apps (e.g., via integration with BiometricPrompt/BiometricManager, androidx.biometric, or FIDO2 APIs)

2 Keystore integration means integrating Keystore, e.g., to release app auth-bound keys

Benefits and caveats

Biometrics provide convenience to users while maintaining a high level of security. Because users need to set up a primary authentication modality in order to use biometrics, it helps boost the lockscreen adoption (we see an average of 20% higher lockscreen adoption on devices that offer biometrics versus those that do not). This allows more users to benefit from the security features that the lockscreen provides: gates unauthorized access to sensitive user data and also confers other advantages of a primary authentication modality to these users, such as encrypted backups. Finally, biometrics also help reduce shoulder surfing attacks in which an attacker tries to reproduce a PIN, pattern, or password after observing a user entering the credential.

However, it is important that users understand the trade-offs involved with the use of biometrics. Primary among these is that no biometric system is foolproof. This is true not just on Android, but across all operating systems, form-factors, and technologies. For example, a face biometric implementation might be fooled by family members who resemble the user or a 3D mask of the user. A fingerprint biometric implementation could potentially be bypassed by a spoof made from latent fingerprints of the user. Although anti-spoofing or Presentation Attack Detection (PAD) technologies have been actively developed to mitigate such spoofing attacks, they are mitigations, not preventions.

One effort that Android has made to mitigate the potential risk of using biometrics is the lockdown mode introduced in Android P. Android users can use this feature to temporarily disable biometrics, together with Smart Lock (for example, Trusted Places and Trusted Devices) as well as notifications on the lock screen, when they feel the need to do so.

To use the lockdown mode, users first need to set up a primary authentication modality and then enable it in settings. The exact setting where the lockdown mode can be enabled varies by device models, and on a Google Pixel 4 device it is under Settings > Display > Lock screen > Show lockdown option. Once enabled, users can trigger the lockdown mode by holding the power button and then clicking the Lockdown icon on the power menu. A device in lockdown mode will return to the non-lockdown state after a primary authentication modality (such as a PIN, pattern, or password) is used to unlock the device.

BiometricPrompt - New APIs

In order for developers to benefit from the security guarantee provided by Android biometrics and to easily integrate biometric authentication into their apps to better protect sensitive user data, we introduced the BiometricPrompt APIs in Android P.

There are several benefits of using the BiometricPrompt APIs. Most importantly, these APIs allow app developers to target biometrics in a modality-agnostic way across different Android devices (that is, BiometricPrompt can be used as a single integration point for various biometric modalities supported on devices), while controlling the security guarantees that the authentication needs to provide (such as requiring Class 3 or Class 2 biometrics, with device credential as a fallback). In this way, it helps protect app data with a second layer of defenses (in addition to the lockscreen) and in turn respects the sensitivity of user data. Furthermore, BiometricPrompt provides a persistent UI with customization options for certain information (for example, title and description), offering a consistent user experience across biometric modalities and across Android devices.

As shown in the following architecture diagram, apps can integrate with biometrics on Android devices through either the framework API or the support library (that is, androidx.biometric for backward compatibility). One thing to note is that FingerprintManager is deprecated because developers are encouraged to migrate to BiometricPrompt for modality-agnostic authentications.

Improvements to BiometricPrompt

Android 10 introduced the BiometricManager class that developers can use to query the availability of biometric authentication and included fingerprint and face authentication integration for BiometricPrompt.

In Android 11, we introduce new features such as the BiometricManager.Authenticators interface which allows developers to specify the authentication types accepted by their apps, as well as additional support for auth-per-use keys within the BiometricPrompt class.

More details can be found in the Android 11 preview and Android Biometrics documentation. Read more about BiometricPrompt API usage in our blog post Using BiometricPrompt with CryptoObject: How and Why and our codelab Login with Biometrics on Android.

Lockscreen and authentication improvements in Android 11

Android graphic

As phones become faster and smarter, they play increasingly important roles in our lives, functioning as our extended memory, our connection to the world at large, and often the primary interface for communication with friends, family, and wider communities. It is only natural that as part of this evolution, we’ve come to entrust our phones with our most private information, and in many ways treat them as extensions of our digital and physical identities.

This trust is paramount to the Android Security team. The team focuses on ensuring that Android devices respect the privacy and sensitivity of user data. A fundamental aspect of this work centers around the lockscreen, which acts as the proverbial front door to our devices. After all, the lockscreen ensures that only the intended user(s) of a device can access their private data.

This blog post outlines recent improvements around how users interact with the lockscreen on Android devices and more generally with authentication. In particular, we focus on two categories of authentication that present both immense potential as well as potentially immense risk if not designed well: biometrics and environmental modalities.

The tiered authentication model

Before getting into the details of lockscreen and authentication improvements, we first want to establish some context to help relate these improvements to each other. A good way to envision these changes is to fit them into the framework of the tiered authentication model, a conceptual classification of all the different authentication modalities on Android, how they relate to each other, and how they are constrained based on this classification.

The model itself is fairly simple, classifying authentication modalities into three buckets of decreasing levels of security and commensurately increasing constraints. The primary tier is the least constrained in the sense that users only need to re-enter a primary modality under certain situations (for example, after each boot or every 72 hours) in order to use its capability. The secondary and tertiary tiers are more constrained because they cannot be set up and used without having a primary modality enrolled first and they have more constraints further restricting their capabilities.

  1. Primary Tier - Knowledge Factor: The first tier consists of modalities that rely on knowledge factors, or something the user knows, for example, a PIN, pattern, or password. Good high-entropy knowledge factors, such as complex passwords that are hard to guess, offer the highest potential guarantee of identity.

    Knowledge factors are especially useful on Android becauses devices offer hardware backed brute-force protection with exponential-backoff, meaning Android devices prevent attackers from repeatedly guessing a PIN, pattern, or password by having hardware backed timeouts after every 5 incorrect attempts. Knowledge factors also confer additional benefits to all users that use them, such as File Based Encryption (FBE) and encrypted device backup.

  2. Secondary Tier - Biometrics: The second tier consists primarily of biometrics, or something the user is. Face or fingerprint based authentications are examples of secondary authentication modalities. Biometrics offer a more convenient but potentially less secure way of confirming your identity with a device.

    We will delve into Android biometrics in the next section.

  3. The Tertiary Tier - Environmental: The last tier includes modalities that rely on something the user has. This could either be a physical token, such as with Smart Lock’s Trusted Devices where a phone can be unlocked when paired with a safelisted bluetooth device. Or it could be something inherent to the physical environment around the device, such as with Smart Lock’s Trusted Places where a phone can be unlocked when it is taken to a safelisted location.

    Improvements to tertiary authentication

    While both Trusted Places and Trusted Devices (and tertiary modalities in general) offer convenient ways to get access to the contents of your device, the fundamental issue they share is that they are ultimately a poor proxy for user identity. For example, an attacker could unlock a misplaced phone that uses Trusted Place simply by driving it past the user's home, or with moderate amount of effort, spoofing a GPS signal using off-the-shelf Software Defined Radios and some mild scripting. Similarly with Trusted Device, access to a safelisted bluetooth device also gives access to all data on the user’s phone.

    Because of this, a major improvement has been made to the environmental tier in Android 10. The Tertiary tier was switched from an active unlock mechanism into an extending unlock mechanism instead. In this new mode, a tertiary tier modality can no longer unlock a locked device. Instead, if the device is first unlocked using either a primary or secondary modality, it can continue to keep it in the unlocked state for a maximum of four hours.

A closer look at Android biometrics

Biometric implementations come with a wide variety of security characteristics, so we rely on the following two key factors to determine the security of a particular implementation:

  1. Architectural security: The resilience of a biometric pipeline against kernel or platform compromise. A pipeline is considered secure if kernel and platform compromises don’t grant the ability to either read raw biometric data, or inject synthetic data into the pipeline to influence an authentication decision.
  2. Spoofability: Is measured using the Spoof Acceptance Rate (SAR). SAR is a metric first introduced in Android P, and is intended to measure how resilient a biometric is against a dedicated attacker. Read more about SAR and its measurement in Measuring Biometric Unlock Security.

We use these two factors to classify biometrics into one of three different classes in decreasing order of security:

  • Class 3 (formerly Strong)
  • Class 2 (formerly Weak)
  • Class 1 (formerly Convenience)

Each class comes with an associated set of constraints that aim to balance their ease of use with the level of security they offer.

These constraints reflect the length of time before a biometric falls back to primary authentication, and the allowed application integration. For example, a Class 3 biometric enjoys the longest timeouts and offers all integration options for apps, while a Class 1 biometric has the shortest timeouts and no options for app integration. You can see a summary of the details in the table below, or the full details in the Android Android Compatibility Definition Document (CDD).

1 App integration means exposing an API to apps (e.g., via integration with BiometricPrompt/BiometricManager, androidx.biometric, or FIDO2 APIs)

2 Keystore integration means integrating Keystore, e.g., to release app auth-bound keys

Benefits and caveats

Biometrics provide convenience to users while maintaining a high level of security. Because users need to set up a primary authentication modality in order to use biometrics, it helps boost the lockscreen adoption (we see an average of 20% higher lockscreen adoption on devices that offer biometrics versus those that do not). This allows more users to benefit from the security features that the lockscreen provides: gates unauthorized access to sensitive user data and also confers other advantages of a primary authentication modality to these users, such as encrypted backups. Finally, biometrics also help reduce shoulder surfing attacks in which an attacker tries to reproduce a PIN, pattern, or password after observing a user entering the credential.

However, it is important that users understand the trade-offs involved with the use of biometrics. Primary among these is that no biometric system is foolproof. This is true not just on Android, but across all operating systems, form-factors, and technologies. For example, a face biometric implementation might be fooled by family members who resemble the user or a 3D mask of the user. A fingerprint biometric implementation could potentially be bypassed by a spoof made from latent fingerprints of the user. Although anti-spoofing or Presentation Attack Detection (PAD) technologies have been actively developed to mitigate such spoofing attacks, they are mitigations, not preventions.

One effort that Android has made to mitigate the potential risk of using biometrics is the lockdown mode introduced in Android P. Android users can use this feature to temporarily disable biometrics, together with Smart Lock (for example, Trusted Places and Trusted Devices) as well as notifications on the lock screen, when they feel the need to do so.

To use the lockdown mode, users first need to set up a primary authentication modality and then enable it in settings. The exact setting where the lockdown mode can be enabled varies by device models, and on a Google Pixel 4 device it is under Settings > Display > Lock screen > Show lockdown option. Once enabled, users can trigger the lockdown mode by holding the power button and then clicking the Lockdown icon on the power menu. A device in lockdown mode will return to the non-lockdown state after a primary authentication modality (such as a PIN, pattern, or password) is used to unlock the device.

BiometricPrompt - New APIs

In order for developers to benefit from the security guarantee provided by Android biometrics and to easily integrate biometric authentication into their apps to better protect sensitive user data, we introduced the BiometricPrompt APIs in Android P.

There are several benefits of using the BiometricPrompt APIs. Most importantly, these APIs allow app developers to target biometrics in a modality-agnostic way across different Android devices (that is, BiometricPrompt can be used as a single integration point for various biometric modalities supported on devices), while controlling the security guarantees that the authentication needs to provide (such as requiring Class 3 or Class 2 biometrics, with device credential as a fallback). In this way, it helps protect app data with a second layer of defenses (in addition to the lockscreen) and in turn respects the sensitivity of user data. Furthermore, BiometricPrompt provides a persistent UI with customization options for certain information (for example, title and description), offering a consistent user experience across biometric modalities and across Android devices.

As shown in the following architecture diagram, apps can integrate with biometrics on Android devices through either the framework API or the support library (that is, androidx.biometric for backward compatibility). One thing to note is that FingerprintManager is deprecated because developers are encouraged to migrate to BiometricPrompt for modality-agnostic authentications.

Improvements to BiometricPrompt

Android 10 introduced the BiometricManager class that developers can use to query the availability of biometric authentication and included fingerprint and face authentication integration for BiometricPrompt.

In Android 11, we introduce new features such as the BiometricManager.Authenticators interface which allows developers to specify the authentication types accepted by their apps, as well as additional support for auth-per-use keys within the BiometricPrompt class.

More details can be found in the Android 11 preview and Android Biometrics documentation. Read more about BiometricPrompt API usage in our blog post Using BiometricPrompt with CryptoObject: How and Why and our codelab Login with Biometrics on Android.

One Biometric API Over all Android

Posted by Isai Damier, Android Developer Platform Engineering (@isaidamier)

Kevin Chyn, Android Framework

Curtis Belmonte, Android Framework

With the launch of Android 10 (API level 29), developers can now use the Biometric API, part of the AndroidX Biometric Library, for all their on-device user authentication needs. The Android Framework and Security team has added a number of significant features to the AndroidX Biometric Library, which makes all of the biometric behavior from Android 10 available to all devices that run Android 6.0 (API level 23) or higher. In addition to supporting multiple biometric authentication form factors, the API has made it much easier for developers to check whether a given device has biometric sensors. And if there are no biometric sensors present, the API allows developers to specify whether they want to use device credentials in their apps.

The features do not just benefit developers. Device manufacturers and OEMs have a lot to celebrate as well. The framework is now providing a friendly, standardized API for OEMs to integrate support for all types of biometric sensors on their devices. In addition, the framework has built-in support for facial authentication in Android 10 so that vendors don’t need to create a custom implementation.

A bit of background

The FingerprintManager class was introduced in Android 6.0 (API level 23). At the time -- and up until Android 9 (API level 28) -- the API provided support only for fingerprint sensors, and with no UI. Developers needed to build their own fingerprint UI.

Based on developer feedback, Android 9 introduced a standardized fingerprint UI policy. In addition, BiometricPrompt was introduced to encompass more sensors than just fingerprint. In addition to providing a safe, familiar UI for user authentication, it enabled a small, maintainable API surface for developers to access the variety of biometric hardware available on OEM devices. OEMs can now customize the UI with necessary affordances and iconography to expose new biometrics, such as outlines for in-display sensors. With this, app developers don’t need to worry about implementing customized, device-specific implementations for biometric authentication.

Then, in Android 10, the team introduced some pivotal features to turn the biometric API into a one-stop-shop for in-app user authentication. BiometricManager enables developers to check whether a device supports biometric authentication. Furthermore, the setDeviceCredentialAllowed() method was added to allow developers the option to use a device’s PIN/pattern/password instead of biometric credentials, if it makes sense for their app.

The team has now packaged every biometric feature you get in Android 10 into the androidx.biometric Gradle dependency so that a single, consistent, interface is available all the way back to Android 6.0 (API level 23).

How it works

The androidx.biometric Gradle dependency is a support library for the Android framework Biometric classes. On API 29 and above, the library uses the classes under android.hardware.biometrics, FingerprintManager back to API 23, and Confirm Credential all the way back to API 21. Because of the variety of APIs, we strongly recommend using the androidx support library regardless of which API level your app targets.

To use the Biometric API in your app, do the following.

1. Add the Gradle dependency to your app module

$biometric_version is the latest release of the library

def biometric_version= '1.0.0-rc02'
implementation "androidx.biometric:biometric:$biometric_version"

2. Check whether the device supports biometric authentication

The BiometricPrompt needs to be recreated every time the Activity/Fragment is created; this should be done inside onCreate() or onCreateView() so that BiometricPrompt.AuthenticationCallback can start receiving callbacks properly.

To check whether the device supports biometric authentication, add the following logic:

val biometricManager = BiometricManager.from(context)
if (biometricManager.canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS){
   // TODO: show in-app settings, make authentication calls.
}

3. Create an instance of BiometricPrompt

The BiometricPrompt constructor requires both an Executor and an AuthenticationCallback object. The Executor allows you to specify a thread on which your callbacks should be run.

The AuthenticationCallback has three methods:

  1. onAuthenticationSucceeded() is called when the user has been authenticated using a credential that the device recognizes.
  2. onAuthenticationError() is called when an unrecoverable error occurs.
  3. onAuthenticationFailed() is called when the user is rejected, for example when a non-enrolled fingerprint is placed on the sensor, but unlike with onAuthenticationError(), the user can continue trying to authenticate.

The following snippet shows one way of implementing the Executor and how to instantiate the BiometricPrompt:

private fun instanceOfBiometricPrompt(): BiometricPrompt {
   val executor = ContextCompat.getmainExecutor(context)

   val callback = object: BiometricPrompt.AuthenticationCallback() {
       override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
           super.onAuthenticationError(errorCode, errString)
           showMessage("$errorCode :: $errString")
       }

       override fun onAuthenticationFailed() {
           super.onAuthenticationFailed()
           showMessage("Authentication failed for an unknown reason")
       }

       override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
           super.onAuthenticationSucceeded(result)
           showMessage("Authentication was successful")
       }
   }

   val biometricPrompt = BiometricPrompt(context, executor, callback)
   return biometricPrompt
}

Instantiating the BiometricPrompt should be done early in the lifecycle of your fragment or activity (e.g., in onCreate or onCreateView). This ensures that the current instance will always properly receive authentication callbacks.

4. Build a PromptInfo object

Once you have a BiometricPrompt object, you ask the user to authenticate by calling biometricPrompt.authenticate(promptInfo). If your app requires the user to authenticate using a Strong biometric or needs to perform cryptographic operations in KeyStore, you should use authenticate(PromptInfo, CryptoObject) instead.

This call will show the user the appropriate UI, based on the type of biometric credential being used for authentication – such as fingerprint, face, or iris. As a developer you don’t need to know which type of credential is being used for authentication; the API handles all of that for you.

This call requires a BiometricPrompt.PromptInfo object. A PromptInfo is where you define the text that appears in the prompt: such as title, subtitle, description. Without a PromptInfo, it is not clear to the end user which app is asking for their biometric credentials. PromptInfo also allows you to specify whether it’s OK for devices that do not support biometric authentication to grant access through the device credentials, such as password, PIN, or pattern that are used to unlock the device.

Here is an example of a PromptInfo declaration:

private fun getPromptInfo(): BiometricPrompt.PromptInfo {
   val promptInfo = BiometricPrompt.PromptInfo.Builder()
       .setTitle("My App's Authentication")
       .setSubtitle("Please login to get access")
       .setDescription("My App is using Android biometric authentication")
              .setDeviceCredentialAllowed(true)
       .build()
   return promptInfo
}

For actions that require a confirmation step, such as transactions and payments, we recommend using the default option -- setConfirmationRequired(true) -- which will add a confirmation button to the UI, as shown in Figure 2.

Figure 1. Example face authentication flow using BiometricPrompt with setConfirmationRequired(false).

Figure 2. Example face authentication flow using BiometricPrompt with setConfirmationRequired(true) (default behavior).

5. Ask the user to authenticate

Now that you have all the required pieces, you can ask the user to authenticate.

val canAuthenticate = biometricManager.canAuthenticate()
if (canAuthenticate == BiometricManager.BIOMETRIC_SUCCESS) {
   biometricPrompt.authenticate(promptInfo)
} else {
   Log.d(TAG, "could not authenticate because: $canAuthenticate")
}

And that’s it! You should now be able to perform authentication, using biometric credentials, on any device that runs Android 6.0 (API level 23) or higher.

Going forward

Because the ecosystem continues to evolve rapidly, the Android Framework team is constantly thinking about how to provide long-term support for both OEMs and developers. Given the biometric library’s consistent, system-themed UI, developers don’t need to worry about device-specific requirements, and users get a more trustworthy experience.

We welcome any feedback from developers and OEMs on how to make it more robust, easier to use, and supportive of a wider range of use cases.

For in-depth examples that showcase additional use cases and demonstrate how you might integrate this library into your app, check out our repo, which contains functional sample apps that make use of the library. You can also read the associated developer guide and API reference for more information.

Google Play services and Firebase migrating to AndroidX

Posted by Doug Stevenson, Developer Advocate

Later this year, the Google Play services and Firebase SDKs will migrate from the Android Support libraries to androidx-packaged library artifacts. We are targeting this change for June/July of 2019. This will not only make our SDKs better, but make it easier for you to use the latest Jetpack features in your app.

If your app depends on any com.google.android.gms or com.google.firebase libraries, you should prepare for this migration. To quickly test your build with androidx-packaged library artifacts, add the following two lines to your gradle.properties file:

android.useAndroidX=true
android.enableJetifier=true

If your build still works, then you're done! You will be ready to use the new Google Play services and Firebase SDKs when they arrive. If you experience any new build issues or want more information on this migration, visit the official Jetpack migration guide. We will communicate when the androidx migration is complete in the near future, stay tuned!

AndroidX Development is Now Even Better

Posted by Aurimas Liutikas, software engineer on AndroidX team

AndroidX (previously known as Android Support Library) started out as a small set of libraries intended to provide backwards compatibility for new Android platform APIs and, as such, its development was strictly tied to the platform. As a result, all work was done in internal Google branches and then pushed to the public Android Open Source Project (AOSP) together with the platform push. With this flow, external contributions were limited to a narrow window of time where the internal and AOSP branches were close in content. On top of that, it was difficult to contribute -- in order to do a full AndroidX build and testing, external developers had to check out >40GB of the full Android platform code.

Today, the scope of AndroidX has expanded dramatically and includes libraries such as AppCompat for easier UI development, Room for database management, and WorkManager for background work. Many of these libraries implement higher-level abstractions and are less tied to new revisions of the Android platform, and all libraries are designed with backwards compatibility in mind from the start. Several libraries, such as RecyclerView and Fragment, are purely AndroidX-side implementations with few ties to the platform.

Starting a little over two years ago, we began a process of unbundling -- moving AndroidX out of Android platform builds into its own separate build. We had to do a great deal of work, including migrating our builds from make to Gradle as well as migrating all of our API tracking tools and documentation generation out of the platform build. With that process completed, we reached a point where a developer can now check out a minimal AndroidX project, open it in Android Studio, and build using the public SDK and public Android Gradle Plugin.

The Android developer community has long expressed a desire to contribute more easily to AndroidX; however, this was always a challenge due to the reasons described above. This changes today: AndroidX development is moving to public AOSP. That means that our primary feature development (except for top-secret integrations with the platform ?) and bug fixes will be done in the open using the r.android.com Gerrit review tool and changes will be visible in the aosp/androidx-master-dev branch.

We are making this change to give better transparency to developers; it gives developers a chance to see features and bug fixes implemented in real-time. We are also excited about receiving bug fix contributions from the community. We have written up a short guide on how to go about contributing a patch.

In addition to regular development, AOSP will be a place for experimentation and prototyping. You will see new libraries show up in this repository; some of them may be removed before they ship, change dramatically during pre-alpha development, or merge into existing libraries. The general rule is that only the libraries on maven.google.com are officially ready for external developer usage.

Finally, we are just getting started. We apologize for any rough edges that you might have when contributing to AndroidX, and we request your feedback via the public AndroidX tracker if you hit any issues.

Hello World, AndroidX

Posted by Alan Viverette (/u/alanviverette), Kathy Kam (@kathykam) , Lukas Bergstrom (@lukasb)

Today, we launch an early preview of the new Android extension libraries (AndroidX) which represents a new era for the Support Library. Please preview the change and give us your feedback. Since this is an early preview, we do not recommend trying this on any production projects as there are some known issues.

The Support Library started over 7+ years ago to provide backwards compatibility to framework APIs. Over the years, the library has grown to include device-specific UX, debugging, testing and other utilities. The adoption of the Support Library has been phenomenal; most Android apps use the Support Library today. We want to increase our investment in this area, and it is critical that we lay a solid foundation.

In that vein, we took a step back and chatted with many of you. The feedback has been consistent and unanimous; the organic growth of the library has become confusing. There are components and packages named "v7" when the minimal SDK level we support is 14! We want to make it clear for you to understand the division between APIs that are bundled with the platform and which are static libraries for app developers that work across different versions of Android.

With that in mind, say "Hello World" to "AndroidX". As previously noted in the Android KTX announcement, we are adding new features under this package, and updating some existing ones.

android.* vs androidx.* namespaces

Writing Android apps means depending on two kinds of classes:

  • Classes like PackageManager, which are bundled with the operating system and can have different APIs and behavior for different Android versions
  • Classes like AppCompatActivity or ViewModel, which are unbundled from the operating system and ship in your apk. These libraries are written to provide a single API surface with behavior that's as consistent as possible across Android versions.

Many times, unbundled libraries can be a better choice, since they provide a single API surface across different Android versions. This refactor moves the unbundled libraries - including all of the Support Library and Architecture Components - into the AndroidX package, to make it clear to know which dependencies to include.

Revised naming for packages and Maven artifacts

We redesigned the package structure to encourage smaller, more focused libraries that relieve pressure on apps and tests that aren't using Proguard or Multidex. Maven groupIds and artifactIds have been updated to better reflect library contents, and we have moved to prefixing library packages with their groupId to create an obvious link between the class that you are using and the Maven artifact from which it came.

Generally, you can expect the following mapping from old to new packages:

Old New
android.support.** androidx.@
android.databinding.** androidx.databinding.@
android.design.** com.google.android.material.@
android.support.test.** (in a future release) androidx.test.@

The Architecture Components libraries have also been moved under androidx and their package names simplified to reflect their integration with core libraries. A sample of changes to these libraries:

Old New
android.arch.** androidx.@
android.arch.persistence.room.** androidx.room.@
android.arch.persistence.** androidx.sqlite.@

Additionally, following the introduction in 28.0.0-alpha1 of Material Components for Android as a drop-in replacement for Design Library, we have refactored the design package to reflect its new direction.

For a complete listing of mappings from 28.0.0-alpha1 (android.support) to 1.0.0-alpha1 (androidx), please see the full AndroidX refactoring map. Please note that there may be minor changes to this map during the alpha phase.

Per-artifact strict semantic versioning

Starting with the AndroidX refactor, library versions have been reset from 28.0.0 to 1.0.0. Future updates will be versioned on a per-library basis, following strict semantic versioning rules where the major version indicates binary compatibility. This means, for example, that a feature may be added to RecyclerView and used in your app without requiring an update to every other library used by your app. This also means that libraries depending on androidx may provide reasonable guarantees about binary compatibility with future releases of AndroidX -- that a dependency on a 1.5.0 revision will still work when run against 1.7.0 but will likely not work against 2.0.0.

Migration from 28.0.0-alpha1

Moving your app from android.support to androidx-packaged dependencies has two major parts: source refactoring and dependency translation.

Source refactoring updates your Java code, XML resources, and Gradle configuration to reference the refactored classes and Maven artifacts. This feature is available in Android Studio Canary 14 for applications targeting Android P.

If you depend on a library that references the older Support Library, Android Studio will update that library to reference androidx instead via dependency translation. Dependency translation is automatically applied by the Android Gradle Plugin 3.2.0-alpha14, which rewrites bytecode and resources of JAR and AAR dependencies (and transitive dependencies) to reference the new androidx-packaged classes and artifacts. We will also provide a standalone translation tool as a JAR.

What's next?

We understand this is a big change for existing projects and codebases. Our intention is to provide a strong foundation that sets Android library projects up for more sustainable growth, better modularity, and smaller code size.

We hope that these changes also make it easier for developers to discover features and implement high-quality apps in less time; however, we understand that migration takes time and may not fit into everyone's production schedule. For this reason, we will continue to provide parallel updates to an android.support-packaged set of libraries for the duration of the P preview SDK timeframe. These updates will continue the 28.0.0 versioning scheme that began with 28.0.0-alpha1 in March 2018, and they will continue to be source-compatible with existing projects that depend on the android.support package.

The stable release of 28.0.0 will be the final feature release packaged as android.support. All subsequent feature releases will only be made available as androidx-packaged artifacts.

We'd love to hear from you as we iterate on this exciting future. Send us feedback by posting comments below, and please file any bugs you run into on AOSP.

We look forward to a new era of Android libraries!