Tag Archives: Jetpack

What’s new with Android for Cars

Posted by Mickey Kataria, Director of Product Management

For over a decade, Google has been committed to automotive, with a vision of creating a safe and seamless connected experience in every car. Developers like all of you are a crucial part of helping people stay connected while on the go. We’re seeing strong momentum across our in-car experiences, Android Auto and Android Automotive OS, and today, we’re excited to share the latest updates and opportunities to reach users in the car.

Check out our I/O session: What's new with Android for Cars

Android Auto

Android Auto, which allows users to connect their phone to their car display, now has over 100 million compatible cars on the road and is supported by nearly every major car manufacturer. Porsche is our newest partner and they will begin shipping Android Auto on new cars, starting this summer with the Porsche 911.

We’ve been working closely with car manufacturers to build an even better Android Auto experience by enabling wireless projection in more vehicles, extending availability to more countries, and continuing to launch new features, like integration into the instrument cluster. To see some of the newest Android Auto technology in the BMW iX, check out the video below.

Android Auto projecting to the cluster display in a BMW iX.

Android Automotive OS

Our newest in-car experience, Android Automotive OS with Google apps and services built-in, also has strong momentum. With this experience, the entire infotainment system is powered by Android and users can access Google Assistant, Google Maps, and more apps from Google Play directly from the car screen without relying on a phone. Cars from Polestar and Volvo, like the Polestar 2 and the Volvo XC40 Recharge, are already available to customers. And by the end of 2021, this experience will be available to order in more than 10 car models from Volvo, General Motors and Renault. You can get a sneak peek of this customized experience in the new GMC HUMMER EV below.

The all-electric GMC HUMMER EV infotainment features Android Automotive OS with Google built-in. Preproduction model shown. Actual production models may vary. Initial availability Fall 2021.

Developing new apps for cars

To support this growing ecosystem, we recently made the Android for Cars App Library available as part of Jetpack. It allows developers of navigation, EV charging and parking apps to bring their apps to Android Auto compatible cars. Many of these developers have already published their Android Auto apps to the Play Store and we’re now extending this library to also support Android Automotive OS, making it easy for you to build once and generate apps that are compatible with both platforms. We’re already working with Early Access Partners — including Parkwhiz, Plugshare, Sygic, ChargePoint, Flitsmeister, SpotHero and others — to bring apps in these categories to cars powered by Android Automotive OS.

Android for cars

PlugShare, an app for finding EV chargers, has used the Android for Cars App Library and Google Assistant App Actions to build for Android Auto.

We plan to expand to more app categories in the future, so if you’re interested in joining our Early Access Program, please fill out this interest form. You can also get started with the Android for Cars App Library today, by visiting g.co/androidforcars. Lastly, you can always get help from the developer community at Stack Overflow using the android-automotive and android-auto tags. We can’t wait to see what you build next!

Android Auto Apps Powered by Jetpack

Posted by Eric Bahna, Product Manager

In January, we enabled the Google Play Store to accept open testing submissions of navigation, parking, and charging apps. It’s great to see many of you developing Android Auto apps and sending us feedback through the issue tracker. Thank you for helping us improve the platform so we deliver better in-car experiences together! Drivers have been sending positive feedback, too, as new apps launch to open testing, like Chargemap.

Chargemap in Android Auto

Today, we’ve reached the next milestone: the Android for Cars App Library is available in Jetpack as androidx.car.app 1.0.0-beta01! The move to Jetpack makes the library open source, gives you more visibility into our feature development, and provides API consistency with other Jetpack libraries. We’ve updated the developer guide and design guidelines to cover androidx.car.app. Test your app with Android Auto 6.1, or later, then you can publish your app to open testing in the Google Play Store. androidx.car.app includes all functionality of the closed source library (com.google.android.libraries.car), and then some! For example, we added a new GridTemplate, which is useful when users rely primarily on images to make their selections.

Examples of the new GridTemplate in androidx.car.app

On September 1, 2021, the closed source Android for Cars App Library (com.google.android.libraries.car.app) will no longer be available and the Google Play Store will not accept submissions that use com.google.android.libraries.car.app. Our development focus from now, including new features, is on androidx.car.app. We encourage you to migrate now and we’ve created a migration guide that makes it easy. Migration usually takes less than a day, in our experience with early access partners.

We’re working hard to stabilize androidx.car.app and prepare the Google Play Store for production submissions. Production submissions will require androidx.car.app and you can get your app ready by using it in open testing today.

Announcing Jetpack Compose Beta!

Posted by Anna-Chiara Bellini, Product Manager, Nick Butcher, Developer Relations

