Posted by Lisa Martinez, Head of Security & Privacy Business Development, Google Play and Andrew Ahn, Product Manager, Play and Android App Safety
Google helps protect billions of users every day through the use of a robust set of tools designed to keep users safe online. We’re proud to provide a wide range of these same resources to help developers build safe and successful apps. User participation increases when people have a safe and positive app engagement. We’d like to highlight a few of these free tools that developers can consider to help make user experiences safer for everyone.
Reducing toxic conversation with Perspective API
Perspective API, a free product offered by Jigsaw, uses machine learning to identify toxic language, like insults, profanity, or identity based attacks, making it easier to host healthier conversations in your apps. Perspective can be used to give feedback to commenters, help moderators more easily review comments, and keep conversations open online. Many online publishers and developers, such as the New York Times, El País, FACEIT, and Coral by VoxMedia have started to adopt this tool to promote constructive online dialogues. Learn how to get started here.
Increase child safety with Content Safety API
Google’s Content Safety API uses artificial intelligence to help developers better prioritize abuse material for review. We offer this service to NGOs and private companies to support their work protecting children. The API steps up the fight for child safety by prioritizing potentially illegal content for human review and helping reviewers find and report content faster. Quicker identification of new abuse images increases the likelihood that children being abused could be identified and protected from further abuse. Making review queues more efficient and less noisy also reduces the toll on human reviewers, who review images to confirm instances of abuse. Learn more about this on our Protecting Children site.
Prevent links to unsafe files and sites with the Safe Browsing API
Google Safe Browsing helps protect billions of devices every day by showing warnings to users when they attempt to navigate to dangerous sites or download dangerous files. Safe Browsing also notifies webmasters when their websites are compromised by malicious actors. Safe Browsing protections work across Google products and power safer browsing experiences across the Internet. Technical information on how to get started can be found here.
Thank you for continuing to partner with us to provide a positive experience for our shared users on Google Play.
Posted by Eric Bahna, Product Manager
In March, we published the Android for Cars App Library as part of Jetpack and most developers have already migrated their implementations to it! In addition to fantastic partner adoption, drivers have been enthusiastic about the new apps and our quality metrics have been positive.
Partner apps running on the Jetpack library (clockwise from upper left): T map, Chargepoint, Sygic, PlugShare, AmiGO, 2GIS, A Better Route Planner, and Flitsmeister
Today, we’re thrilled to announce that you can publish your Android Auto navigation, parking, and charging apps to production! We’ve been hard at work stabilizing the library, Android Auto, and the publishing process to reach this milestone. Publishing to production enables drivers to use your Android Auto app on their car screen without needing to sign up for a beta program. Here’s how:
Thank you for your collaboration and feedback on the Android for Cars App Library 1.0! One of the most common requests from Android Auto users has been for more categories of apps. Our goal with the library is to enable you to easily bring your app to 500+ models of Android Auto-compatible vehicles while meeting our app quality guidelines. The library abstracts away the complexities of screen form factors and input modes so you can focus on what makes your app shine.
Enabling navigation, parking, and charging apps in production is both a big step and the start of a much longer journey. We’re excited to see what you build and look forward to working together to deliver awesome in-car experiences.
Posted by Caren Chang, Developer Relations Engineer
In case you missed it, we’ve just finished a MAD Skills series on WorkManager. We started by introducing WorkManager for those new to the library and then proceeded to talk more about advanced usages including how to test and debug your WorkManager code. The series ended with an episode on how to migrate your old code from GCMNetworkManager and FirebaseJobDispatcher to use WorkManager instead.
Here’s a quick summary of what we covered.
In our first episode, we explored the basics of WorkManager through the WorkManager codelab. We started by understanding how to define work we want done, and how to schedule the work. We then moved on to implementing different types of work: unique and periodic. Finally, we ended the episode by taking a look at app standby buckets to better understand how WorkManager schedules work.
If you’re new to WorkManager, we also recommend taking a look at the following articles:
The series continued with Ben giving a more in-depth look at how WorkManager deals with multi-threading. When working with threads, you have the option of using Executors, coroutines or RxJava, and Ben demonstrated each of these approaches with WorkManager. The episode concluded by demonstrating how to return a result when the work is completed so that the UI can be updated.
In episode 3, we took a look at how to customize the initialization of WorkManager and support apps that span multiple processes. We’ve gotten a lot of questions from developers around testing and debugging, so Ben also dove into how to test your Workers, and useful debugging techniques.
In episode 4, we focused on how to migrate from old job scheduling libraries (GCMNetworkManager and FirebaseJobDispatcher) to WorkManager. Once your app starts targeting API level 30 and above, GCM NetworkManager and FirebaseJobDispatcher will no longer work on devices running Android Marshmallow (6.0) and above. If your app is still using either of those libraries, now is the time to update your apps to use WorkManager instead!
Android GDE Hugo Visser talked about why he chose to use WorkManager in a health app he recently worked on and how the library has helped his development process.
The series wrapped up with a live Q&A session where we answered your WorkManager related questions. Watch the recording to see all your questions answered, including future plans for WorkManager, handling duplicate work, retrying failed work, and more!
Posted by Luli Perkins, Developer Relations Program Manager
For the March edition of #AndroidDevJourney, we’re highlighting Android developers from all over the world with many different experiences. Early this year, we launched the #AndroidDevJourney series to highlight our community on our social media accounts. Each Saturday, from January through June, we’ll feature a new developer on our Twitter account.
For a chance to be featured in our April spotlight series, tweet us your story using #AndroidDevJourney.
Tell me about your journey to becoming an Android Developer and how you got started.
Since the age of 14, I was very interested in animations and graphic design. I used to watch advertisement animations or cricket match animations of player profiles on TV and wonder how I could create these. Later that year, when my sister purchased our home's first PC, I started learning Microsoft Paint and later Adobe Flash. I worked on Flash for about 11 years throughout high school, University, and my first three jobs in game development.
Game development was and has been my first love in computer science. But, Android became something special for me. It was NOT love-at-first sight because I hated Android when I first learned about it. I still don't know why. Coming from a poor family background, I got a fully-funded scholarship through Prime Minister ICT R&D Scholarship Program and enrolled in National University of Engineering & Technology (NUST), SEECS Islamabad campus.
In my 3rd semester, Android was at 2.2 Froyo. A company organized a workshop at our campus which was attended by high-level tech folks like CTOs, software architects, and lead engineers. University management decided to send three students to attend that workshop and I was lucky enough to be one of them. In simple words, the whole 3-days workshop was over my head. I was a newbie in C++ programming and didn't know anything about Java. And here I was trying to learn high-level Android.
After the workshop, I decided that Android was not for me. However, the university announced an open programming competition for any technology. But they gave extra points for Android submissions. This was my calling. In greed of those extra points, I took up the challenge. I borrowed the only Android book "Hello Android" from my teacher, Sir Shamyl bin Mansoor, and tried to learn as much as I could. Somehow, I managed to submit my first Android app which I showcased on a borrowed laptop with a very slow emulator of Android 2.2. To my surprise, I won it and got Rs. 100,000 prize money. First thing I bought was an Android phone and my journey started.
I started writing about it in a WordPress blog, organized workshops in different universities, made my final year project a 3D game in Adobe Flash, and AIR deployed on a Samsung Galaxy 10 tablet which had a new Android 4 Holo theme and the great Fragments.
After graduation, I got an opportunity from PacktPub (a book publishing company) to write a full book on Android. This was the best achievement I ever received. I managed to co-author two worldwide published 300+ page books (Learning Android Intents & Mastering Android Game Development) on Android in the following two years.
Having about seven years industry hands-on experience in Android development, I spend a lot of time on writing and sharing my knowledge with the community. I mostly write on my website and on Medium. Besides writing, I have been active in open source and have created some Android libraries like EasyFlipView, Room Explorer, etc.
In 2017, I started doing public speaking again. At first, it was a little tough to manage time while working a full-time job and freelance contracts, but it was worth it. I got more and more active in speaking and gave talks at events like Google IO Extended Karachi & Hyderabad in 2018 and 2019, DevFest 2019 Karachi, Pakistan's first DSC Summit, Kotlin Everywhere 2019, and other local events.
From these events, Sami Kizilbash noticed me and nominated me for becoming a Google Developers Expert. It was a tough time because of a serious medical situation with my father at that time, but a year later in February 2020 I became Pakistan's first Google Developers Expert in Android. I never thought that I would be a GDE in a field like Android. It is a big honor and achievement for me, along with a feeling of responsibility to help the community in a better way now. Android development has been my life fuel, career, brought bread for me and my family and happiness in developing and delivering more than 100 apps. With more than 2.5 billion Android devices today, this is an excellent career choice with high growth and potential for upcoming students and developers.
My GDE journey has been a fantastic one. I have enjoyed every moment of it, all the love I got from Google and fellow GDEs - including Joe Birch who actually inspired me to become GDE, Hasan Abid, Saurabh Arora, and Juhani Lehtimaki, and Saad Hamid who also helped me through the process. In all the chaos of 2020, it was a very talkative year for me, as I did 25+ online talks on Jetpack Compose animations concepts.
What’s one shortcut, tip, or hack you can’t live without?
I simply love how Mnemonic Bookmarks make code navigation so much faster and easier. When you are working on a large codebase, it becomes harder to remember which method was where and what was happening in another Fragment. Simply, press Ctrl + F11 and choose any number or character, let's say 1. Now, when you press Ctrl + 1, Android Studio will bring you back on that exact line.
What's the one piece of advice you wish someone would have given you when you started on your journey?
My journey started from my college days. I got selected as an Applied CS facilitator for Android by Google in my second year of university. Because of this, I had to take sessions and help students complete a set of tasks as part of Bootcamp. In my college days I was not very good at Android, so when the opportunity came I took it upon myself to gain some knowledge of Android and then help people with their tasks. Learning to build apps that would be used by a lot of people helped me choose Android as a career. And that is how my journey to become an Android developer started.
I like to use the Macro shortcut in Android Studio.
As a beginner in any domain, not just Android, please keep asking questions on how to improve and learn from people in the community. Some of them might not answer your queries but a handful of them might. And in this way, you can learn and grow from their experience and when the time is right, you might be able to help someone in the coming future. This is the key to success!
My journey in becoming an Android Developer started in 2010, my second year of university when I had the opportunity to participate in a program called “Entrepreneurial Programming and Research on Mobiles” (EPROM). It was a collaboration between MIT and Nokia, and my university was one of the campuses that ran the program. I did not study computer science, so the program was my first exposure to software development. I learned how to build J2ME apps and got exposure to different mobile technologies at the time.
Shortly after the program, I got a work-study opportunity at iQube Labs, where my mentor - James Fowe, who was building a mobile developer community in Nigeria - sent me a bunch of resources and tasks for me to learn how to build Android apps. The Android OS around 2010 was Android Froyo and that was the operating system on which I ran my “Hello world” on Android. Within the next year, I found myself building actual apps on Android Gingerbread.
I have since worked as an Android Developer in different companies ranging from small to mid-sized startups with millions of users, to publicly traded companies, all across many countries. I’ve had the opportunity of working with very brilliant folks that have contributed to my growth and learning.
My journey is not complete without talking about the developer community. I consider myself a product of the community and that’s why I try to give back every now and then when I have the opportunity.
I started getting involved in the developer community at my university - through various student groups, including my local GDG group then co-organized by Moyinoluwa Adeyemi (an Android GDE). I attended meetups and participated in developer challenges and hackathons.
Becoming a GDE for Android is a career milestone I never saw coming. It started in 2016 when John Kimani (Google DevRel manager for SSA) toured my office and we ran into each other at the door. I wasn’t prepared enough to become a GDE the first time my profile was reviewed, but with feedback, guidance, mentorship and hard work, I became an Android GDE in 2018.
I’m grateful to have had the opportunity to travel to so many countries around the world and meet members of the global Android Developer community. I’ve also given talks at conferences and meetups; including DevFests, Droidcon (Nairobi, Dubai, Berlin, Boston), and 360AnDev, to mention a few, about topics I enjoy - Kotlin, Design Systems, Jetpack Compose, and Developer Productivity Engineering.
That’s such a tough one, but I’ll say my favourite AndroidDev tip right now is: use the Android code search tool - https://cs.android.com - and Android API documentation as often as possible. (See also: https://androidsrc.dev/)
The two resources have helped me in answering the “why is this not working” question and understanding what’s happening under the hood. A lot of times, I need to really understand what the Framework function I’m calling does, and the answer is almost always in the documentation or in the source code.
I’ll give two for the price of one:
From a young age, I’ve always loved science fiction books and movies – I always had a gut feeling that whatever career path I went down, it would have something to do with computers. Programming quickly became my favourite creative outlet – it started with creating websites and apps when I was 11, mainly as a way to enhance my other passions such as drawing and making puzzles for my friends.
I got my first Android phone when I was in high school and immediately knew it would open a whole new world of opportunities for me, so I picked up a few books and found a few online tutorials which got me started with code on my phone running Android 2.1 Eclair.
My first app was a flashcards maker. I needed something like that to help me learn English and I couldn’t find anything online - so I made my own!
Thanks to a few of my passion projects, including a flashcard maker app, I managed to quickly land a job as an Android Engineer while I was still completing my Computer Science degree at university. I then tried working across a few other areas in software engineering, but ultimately, Android was always my favourite and ended up becoming my specialty!
It’s not quite a hack, but I honestly don’t know how I lived before ConstraintLayout became a thing! Oh – and Android Weekly’s mailing list, definitely one of the best ways to get all of the relevant news and tutorials in the Android world delivered directly to you every Monday!
Looking back, I definitely recommend putting effort and being really intentional about seeking out other Android engineers around you. Once I started proactively attending meetups and working with other engineers, my skills and knowledge grew exponentially. Collaborating and bouncing around ideas has always been my favourite way to find creative and innovative solutions to problems I’m working on.
Posted by Dan Galpin
We've added the Oboe C++ audio library to the Android Game SDK. Oboe's support of high-performance, low-latency audio across the widest range of Android devices is the right choice for most game developers.
Single API
On Android devices running Android 8.1 (API level 27) and higher, Oboe takes advantage of the improved performance and features of AAudio while maintaining backward compatibility (using OpenSL ES) with Android 4.1 (API level 16) and higher. Oboe also adds key features on top of the platform APIs to improve the audio developer experience, such as resampling, format conversion, and dynamic latency tuning. It performs audio data transformations, such as channel count conversion, when necessary to improve performance on selected devices, and has workarounds for other device-specific behaviors that improve the robustness of your audio code. In short, Oboe is now the recommended way to write audio code in C/C++ on Android.
Integrating Oboe
There are two primary ways to incorporate Oboe library prebuilts into your project. If you're using the Android Gradle plugin version 4.1.0 or higher along with CMake, and are using or can enable shared STL, enabling Oboe is as easy as adding Oboe to your Gradle dependencies, enabling prefabs, and adding a few lines to your CMakeLists file.
You can also integrate Oboe by statically linking using the Android Game SDK. Begin by downloading the library and checking it into your source control system. You need to be using minSdkVersion of 16 or higher with NDK release 18 or higher. Then, to specify the version of the game SDK to link in that's been compiled for the given ABI, API level, NDK, and STL combination, add a compiler include path in this form:
gamesdk/libs/[architecture]_API[apiLevel]_NDK[ndkVersion]_[stlVersion]_Release Example: gamesdk/libs/arm64-v8a_API24_NDK18_cpp_static_Release
Then add -loboe_static to your linker command. Since you don't need to bundle the liboboe.so shared library, static linking gives you a smaller code footprint. If the ABI, API level, NDK, and STL combination doesn't have a precompiled version available for your settings, you can alternately link against the shared library. We have more guidance, including how to configure CMake for static libraries, in our developer documentation.
-loboe_static
Oboe Basics
To output audio, you begin by creating a stream with the required properties, including a callback that is used when the stream requires new data.
oboe::AudioStreamBuilder builder; builder.setPerformanceMode(oboe::PerformanceMode::LowLatency) ->setSharingMode(oboe::SharingMode::Exclusive) ->setDataCallback(myCallback) ->setFormat(oboe::AudioFormat::Float);
You'll then populate the audio data inside of the callback. If the stream creates successfully, that means you got the requested stream type. If you didn't specify these types, you'll have to query to see what format was returned.
class MyCallback : public oboe::AudioStreamDataCallback { public: oboe::DataCallbackResult onAudioReady(oboe::AudioStream *audioStream, void *audioData, int32_t numFrames) { // We requested AudioFormat::Float auto *outputData = static_cast<float *>(audioData); // TODO: populate audioData here return oboe::DataCallbackResult::Continue; } };
For full details on using Oboe, check out the documentation, code samples and API reference. There's even a codelab which shows you how to build a simple rhythm-based game.
If you have any issues, please file them here. We'd love to hear from you.
Posted by Dave Burke, VP of Engineering
Last month we shared the first preview of Android 12, an early look at the next version of Android. Today we’re bringing you the next milestone build in this year’s release, with more new features and changes for you to try with your apps. Our program of early previews is driven by our core philosophy of openness and collaboration with you, our community. Your input helps us make Android a better platform for developers and users, so keep the feedback coming!
In Android 12 we’re making the OS smarter, easier to use, and better performing, with privacy and security at the core. We’re also working to give you new tools for building great experiences for users, whether they’re using phones, laptops, tablets, TVs, or cars. Some things to look for in today’s release include new rounded corners APIs, improved picture-in-picture APIs, better companion device management, easier effects like blur and color filter, app overlay controls, and more.
There’s a lot to check out in Developer Preview 2 - read on for a few highlights and visit the Android 12 developer site for details and downloads for Pixel. For those already running Developer Preview 1 or 1.1, we’re also offering an over-the-air (OTA) update to today’s release.
Let us know what you think, and thank you to everyone who has shared such great feedback so far.
We’re continuing to focus on giving users more transparency and control while keeping their devices and data secure. In today’s release, we’ve added some new features to check out and test with your apps.
App overlay controls - Android’s system alert window gives apps a way to get users’ attention for important actions by showing an overlay on top of the active app. These windows can interrupt the user, though, so we already require apps to request permission before displaying them. Now in Android 12 we’re giving you control over whether these overlays can be shown over your content. After you’ve declared a new permission, your app can call Window#setHideOverlayWindows() to indicate that all TYPE_APPLICATION_OVERLAY windows should be hidden when your app’s window is visible. You might choose to do this when displaying sensitive screens, such as transaction confirmation flows. More here.
Extended security for lockscreen notification actions - Android 12 adds finer-grained privacy and security controls for notifications displayed on the device lockscreen. You can now configure notification actions so that when triggered from the lockscreen, they will always generate an authentication challenge. This extends the notification visibility controls already available through the notification APIs. For example, this enables a messaging app to require authentication before deleting a message or marking it as read. More here.
You can read more about these and other privacy and security changes here.
We’re working to give you more tools to help you deliver a polished experience and better performance for users. Here are some of the updates in today’s release.
Support for Rounded corners - Many modern devices use screens with rounded corners, giving them a clean modern look, but also introducing some extra considerations for app developers. To deliver a great UX on these devices, developers need to account for the rounded corners and adjust any nearby UI elements to prevent them from being truncated.
To help with this, we’re introducing new APIs to let you query for rounded corners and get their details. A RoundedCorner holds the details for a corner, including its radius, centerpoint, and other data. You can call Display.getRoundedCorner() to get the absolute details for each rounded corner. You can also call WindowInsets.getRoundedCorner() to get the corner details relative to your app’s bounds. With these, you can manage the position of UI elements and content as needed. More here.
Picture in Picture (PIP) improvements - for people using gesture nav, we’ve improved how apps transition to picture-in-picture (PIP) mode on swipe up-to-home. If an app enables auto-PIP, the system now directly transitions the app to PIP mode on up-to-home, instead of waiting for the up-to-home animation to complete. This makes the transition smoother and improves perceived performance. We’ve also improved PIP window resizing for non-video content. Apps can now enable seamless resize to let the system resize the PIP Activity when needed. Android 12 also supports stashing the PiP window by dragging it to the left or right edge of the screen. Also, to make PIP windows easier to manipulate, we’ve updated the tap behaviors. Single-tapping now displays controls, and double-tapping toggles the PIP window size. More here.
Keeping companion device apps awake - For apps that manage companion devices like smartwatches and fitness trackers, it can be a challenge to make sure the app is running and connected whenever an associated companion device is nearby. To make this easier, we’re extending the Companion Device Manager with a new CompanionDeviceService API. Apps that manage companion devices can implement this service to let the system wake the app whenever the associated companion device is nearby. The system keeps the service bound whenever the device is nearby, and notifies the service when the device goes in and out of range or is turned off, to let the app clean up state as needed. Apps can also use a new companion device profile when connecting to a watch, which simplifies enrollment by bundling related permissions into a single grant. More here.
Bandwidth estimation improvements - for developers who need to know the typical bandwidth available to each user so you can tailor their experience, we now provide improved bandwidth estimation. We’ve enhanced the existing bandwidth estimation APIs to let you retrieve an estimate of aggregate throughput per carrier or Wi-Fi SSID, network type, and signal level, for all users on the device. The new estimation is likely to be easier and more accurate than most other estimation methods, give it a try and let us know how it works for you.
Easier blurs, color filters and other effects - In Android 12, we’re making it easier to apply common graphics effects to your Views and rendering hierarchies. You can use RenderEffect to apply blurs, color filters, and more to any RenderNode. You can combine these effects as chain effects (which compose an inner and outer effect in order) or blend them. You can also apply effects directly to Views (leveraging the underlying RenderNode) by calling View.setRenderEffect(RenderEffect).
view.setRenderEffect(RenderEffect.createBlurEffect(radiusX, radiusY, SHADER_TILE_MODE))
Blurring a View with RenderEffect
This allows you to blur the contents of an ImageView without having to get the bitmap data, process the image, create a new Bitmap, and set it back into the ImageView. RenderEffect leverages the existing rendering pipeline to minimize excess calculation.
Give these a try and let use know what you think! More here.
You can also create a frosted glass effect for your window background using a new Window.setBackgroundBlurRadius() API. With this you can set a radius to control the density and scope and the platform applies the blur to the background content within the bounds of your app’s window only. You can also use blurBehindRadius to blur all of the content behind the window to create a depth effect for a floating window.
A dialog window with background blur and blur behind...
We’re working to make updates faster and smoother by prioritizing app compatibility as we roll out new platform versions. In Android 12, we’ve made most app-facing changes opt-in to give you more time, and we’ve updated our tools and processes to help you get ready sooner.
With Developer Preview 2, we’re well into the release and continuing to improve overall stability, so now is the time to try the new features and changes and give us your feedback. We’re especially looking for input on our APIs, as well as details on how the platform changes affect your apps. Please visit the feedback page to share your thoughts with us or report issues.
It’s also a good time to start your compatibility testing and identify any work you’ll need to do. We recommend doing the work early, so you can release a compatible update by Android 12 Beta 1. There’s no need to change your app’s targetSdkVersion at this time, but we do recommend using the behavior change toggles to get a preliminary idea of how your app might be affected by opt-in changes in Android 12.
As we reach Platform Stability in August 2021, all of the app-facing system behaviors, SDK/NDK APIs, and non-SDK lists will be finalized. At that point, you can wind up your final compatibility testing and release a fully compatible version of your app, SDK, or library. More on the timeline for developers is here.
App compatibility toggles in Developer Options.
The Developer Preview has everything you need to try the Android 12 features, test your apps, and give us feedback. You can get started today by flashing a device system image to a Pixel 3 / 3 XL, Pixel 3a / 3a XL, Pixel 4 / 4 XL, Pixel 4a / 4a 5G, or Pixel 5 device or using the Android Emulator. If you’ve already installed a preview build to your Pixel device, you’ll automatically get future updates over-the-air for all later previews and Betas. More details on how to get Android 12 are here.
You can also test your apps on Android TV using today’s release and try the all-new Google TV experience. Learn more here and get started with your ADT-3 developer kit.
For complete information, visit the Android 12 developer site.
Posted by Jolanda Verhoef, Developer Relations Engineer
Let your creativity shine in the final week of the #AndroidDevChallenge! Last week we asked you to be fast, but for this final week we ask you to bring your 'A' game. Here’s the challenge:
Create a single-screen weather forecast app. You have until March 23rd, 23:59 PST to submit your entry.1
Your UI must be fully built in Compose. You can use fake weather data.
We will judge your submission on these four categories:
To help implement a beautiful design, check out the Compose documentation on layouts, theming, and graphics. Think of novel uses of animations and gestures. Improve your code quality with architecture and testing. And for overall execution, make sure to read about accessibility.
Your solution must be implemented in a public GitHub repository. Make a copy of this Github repository template and follow the instructions in the README. The template contains a basic Hello World! in Compose and a continuous integration setup.
Hello World!
The App Submission must, at a minimum, support English language use.
This week you have a chance of winning a Google Pixel 5, the ultimate 5G Google phone! We’ll be giving away one Google Pixel 5 for the winner of each of the four categories, and one for the best of the best submission.2
Community is at the heart of Jetpack Compose and your feedback helps us build a better product:
Please review the link for the full official rules associated with the entry. ↩
If you don’t live in a country where the Pixel 5 is available, when you win we’ll instead send you an electronics gift card valued at US$699. ↩