Android 11 is out, more and more devices are being updated. As is tradition, apps will be required to update their
targetSdkVersion to the API 30 in the second half of the year — August for new apps, November for existing apps.
A big change that comes with targeting API 30 is the requirement to work with Scoped Storage.
Changes this big, especially in large apps, can be scary. To make matters worse, some of the advice we’ve seen on the Internet around how to adapt to Scoped Storage is sometimes confusing, or even misleading.
In an effort to help…
PendingIntents are an important part of the Android framework, but most of the available developer resources focus on their implementation details — a “reference to a token maintained by the system” — rather than their usage.
Since Android 12 includes important changes to pending intents, including a change that requires explicitly deciding when a
PendingIntent is mutable or immutable, I thought it would be helpful to talk more what pending intents do, how the system uses them, and why you might occasionally want a mutable
PendingIntent object wraps the functionality of an
Intent object while allowing your app…
An important change is coming to Android 12 that improves both app and platform security. This change affects all apps that target Android 12.
Activities, services, and broadcast receivers with declared intent-filters now must explicitly declare whether they should be exported or not.
❗️If your app fails with one of these error messages, it’s most likely related to this change.
Installation did not succeed.
The application could not be installed: INSTALL_FAILED_VERIFICATION_FAILURE
List of apks:
Installation failed due to: ‘null’
INSTALL_PARSE_FAILED_MANIFEST_MALFORMED: Failed parse during installPackageLI: /data/app/vmdl538800143.tmp/base.apk (at Binary XML file line #…): com.example.package.ActivityName: …
Does your app provide a service that starts another app’s
Activity as a callback when some action occurs? For example, does it accept an
Intent as an extra parameter of another
Intent, which is used as a parameter of a
Did you know this can leave your app vulnerable?
In the rest of this post, I’ll explain the problems of using this approach, and provide a solution that allows your app to provide the same functionality more safely.
The way we would expect this type of interaction to work would be something like this:
TL:DR: Learn how to write Kotlin code that works idiomatically from both Kotlin and the Java Programming Language by following our new Java-Friendly Kotlin codelab.
Since we announced adding Kotlin as an officially-supported language on Android, we’ve recommended a staged approach when adopting Kotlin. At the beginning, this means writing code such as tests and new features in Kotlin, which typically means calling from Java code into Kotlin.
As new libraries are added, or as existing libraries are converted to Kotlin, it becomes more common for Java code to call into Kotlin.
The Java-Friendly Kotlin codelab presents a sample app…
Managing audio focus is a vital part of being a good citizen in the Android media ecosystem.
What is audio focus? The docs describe it like this:
Two or more Android apps can play audio to the same output stream simultaneously. The system mixes everything together. While this is technically impressive, it can be very aggravating to a user. To avoid every music app playing at the same time, Android introduces the idea of audio focus. Only one app can hold audio focus at a time.
When your app needs to output audio, it should request audio focus. When it…
I have a confession. I’m a bit of a gamer. The Legend of Zelda games are particular favorites. Imagine my excitement when I learned there were “randomizers”, programs that would shuffle items, dungeon entrances, map layouts, and character statistics in the game so even experienced players have fresh experiences. Randomizers for some of my absolute favorite titles, including the original Legend of Zelda and The Adventure of Link. Since many of us no longer have the original hardware, we turn to emulators.
Often, emulators can be extremely complicated to implement. But it turns out that emulating a system like the…
While working on UAMP, I found it convenient to wrap several support library classes in a helper for a variety of reasons. One of the features I wanted from this wrapper was the ability to quickly reference the “transport controls” class, which is used to give commands such as play and pause.
To make it convenient, I added a property to my wrapper:
val transportControls: MediaControllerCompat.TransportControls
The thing to keep in mind is that
mediaController is a
lateinit var, because it's created during a callback to a service connection. …
Names are really helpful, both in programming and in the real world. Being able to talk about someone is much easier this way, rather than having to remember some arbitrary ID. Naming variables is so useful, in fact, that even the Harvard Mark I, which was presented to the school in early August of 1944, had the ability to name variables.
While names are useful, the same individual can be referred to differently depending on the group and situation: me, you, Nikki, Nicole, Nicole from Google, etc… This is similar to how scope works in computer science.
.let's talk about scope functions
Kotlin “scope functions”…
During a trip to Austria, I visited the Austrian National Library in Vienna. The State Hall, in particular, is this amazing space that feels like something out of an Indiana Jones film. Spaced around the room are these doors built into the shelves, and it’s tempting to imagine what sort of secrets are hidden behind them.
As it turns out, however, they’re simply reading rooms.
Let’s imagine we have an app that tracks the books in the library. One day we’re wondering what the longest and shortest books in the collection are. …