The Android Show: Jetpack Compose, Feb. 24 at 9am PT

Today, we’re launching the beta release of Jetpack Compose, our new UI toolkit designed to make it faster and easier to build native apps across all Android platforms. Compose offers modern, declarative Kotlin APIs, helping you build beautiful, responsive apps with way less code. Built to integrate with existing Android apps and Jetpack libraries, you can adopt Compose at your own pace by combining Android Views and Compose.

With this beta release, Compose is API complete and has all the features you need to build production-ready apps. Beta also means API stable, so we won’t change or remove APIs. Now is a great time to start learning Compose and begin planning for how you will use it in an upcoming project or feature once it reaches 1.0 later this year.

What's In Beta

Our team has been developing Compose in the open with feedback and participation from the community. Since open sourcing development in 2019, we’ve had 30 public releases, addressed over 700 external bugs, and accepted over 200 external contributions. We love seeing what you’ve been building with Compose and have used your feedback and feature requests to refine our APIs and prioritize our work. Since the alpha release, we’ve added and improved a number of new features:

  • ? Coroutines support
  • ? Accessibility support for Talkback - support for other technologies will be in Stable
  • ? Easy to use Animations, with a completely new API since alpha.
  • Interoperability with Views
  • Material UI Components, all with @Sampled code
  • Lazy Lists - Jetpack Compose's take on RecyclerView
  • DSL-based Constraint Layout
  • Modifiers
  • Testing
  • Theming and Graphics, with easy support for Dark and Light mode
  • Input and gestures
  • Text and editable text
  • Window management

For the beta release, we’ve been focused on ensuring API completeness; that all foundational APIs are in place for us to continue to build upon for 1.0 and beyond. We’ll work on stabilizing these APIs up to our 1.0 release with particular focus on app performance and accessibility.

Compose Beta is supported by the latest Canary of Android Studio Arctic Fox, which features many new tools:

    ? Live Literals: real time update of literals in Preview and on device or emulator

    ? Animation Preview: inspect and playback animations

    ? Compose support in the Layout Inspector

    ? Interactive preview: inspect and interact with a Composable in isolation

    ? Deploy Preview: to deploy a Composable on your device without needing a full app

Live Literals on Android Emulator


Layout Inspector for Jetpack Compose

Works with your existing app

Jetpack Compose is designed to work seamlessly with Android Views, letting you adopt at your own pace. You can embed Compose UIs within Android Views and use Views within Compose. We lay out a number of adoption strategies in our interoperability documentation.

In addition to View interop, we integrate with common libraries to help you to add Compose to your existing applications—no need to rewrite or re-architect your app. We offer integrations with:

  • Navigation
  • ViewModel
  • LiveData / Rx / Flow
  • Paging
  • Hilt

The MDC-Android Compose Theme Adapter and Accompanist libraries provide integrations with Material and AppCompat XML themes so you don’t need to duplicate theme definitions. Accompanist also offers wrappers for common image loading libraries.

Thinking in Compose

Jetpack Compose is a declarative UI toolkit, a paradigm shift from the current View system, where you describe what your UI should look like for a given application state, not how to produce it. Compose takes care of updating your UI when your app state changes, so you don’t have to manipulate your UI into the desired state which can be tedious and error prone.

Built entirely in Kotlin, Compose takes advantage of its great language features to offer powerful, succinct, intuitive APIs. Coroutines for example enable us to write much simpler async APIs such as describing gestures, animation or scrolling. This makes it easier to write code that combines async events, like a gesture which hands off to an animation, all with cancellation and clean-up provided by structured concurrency.

Learning Compose

To help you and your team learn all about Jetpack Compose, we’ve updated our learning pathway; a curated list of videos, hands-on codelabs and key docs to get you started. Today we’re releasing new & updated documentation guides, a number of screencasts and a new Animation Codelab to help dive deeper into how to build with Compose. From guidance on architecture, accessibility and testing, to deep dives into animation, lists or thinking in Compose, we have guides to help you get up to speed.

We also offer 8 official sample applications if you want to jump straight in and see Compose in action. We have simple to complex samples, each showcasing different APIs and use cases. Check the readme for more details.


#AndroidDevChallenge: learn Compose and win prizes

If you’re ready to get started with Compose–and also want to win some prizes along the way, check out the #AndroidDevChallenge. For the next four weeks, we’ll have weekly challenges designed to give your very own insights into Jetpack Compose, so you can fly through your projects. Compete to win new prizes for each challenge, with over one thousand prizes to win including a Google Pixel 5. You can read more about the first weekly challenge - starting today - right here.

With Jetpack Compose reaching Beta—with stable APIs and feature complete for 1.0—it's a great time to start learning Jetpack Compose and planning how you might use it in an upcoming project. We’d love to hear your feedback on adopting Compose in your app or join the discussion in the Kotlin Slack #compose channel.

MAD Skills Kotlin and Jetpack: wrap-up

Posted by Florina Muntenescu, Developer Relations Engineer

Kotlin and Jetpack image

We just wrapped up another series of MAD Skills videos and articles - this time on Kotlin and Jetpack. We covered different ways in which we made Android code more expressive and concise, safer, and easy to run asynchronous code with Kotlin.

Check out the episodes below to level up your Kotlin and Jetpack knowledge! Each episode covers a specific set of APIs, talking both about how to use the APIs but also showing how APIs work under the hood. All the episodes have accompanying blog posts and most of them link to either a sample or a codelab to make it easier to follow and dig deeper into the content. We also had a live Q&A featuring Jetpack and Kotlin engineers.

Episode 1 - Using KTX libraries

In this episode we looked at how you can make your Android and Jetpack coding easy, pleasant and Kotlin-idiomatic with Jetpack KTX extensions. Currently, more than 20 libraries have a KTX version. This episode covers some of the most important ones: core-ktx that provides idiomatic Kotlin functionality for APIs coming from the Android platform, plus a few Jetpack KTX libraries that allow us to have a better user experience when working with APIs like LiveData and ViewModel.

Check out the video or the article:

Episode 2 - Simplifying APIs with coroutines and Flow

Episode 2, covers how to simplify APIs using coroutines and Flow as well as how to build your own adapter using suspendCancellableCoroutine and callbackFlow APIs. To get hands-on with this topic, check out the Building a Kotlin extensions library codelab.

Watch the video or read the article:

Episode 3 - Using and testing Room Kotlin APIs

This episode opens the door to Room, peeking in to see how to create Room tables and databases in Kotlin and how to implement one-shot suspend operations like insert, and observable queries using Flow. When using coroutines and Flow, Room moves all the database operations onto the background thread for you. Check out the video or blog post to find out how to implement and test Room queries. For more hands-on work - check out the Room with a view codelab.

Episode 4 - Using WorkManager Kotlin APIs

Episode 4 makes your job easier with WorkManager, for scheduling asynchronous tasks for immediate or deferred execution that are expected to run even if the app is closed or the device restarts. In this episode we go over the basics of WorkManager and look a bit more in depth at the Kotlin APIs, like CoroutineWorker.

Find the video here and the article here, but nothing compares to practical experience so go through the WorkManager codelab.

Episode 5 - Community tip

Episode 5 is by Magda Miu - a Google Developer Expert on Android who shared her experience of leveraging foundational Kotlin APIs with CameraX. Check it out here:

Episode 6 - Live Q&A

In the final episode we launched into a live Q&A, hosted by Chet Haase, with guests Yigit Boyar - Architecture Components tech lead, David Winer - Kotlin product manager, and developer relations engineers Manuel Vivo and myself. We answered questions from you on YouTube, Twitter and elsewhere.

Prefer Storing Data with Jetpack DataStore

Posted by Florina Muntenescu, Android Developer Advocate, Rohit Sathyanarayana, Software Engineer

Welcome Jetpack DataStore, now in alpha - a new and improved data storage solution aimed at replacing SharedPreferences. Built on Kotlin coroutines and Flow, DataStore provides two different implementations: Proto DataStore, that lets you store typed objects (backed by protocol buffers) and Preferences DataStore, that stores key-value pairs. Data is stored asynchronously, consistently, and transactionally, overcoming most of the drawbacks of SharedPreferences.

SharedPreferences vs DataStore

SharedPreferences

* SharedPreferences has a synchronous API that can appear safe to call on the UI thread, but which actually does disk I/O operations. Furthermore, apply() blocks the UI thread on fsync(). Pending fsync() calls are triggered every time any service starts or stops, and every time an activity starts or stops anywhere in your application. The UI thread is blocked on pending fsync() calls scheduled by apply(), often becoming a source of ANRs.

** SharedPreferences throws parsing errors as runtime exceptions.

In both implementations, DataStore saves the preferences in a file and performs all data operations on Dispatchers.IO unless specified otherwise.

While both Preferences DataStore and Proto DataStore allow saving data, they do this in different ways:

  • Preference DataStore, like SharedPreferences, has no way to define a schema or to ensure that keys are accessed with the correct type.
  • Proto DataStore lets you define a schema using Protocol buffers. Using Protobufs allows persisting strongly typed data. They are faster, smaller, simpler, and less ambiguous than XML and other similar data formats. While Proto DataStore requires you to learn a new serialization mechanism, we believe that the strongly typed schema advantage brought by Proto DataStore is worth it.

Room vs DataStore

If you have a need for partial updates, referential integrity, or support for large/complex datasets, you should consider using Room instead of DataStore. DataStore is ideal for small , simple datasets and does not support partial updates or referential integrity.

Using DataStore

Start by adding the DataStore dependency. If you’re using Proto DataStore, make sure you also add the proto dependency:

// Preferences DataStore
implementation "androidx.datastore:datastore-preferences:1.0.0-alpha01"


// Proto DataStore
implementation  "androidx.datastore:datastore-core:1.0.0-alpha01"

When working with Proto DataStore, you define your schema in a proto file in the app/src/main/proto/ directory. See the protobuf language guide for more information on defining a proto schema.

syntax = "proto3";

option java_package = "<your package name here>";
option java_multiple_files = true;

message Settings {
  int my_counter = 1;
}

Create the DataStore

Create the DataStore with the Context.createDataStore() extension functions.

// with Preferences DataStore
val dataStore: DataStore<Preferences> = context.createDataStore(
    name = "settings"
)

If you’re using Proto DataStore, you’ll also have to implement the Serializer interface to tell DataStore how to read and write your data type.

object SettingsSerializer : Serializer<Settings> {
    override fun readFrom(input: InputStream): Settings {
        try {
            return Settings.parseFrom(input)
        } catch (exception: InvalidProtocolBufferException) {
            throw CorruptionException("Cannot read proto.", exception)
        }
    }

    override fun writeTo(t: Settings, output: OutputStream) = t.writeTo(output)
}


// with Proto DataStore
val settingsDataStore: DataStore<Settings> = context.createDataStore(
    fileName = "settings.pb",
    serializer = SettingsSerializer
)

Read data from DataStore

DataStore exposes the stored data in a Flow, either in a Preferences object or as the object defined in your proto schema. DataStore ensures that data is retrieved on Dispatchers.IO so your UI thread isn’t blocked.

With Preferences DataStore:

val MY_COUNTER = preferencesKey<Int>("my_counter")
val myCounterFlow: Flow<Int> = dataStore.data
     .map { currentPreferences ->
        // Unlike Proto DataStore, there's no type safety here.
        currentPreferences[MY_COUNTER] ?: 0   
   }

With Proto DataStore:

val myCounterFlow: Flow<Int> = settingsDataStore.data
    .map { settings ->
        // The myCounter property is generated for you from your proto schema!
        settings.myCounter 
    }

Write data to DataStore

To write data, DataStore offers a suspending DataStore.updateData() function that gives you the current state of the stored data as a parameter—either as a Preferences object, or an instance of the object defined in the proto schema. The updateData() function updates the data transactionally in an atomic read-write-modify operation. The coroutine completes once the data is persisted on disk.

Preferences DataStore also provides a DataStore.edit() function to make it easier to update data. Instead of receiving a Preferences object, you receive a MutablePreferences object which you edit. As with updateData(), the changes are applied to disk after the transform block completes, and the coroutine completes once data is persisted to disk.

With Preferences DataStore:

suspend fun incrementCounter() {
    dataStore.edit { settings ->
        // We can safely increment our counter without losing data due to races!
        val currentCounterValue = settings[MY_COUNTER] ?: 0
        settings[MY_COUNTER] = currentCounterValue + 1
    }
}

With Proto DataStore:

suspend fun incrementCounter() {
    settingsDataStore.updateData { currentSettings ->
        // We can safely increment our counter without losing data due to races!
        currentSettings.toBuilder()
            .setMyCounter(currentSettings.myCounter + 1)
            .build()
    }
}

Migrate from SharedPreferences to DataStore

To migrate from SharedPreferences to DataStore, you need to pass in a SharedPreferencesMigration object to the DataStore builder. DataStore can automatically migrate from SharedPreferences to DataStore for you. Migrations are run before any data access can occur in DataStore. This means that your migration must have succeeded before DataStore.data returns any values and before DataStore.updateData() can update the data.

If you’re migrating to Preferences DataStore, you can use the default SharedPreferencesMigration implementation and just pass in the name used to construct your SharedPreferences.

With Preferences DataStore:

val dataStore: DataStore<Preferences> = context.createDataStore(
    name = "settings",
    migrations = listOf(SharedPreferencesMigration(context, "settings_preferences"))
)

When migrating to Proto DataStore, you’ll have to implement a mapping function that defines how to migrate from the key-value pairs used by SharedPreferences to the DataStore schema you defined.

With Proto DataStore:

val settingsDataStore: DataStore<Settings> = context.createDataStore(
    produceFile = { File(context.filesDir, "settings.preferences_pb") },
    serializer = SettingsSerializer,
    migrations = listOf(
        SharedPreferencesMigration(
            context,
            "settings_preferences"            
        ) { sharedPrefs: SharedPreferencesView, currentData: UserPreferences ->
            // Map your sharedPrefs to your type here
          }
    )
)

Wrap-up

SharedPreferences comes with several drawbacks: a synchronous API that can appear safe to call on the UI thread, no mechanism for signaling errors, lack of transactional API, and more. DataStore is a replacement for SharedPreferences that addresses most of these shortcomings. DataStore includes a fully asynchronous API using Kotlin coroutines and Flow, handles data migration, guarantees data consistency, and handles data corruption.

As DataStore is still in alpha, we need your help to make it better! To get started, find out more about DataStore in our documentation and try it out by taking our codelabs: Preferences DataStore codelab and Proto DataStore codelab. Then, let us know how we can improve the library by creating issues on the Issue Tracker.

Announcing Jetpack Compose Alpha!

Posted by Karen Ng, Director, Product Management

Today, we’re releasing the alpha of Jetpack Compose, our modern UI toolkit designed to help you quickly and easily build beautiful apps across all Android platforms, with native access to the platform APIs. Bring your app to life with dramatically less code, interactive tools, and intuitive Kotlin APIs.

No matter where you’re working from -- whether it’s your kitchen table or an office, we know you need a programming language, an IDE and a powerful UI framework that can save you time and reduce how much code you need to write. So we built Jetpack Compose to make you (and us!) more productive with building UI.

We started with Android Jetpack — taking the hardest, most common developer problems on Android and creating a suite of libraries that ensure high quality apps that work across all versions of the platform. Today, 84% of the top 10,000 apps in the Play store are using a Jetpack library.

Then we heard how developers love Kotlin, with over 70% of the top 1000 apps and 60% of pro Android developers using Kotlin today. The Google Home app saw, in certain instances, an 80% reduction in lines of code by using Kotlin and a decrease of NullPointerExceptions by 33% compared to a similar past period. Duolingo, saw reduced line count by an average of 30%.

Finally, we heard strong feedback from the community that developers like the simplicity of declarative APIs for building UI. Jetpack Compose combines all three of these: APIs for high quality apps at scale, an intuitive language, and a reactive programming model.

Jetpack

Jetpack Compose: Now in Alpha

Jetpack Compose Alpha has what you need to build full-fledged Android apps, including powerful tools and interoperability with existing Android views so you don’t need to rewrite your app. Compose APIs are designed and developed hand-in-hand with a set of canonical sample apps that use Material Design that we’re excited to release today! You can import and explore the latest samples directly in Android Studio as well.

compose

The alpha release includes:

  • Animations
  • Constraint Layout
  • Initial A11Y support
  • Input and Gestures
  • Interoperability with Views (start mixing Composable functions in your existing app)
  • Lazy Lists
  • Material UI components
  • Performance optimizations
  • Testing
  • Text and editable Text
  • Theming and Graphics
  • Window management

We've also added a number of new capabilities to Android Studio 4.2 canary, in close partnership with the JetBrains Kotlin team, to help you build apps with Compose:

  • Compose Code completion
  • Compose Preview Annotations
  • Deploy individual composables to any device
  • Interactive Compose previews
  • Kotlin compiler plugin for code generation
  • Sample Data API for Compose

Thinking in Compose

Compose uses a programming model that is quite different from the existing model of building UI on Android. Historically, an Android view hierarchy has been represented as a tree of UI widgets. As the state of the app changes, the UI hierarchy needs to be updated to display the current data. The most common way of updating the UI is to walk the tree using functions like findViewById(), and change nodes by calling methods like:

 button.setText(String) 
container.addView(View) 
 img.setImageBitmap(Bitmap) 
These methods change the internal state of the widget. Not only can this be tedious, but updating views manually increases the likelihood of errors (e.g. forgetting to update a view).

Jetpack Compose is a fully declarative component-based approach, meaning you describe your UI as functions that transform data into a UI hierarchy. When the underlying data changes, the Compose framework automatically updates the UI hierarchy for you, making it simple to build UIs easily and quickly.

Full interop with existing Android views

Adopting any new framework is a big change for existing projects and codebases, which is why we’ve designed Compose to be as easy to adopt as Kotlin — it is fully interoperable with existing Android code, from day one.

Migrating to Compose depends on you and your team. If you're building a new app, the best option might be to implement your entire UI with Compose. We know that most of you have large existing codebases, so rather than rewriting your app, you can combine Compose with your existing UI design.

There are two main ways you can combine Compose with a view-based UI:

  • You can add Compose elements into your existing UI, either by creating an entirely new Compose-based screen, or by adding Compose elements into an existing fragment or view layout.
  • You can add a view-based UI element into your composable functions. Doing so lets you add non-Compose widgets, such as MapView or WebView, into a Compose-based design.

We’ve also published a new library, MDC Compose Theme Adapter, which allows you to reuse your existing Material Components themes within your Compose UI.

To learn more, try the Compose for existing apps codelab or check out these two samples:

  • Tivi and Sunflower are existing apps which are being integrated with Compose
  • Crane sample app, embeds a MapView in Compose

Powerful Tools

Jetpack Compose is built with powerful tooling in Android Studio, designed to help you iterate quickly on the piece of UI you’re working on.

The Compose layout preview enables you to preview your Compose components without having to deploy your app to a device or emulator. As you develop your app, your previews update to help you review your changes faster. To create a layout preview, write a composable function that does not take any parameters, and add the

 @Preview annotation 
After you build your app, the preview function's UI appears in Studio's Preview pane.

Jetpack

Android Studio provides an interactive preview mode. While you're in interactive preview mode, you can click or type in your UI elements, and the UI responds as if it were in the installed app.

Jetpack

You can also deploy a single composable to your physical device or Android Emulator. Android Studio creates a new activity containing the UI generated by that function, and deploys it to your app on the device. This lets you try out the UI on an actual device without needing to reinstall the entire app or navigate to its location.

Jetpack

Get started with Jetpack Compose

To get started with Jetpack Compose, try the Compose Tutorial and get setup. Or dive right into the sample apps and walk through those apps in ‘Compose by Example’:

To find a comprehensive set of Compose resources, from new codelabs and expanded documentation, see the Compose pathway.

Since we open-sourced Jetpack Compose last year, so many of you have given us invaluable feedback, logged bugs, or contributed CLs and have gotten us where we are today. Thank you!

Compose isn’t recommended for full production use yet, in particular as we work towards API stability and finish performance optimizations, but we’d love you to give it a try and share feedback. Join us in the discussion on the #compose channel at Kotlin Slack. Compose 1.0 is expected in 2021.

Happy Composing!

11 Weeks of Android: Jetpack

Posted by Diana Wong, Product Manager, Android Jetpack

Android Jetpack Week 6 banner

This blog post is part of a weekly series for #11WeeksOfAndroid. For each of the #11WeeksOfAndroid, we’re diving into a key area so you don’t miss anything.This week, we spotlighted Jetpack; here’s a look at what you should know.

The big news

In 2018, we launched Android Jetpack as a suite of libraries to help developers follow best practices, reduce boilerplate code, and write code that works consistently across Android versions and devices. We are excited about the growth we’ve seen and the incredible feedback that developers like you have shared with us. 47% of the top 1000 apps use 2 or more Jetpack libraries, not including core libraries like AppCompat or Lifecycle. Our work over the past year has been about making the basics easy for Android developers, so that you can focus on the code you care about. We have released many updates to our existing libraries as well as new libraries to help make building high-quality apps easier.

What to watch

We have also been busy pushing out many updates over the past year!

For an overall look at what’s new in Jetpack, be sure to check out our talk from #Android11 Beta launch:

It’s a quick fly-by introducing many of the updates to our libraries, with pointers on how to get started.

This week, we’ve also done deep dives into major releases like Hilt, including cheat sheets to help you get started, and how we migrated our own samples to use Hilt for dependency injection. Less boilerplate = more fun.

Paging 3.0 is one of our first libraries written Kotlin-first and based on coroutines. The Paging library adds the features you asked for like better error handling, easier list transformations like map or filter, and support for common features like list separators, headers, and footers. We added RxJava, LiveData and ListenableFutures support and backwards compatibility with Paging 2, so it’s easier to migrate.

Using the Camera in your app? CameraX is in Beta and helps developers manage edge cases across different devices and OS versions, so that you don’t have to.

This year, we've made several major improvements with the release of Navigation 2.3, which allows you to navigate between different screens of your app with ease while also allowing you to follow Android UI principles. Let us navigate you through them all here:

Spotlight on Permissions

In Android 11, we continued our work to give users even more control over sensitive permissions. At the same time, it's very important to us that we make it as easy as possible for you as developers to build for Android. With the changes in privacy over the past several releases, Android Jetpack is making it easier for your app to work with Permissions. Now there are type-safe contracts for common intents and more via new ActivityResult APIs. These changes simplify how you request permissions, and we’ll continue to work on making permissions easier in the future. Find out more in this post.

Learning path

Take a look at our new Learning pathway for an easy way to go through all the highlights from this week. It’s an ordered tutorial which guides you through our new content, culminating in a quiz. Bonus: You earn a bright and shiny Jetpack badge to be saved to your Google Developer Profile. In addition to the learning pathway, we’ve also got a new library explorer to make it simple to find more about Jetpack libraries you might be looking for and their latest updates.

Key takeaways

Best practices are baked into Jetpack libraries, giving opinionated guidance to make it easier for you to build a higher-quality Android app. We’ve released new features to Navigation and Workmanager, updates to increase the stability of CameraX, added robustness for Biometrics, and more. We’ve also launched new libraries, like our collaboration with Dagger for Hilt and a new library to help improve app startup. Your feedback is important to us; so give these libraries a shot, tell us what you think, and help us improve them!

Resources

You can find the entire playlist of #11WeeksOfAndroid video content here, and learn more about each week here. We’ll continue to spotlight new areas each week, so keep an eye out and follow us on Twitter and YouTube. Thanks so much for letting us be a part of this experience with you!

Improving inter-activity communication with Jetpack ActivityResult

Posted by Yacine Rezgui, Developer Advocate

Whether you're requesting a permission, selecting a file from the system file manager, or expecting data from a 3rd party app, passing data between activities is a core element in inter-process communication on Android. We’ve recently released the new ActivityResult APIs to help handle these activity results.

Previously, to get results from started activities, apps needed to implement an onActivityResult() method in their activities and fragments, check which requestCode a result is referring to, verify that the requestCode is OK, and finally inspect its result data or extended data.

This leads to complicated code, and it doesn’t provide a type-safe interface for expected arguments when sending or receiving data from an activity.

What are the ActivityResult APIs?

The ActivityResult APIs were added to the Jetpack activity and fragment libraries, making it easier to get results from activities by providing type-safe contracts. These contracts define expected input and result types for common actions like taking a picture or requesting a permission, while also providing a way to create your own contracts.

The ActivityResult APIs provide components for registering for an activity result, launching a request, and handling its result once it is returned by the system. You can also receive the activity result in a separate class from where the activity is launched and still rely on the type-safe contracts.

How to use it

To demonstrate how to use the ActivityResult APIs, let’s go over an example where we’re opening a document.

First, you need to add the following dependencies to your gradle file:

repositories {
    google()
    maven()
}

dependencies {
  implementation "androidx.activity:activity:1.2.0-alpha02"
  implementation "androidx.activity:fragment:1.3.0-alpha02"
}

You need to register a callback along with the contract that defines its input and output types.

In this context, GetContent() refers to the ACTION_GET_DOCUMENT intent, and is one of the default contracts already defined in the Activity library. You can find the complete list of contracts here.

val getContent = registerForActivityResult(GetContent()) { uri: Uri? ->
    // Handle the returned Uri
}

Now we need to launch our activity using the returned launcher. As you can set a mime type filter when listing the selectable files, GetContent.launch() will accept a string as a parameter:

val getContent = registerForActivityResult(GetContent()) { uri: Uri? ->
    // Handle the returned Uri
}

override fun onCreate(savedInstanceState: Bundle?) {
    // ...

    val selectButton = findViewById<Button>(R.id.select_button)

    selectButton.setOnClickListener {
        // Pass in the mime type you'd like to allow the user to select
        // as the input
        getContent.launch("image/*")
    }
}

Once an image has been selected and you return to your activity, your registered callback will be executed with the expected results. As you saw through the code snippets, ActivityResult brings an easier developer experience when dealing with results from activities.

Start using Activity 1.2.0-alpha02 and Fragment 1.3.0-alpha02 for a type-safe way to handle your intent results with the new ActivityResult APIs.

Let us know what you think and how we can make it better by providing feedback on the issue tracker.

Improving inter-activity communication with Jetpack ActivityResult

Posted by Yacine Rezgui, Developer Advocate

Whether you're requesting a permission, selecting a file from the system file manager, or expecting data from a 3rd party app, passing data between activities is a core element in inter-process communication on Android. We’ve recently released the new ActivityResult APIs to help handle these activity results.

Previously, to get results from started activities, apps needed to implement an onActivityResult() method in their activities and fragments, check which requestCode a result is referring to, verify that the requestCode is OK, and finally inspect its result data or extended data.

This leads to complicated code, and it doesn’t provide a type-safe interface for expected arguments when sending or receiving data from an activity.

What are the ActivityResult APIs?

The ActivityResult APIs were added to the Jetpack activity and fragment libraries, making it easier to get results from activities by providing type-safe contracts. These contracts define expected input and result types for common actions like taking a picture or requesting a permission, while also providing a way to create your own contracts.

The ActivityResult APIs provide components for registering for an activity result, launching a request, and handling its result once it is returned by the system. You can also receive the activity result in a separate class from where the activity is launched and still rely on the type-safe contracts.

How to use it

To demonstrate how to use the ActivityResult APIs, let’s go over an example where we’re opening a document.

First, you need to add the following dependencies to your gradle file:

repositories {
    google()
    maven()
}

dependencies {
  implementation "androidx.activity:activity:1.2.0-alpha02"
  implementation "androidx.activity:fragment:1.3.0-alpha02"
}

You need to register a callback along with the contract that defines its input and output types.

In this context, GetContent() refers to the ACTION_GET_DOCUMENT intent, and is one of the default contracts already defined in the Activity library. You can find the complete list of contracts here.

val getContent = registerForActivityResult(GetContent()) { uri: Uri? ->
    // Handle the returned Uri
}

Now we need to launch our activity using the returned launcher. As you can set a mime type filter when listing the selectable files, GetContent.launch() will accept a string as a parameter:

val getContent = registerForActivityResult(GetContent()) { uri: Uri? ->
    // Handle the returned Uri
}

override fun onCreate(savedInstanceState: Bundle?) {
    // ...

    val selectButton = findViewById<Button>(R.id.select_button)

    selectButton.setOnClickListener {
        // Pass in the mime type you'd like to allow the user to select
        // as the input
        getContent.launch("image/*")
    }
}

Once an image has been selected and you return to your activity, your registered callback will be executed with the expected results. As you saw through the code snippets, ActivityResult brings an easier developer experience when dealing with results from activities.

Start using Activity 1.2.0-alpha02 and Fragment 1.3.0-alpha02 for a type-safe way to handle your intent results with the new ActivityResult APIs.

Let us know what you think and how we can make it better by providing feedback on the issue tracker.

Improving inter-activity communication with Jetpack ActivityResult

Posted by Yacine Rezgui, Developer Advocate

Whether you're requesting a permission, selecting a file from the system file manager, or expecting data from a 3rd party app, passing data between activities is a core element in inter-process communication on Android. We’ve recently released the new ActivityResult APIs to help handle these activity results.

Previously, to get results from started activities, apps needed to implement an onActivityResult() method in their activities and fragments, check which requestCode a result is referring to, verify that the requestCode is OK, and finally inspect its result data or extended data.

This leads to complicated code, and it doesn’t provide a type-safe interface for expected arguments when sending or receiving data from an activity.

What are the ActivityResult APIs?

The ActivityResult APIs were added to the Jetpack activity and fragment libraries, making it easier to get results from activities by providing type-safe contracts. These contracts define expected input and result types for common actions like taking a picture or requesting a permission, while also providing a way to create your own contracts.

The ActivityResult APIs provide components for registering for an activity result, launching a request, and handling its result once it is returned by the system. You can also receive the activity result in a separate class from where the activity is launched and still rely on the type-safe contracts.

How to use it

To demonstrate how to use the ActivityResult APIs, let’s go over an example where we’re opening a document.

First, you need to add the following dependencies to your gradle file:

repositories {
    google()
    maven()
}

dependencies {
  implementation "androidx.activity:activity:1.2.0-alpha02"
  implementation "androidx.activity:fragment:1.3.0-alpha02"
}

You need to register a callback along with the contract that defines its input and output types.

In this context, GetContent() refers to the ACTION_GET_DOCUMENT intent, and is one of the default contracts already defined in the Activity library. You can find the complete list of contracts here.

val getContent = registerForActivityResult(GetContent()) { uri: Uri? ->
    // Handle the returned Uri
}

Now we need to launch our activity using the returned launcher. As you can set a mime type filter when listing the selectable files, GetContent.launch() will accept a string as a parameter:

val getContent = registerForActivityResult(GetContent()) { uri: Uri? ->
    // Handle the returned Uri
}

override fun onCreate(savedInstanceState: Bundle?) {
    // ...

    val selectButton = findViewById<Button>(R.id.select_button)

    selectButton.setOnClickListener {
        // Pass in the mime type you'd like to allow the user to select
        // as the input
        getContent.launch("image/*")
    }
}

Once an image has been selected and you return to your activity, your registered callback will be executed with the expected results. As you saw through the code snippets, ActivityResult brings an easier developer experience when dealing with results from activities.

Start using Activity 1.2.0-alpha02 and Fragment 1.3.0-alpha02 for a type-safe way to handle your intent results with the new ActivityResult APIs.

Let us know what you think and how we can make it better by providing feedback on the issue tracker.