API Level: 21

Along with new features and capabilities, Android 5.0 includes a variety of
system changes and API behavior changes. This document highlights
some of the key changes that you should be understand and account for in your apps.

If you have previously published an app for Android, be aware that your app
might be affected by these changes in Android 5.0.

For a high-level look at the new platform features, instead
see the
[Android Lollipop
highlights](https://developer.android.com/about/versions/lollipop).

### Videos

[Dev Byte: What's New in Android 5.0](https://www.youtube.com/watch?v=um1S2u022HA)

[Dev Byte: Notifications](https://www.youtube.com/watch?v=Uiq2kZ2JHVY)

## Android Runtime (ART)

In Android 5.0 the ART runtime replaces Dalvik as the platform default. The ART runtime was
introduced in Android 4.4 on an experimental basis.

For an overview of ART's new features, see
[Introducing
ART](https://source.android.com/devices/tech/dalvik/art.html). Some of the major new features are:

- Ahead-of-time (AOT) compilation
- Improved garbage collection (GC)
- Improved debugging support

Most Android apps should just work without any changes under ART. However, some
techniques that work on Dalvik do not work on ART. For information about the
most important issues, see
[Verifying App
Behavior on the Android Runtime (ART)](https://developer.android.com/guide/practices/verifying-apps-art). Pay particular attention if:

- Your app uses Java Native Interface (JNI) to run C/C++ code.
- You use development tools that generate non-standard code (such as some obfuscators).
- You use techniques that are incompatible with compacting garbage collection.

## Notifications

Make sure your notifications take these Android 5.0 changes into account.
To learn more about designing your notifications for Android 5.0 and higher,
see the [notifications
design guide](https://material.google.com/patterns/notifications.html).

### Material design style

Notifications are drawn with dark text atop white (or very light) backgrounds
to match the new material design widgets. Make sure that all your
notifications look right with the new color scheme. If your notifications
look wrong, fix them:

- Use [setColor()](https://developer.android.com/reference/android/app/Notification.Builder#setColor(int)) to set an accent color in a circle behind your icon image.
- Update or remove assets that involve color. The system ignores all non-alpha channels in action icons and in the main notification icon. You should assume that these icons will be alpha-only. The system draws notification icons in white and action icons in dark gray.

### Sound and vibration

If you are currently adding sounds and vibrations to your notifications by
using the [Ringtone](https://developer.android.com/reference/android/media/Ringtone), [MediaPlayer](https://developer.android.com/reference/android/media/MediaPlayer),
or [Vibrator](https://developer.android.com/reference/android/os/Vibrator) classes, remove this code so that
the system can present notifications correctly in
*priority* mode. Instead, use
[Notification.Builder](https://developer.android.com/reference/android/app/Notification.Builder) methods to add sounds and
vibration.

Setting the device to
[RINGER_MODE_SILENT](https://developer.android.com/reference/android/media/AudioManager#RINGER_MODE_SILENT) causes
the device to enter the new priority mode. The device leaves priority
mode if you set it to
[RINGER_MODE_NORMAL](https://developer.android.com/reference/android/media/AudioManager#RINGER_MODE_NORMAL) or
[RINGER_MODE_VIBRATE](https://developer.android.com/reference/android/media/AudioManager#RINGER_MODE_NORMAL).

Previously, Android used [STREAM_MUSIC](https://developer.android.com/reference/android/media/AudioManager#STREAM_MUSIC)
as the master stream to control volume on tablet devices. In Android 5.0, the
master volume stream for both phone and tablet devices is now unified, and
is controlled by [STREAM_RING](https://developer.android.com/reference/android/media/AudioManager#STREAM_RING) or
[STREAM_NOTIFICATION](https://developer.android.com/reference/android/media/AudioManager#STREAM_NOTIFICATION).

### Lock screen visibility

By default, notifications now appear on the user's lock screen in Android 5.0.
Users can choose to protect sensitive information from being exposed, in which
case the system automatically redacts the text displayed by the notification. To
customize this redacted notification, use
[setPublicVersion()](https://developer.android.com/reference/android/app/Notification.Builder#setPublicVersion(android.app.Notification)).

If the notification does not contain personal information, or if you want to
allow media playback control on the notification, call the
[setVisibility()](https://developer.android.com/reference/android/app/Notification.Builder#setVisibility(int))
method and set the notification's visibility level to
[VISIBILITY_PUBLIC](https://developer.android.com/reference/android/app/Notification#VISIBILITY_PUBLIC).

### Media playback

If you are implementing notifications that present media playback
status or transport controls, consider using the new
[Notification.MediaStyle](https://developer.android.com/reference/android/app/Notification.MediaStyle) template instead of a custom
[RemoteViews.RemoteView](https://developer.android.com/reference/android/widget/RemoteViews.RemoteView) object. Whichever approach you
choose, make sure to set the notification's visibility to
[VISIBILITY_PUBLIC](https://developer.android.com/reference/android/app/Notification#VISIBILITY_PUBLIC) so that
your controls are accessible from the lock screen. Note that beginning in
Android 5.0, the system no longer shows
[RemoteControlClient](https://developer.android.com/reference/android/media/RemoteControlClient) objects on the lock screen. For more
information, see
[If your app uses RemoteControlClient](https://developer.android.com/about/versions/lollipop/android-5.0-changes#BehaviorMediaControl).

### Heads-up notification

Notifications may now appear in a small floating window (also called a
heads-up notification) when the device is active (that is, the device is
unlocked and its screen is on). These notifications appear similar to the
compact form of your notification, except that the heads-up notification also
shows action buttons. Users can act on, or dismiss, a heads-up notification
without leaving the current app.

Examples of conditions that may trigger heads-up notifications include:

- The user's activity is in fullscreen mode (the app uses [fullScreenIntent](https://developer.android.com/reference/android/app/Notification#fullScreenIntent))
- The notification has high priority and uses ringtones or vibrations

If your app implements notifications under any of those scenarios, make sure
that heads-up notifications are presented correctly.

## Media Controls and RemoteControlClient

The [RemoteControlClient](https://developer.android.com/reference/android/media/RemoteControlClient) class is now deprecated. Switch
to the new [MediaSession](https://developer.android.com/reference/android/media/session/MediaSession) API as
soon as possible.

Lock screens in Android 5.0 do not show transport controls for
your [MediaSession](https://developer.android.com/reference/android/media/session/MediaSession) or
[RemoteControlClient](https://developer.android.com/reference/android/media/RemoteControlClient). Instead, your app can provide
media playback control from the lock screen through a notification. This
gives your app more control over the presentation of media buttons, while
providing a consistent experience for users across locked and
unlocked devices.

Android 5.0 introduces a new
[Notification.MediaStyle](https://developer.android.com/reference/android/app/Notification.MediaStyle) template for this purpose.
[Notification.MediaStyle](https://developer.android.com/reference/android/app/Notification.MediaStyle) converts notification
actions that you added with
[Notification.Builder.addAction()](https://developer.android.com/reference/android/app/Notification.Builder#addAction(int, java.lang.CharSequence, android.app.PendingIntent)) into compact buttons embedded in your app's
media playback notifications. Pass your session token to the
[setSession()](https://developer.android.com/reference/android/app/Notification.MediaStyle#setMediaSession(android.media.session.MediaSession.Token)) method to inform the system that this notification controls an
ongoing media session.

Make sure to set the notification's visibility to
[VISIBILITY_PUBLIC](https://developer.android.com/reference/android/app/Notification#VISIBILITY_PUBLIC)
to mark the notification as safe to show on any lock screen (secure or
otherwise). For more information, see
[Lock screen notifications](https://developer.android.com/about/versions/lollipop/android-5.0-changes#LockscreenNotifications).

To display media playback controls if your app is running on the
Android [TV](https://developer.android.com/tv) or
[Wear](https://developer.android.com/wear) platform, implement the
[MediaSession](https://developer.android.com/reference/android/media/session/MediaSession) class. You should also implement
[MediaSession](https://developer.android.com/reference/android/media/session/MediaSession) if your app needs to receive media
button events on Android devices.

## getRecentTasks()

With the introduction of the new *concurrent documents and activities
tasks* feature in Android 5.0 (see [Concurrent
documents and activities in the recents screen](https://developer.android.com/about/versions/lollipop/android-5.0-changes#Recents) below),
the [ActivityManager.getRecentTasks()](https://developer.android.com/reference/android/app/ActivityManager#getRecentTasks(int, int)) method is now deprecated to improve user
privacy. For backward compatibility, this method still returns a small subset of
its data, including the calling application's own tasks and possibly some other
non-sensitive tasks (such as Home). If your app is using this method to retrieve
its own tasks, use [getAppTasks()](https://developer.android.com/reference/android/app/ActivityManager#getAppTasks())
instead to retrieve that information.

## 64-Bit Support in the Android NDK

Android 5.0 introduces support for 64-bit systems. The 64-bit enhancement
increases address space and improves performance, while still supporting
existing 32-bit apps fully. The 64-bit support also improves the performance of
OpenSSL for cryptography. In addition, this release introduces new native
media NDK APIs, as well as native OpenGL ES (GLES) 3.1 support.

To use the 64-bit support provided in Android 5.0, download and install NDK
Revision 10c from the
[Android NDK page](https://developer.android.com/tools/sdk/ndk). Refer to the
Revision 10c [release notes](https://developer.android.com/tools/sdk/ndk#Revisions)
for more information about important changes and bug fixes to the NDK.

## Binding to a Service

The
[Context.bindService()](https://developer.android.com/reference/android/content/Context#bindService(android.content.Intent, android.content.ServiceConnection, int))
method now requires an explicit [Intent](https://developer.android.com/reference/android/content/Intent),
and throws an exception if given an implicit intent.
To ensure your app is secure, use an explicit intent when starting or binding
your [Service](https://developer.android.com/reference/android/app/Service), and do not declare intent filters for the service.

## WebView

Android 5.0 changes the default behavior for your app.

- **If your app targets API level 21 or higher:**
  - The system blocks [mixed content](https://developer.mozilla.org/en-US/docs/Security/MixedContent) and third party cookies by default. To allow mixed content and third party cookies, use the [setMixedContentMode()](https://developer.android.com/reference/android/webkit/WebSettings#setMixedContentMode(int)) and [setAcceptThirdPartyCookies()](https://developer.android.com/reference/android/webkit/CookieManager#setAcceptThirdPartyCookies(android.webkit.WebView, boolean)) methods respectively.
  - The system now intelligently chooses portions of the HTML document to draw. This new default behavior helps to reduce memory footprint and increase performance. If you want to render the whole document at once, disable this optimization by calling [enableSlowWholeDocumentDraw()](https://developer.android.com/reference/android/webkit/WebView#enableSlowWholeDocumentDraw()).
- **If your app targets API levels lower than 21:** The system allows mixed content and third party cookies, and always renders the whole document at once.

## Uniqueness Requirement for Custom Permissions


As documented in the [Permissions](https://developer.android.com/guide/topics/manifest/manifest-intro#perms)
overview, Android apps can define custom permissions as a means of managing
access to components in a proprietary way, without using the platform's
pre-defined system permissions. Apps define custom permissions in [`
<permission>`](https://developer.android.com/guide/topics/manifest/permission-element.html) elements declared in their manifest files.


There are a small number of scenarios where defining custom permissions is a
legitimate and secure approach. However, creating custom permissions is
sometimes unnecessary and can even introduce potential risk to an app,
depending on the protection level assigned to the permissions.


Android 5.0 includes a behavior change to ensure
that only one app can define a given custom permission, unless signed with the
same key as other apps defining the permission.

### Apps using duplicate custom permissions


Any app can define any custom permission it wants, so it can happen
that multiple apps might **define the same custom permission**.
For example, if two apps offer a similar capability, they might derive the
same logical name for their custom permissions. Apps might also incorporate
common public libraries or code examples that themselves include the same
custom permission definitions.


In Android 4.4 and earlier, users were able to install multiple such
apps on a given device, although the system assigned the protection level
specified by the first-installed app.


Starting in Android 5.0, the system enforces a new
**uniqueness restriction on custom permissions** for
apps that are signed with different keys. Now only one app on a device can
define a given custom permission (as determined by its name), unless the
other app defining the permission is signed with the same key. If the user
tries to install an app with a duplicate custom permission and is not signed
with the same key as the resident app that defines the permission, the system
blocks the installation.

### Considerations for your app


In Android 5.0 and later, apps can continue to define their own custom
permissions just as before and to request custom permissions from other apps
through the `<uses-permission>` mechanism. However with the
new requirement introduced in Android 5.0, you should carefully assess
possible impacts on your app.


Here are some points to consider:

- Does your app declare any [`<permission>`](https://developer.android.com/guide/topics/manifest/permission-element.html) elements in its manifest? If so, are they actually necessary to the proper function of your app or service? Or could you use a system default permission instead?
- If you have [`<permission>`](https://developer.android.com/guide/topics/manifest/permission-element.html) elements in your app, do you know where they came from?
- Do you actually intend for other apps to request your custom permissions through [`<uses-permission>`](https://developer.android.com/guide/topics/manifest/uses-permission-element.html)?
- Are you using boilerplate or example code in your app that includes [`<permission>`](https://developer.android.com/guide/topics/manifest/permission-element.html) elements? Are those permission elements actually necessary?
- Do your custom permissions use names that are simple or based on common terms that other apps might share?

### New installs and updates


As mentioned above, for new installs and updates of your app on devices
running Android 4.4 or earlier are unaffected and there is no change in
behavior. For new installs and updates on devices running Android 5.0 or
later, the system **prevents installation of your app** if it
defines a custom permission that is already defined by an existing resident
app.

### Existing installs with Android 5.0 system update


If your app uses custom permissions and is widely distributed and installed,
there's a chance that it will be affected when users receive update their
devices to Android 5.0. After the system update is installed, the system
revalidates installed apps, including a check of their custom permissions. If
your app defines a custom permission that is already defined by another app
that has already been validated, and your app is not signed with the same key
as the other app, the system **does not re-install your app**.

### Recommendations


On devices running Android 5.0 or later, we recommend that you examine your
app immediately, make any adjustments needed, and publish the updated version
as soon as possible to your users.

- If you are using custom permissions in your app, consider their origin and whether you actually need them. Remove all [`<permission>`](https://developer.android.com/guide/topics/manifest/permission-element.html) elements from your app, unless you are certain that they are required for proper function of your app.
- Consider replacing your custom permissions with system default permissions where possible.
- If your app requires custom permissions, rename your custom permissions to be unique to your app, such as by appending them to the full package name of your app.
- If you have a suite of apps *signed with different keys* and the apps access a shared component by means of a custom permission, make sure that the custom permission is only defined once, in the shared component. Apps that use the shared component should not define the custom permission themselves, but should instead request access through the [`<uses-permission>`](https://developer.android.com/guide/topics/manifest/uses-permission-element) mechanism.
- If you have a suite of apps are *signed with the same key* , each app can define the same custom permission(s) as needed --- the system allows the apps to be installed in the usual way.

## TLS/SSL Default Configuration Changes


Android 5.0 introduces changes the default TLS/SSL configuration used by apps
for HTTPS and other TLS/SSL traffic:

- TLSv1.2 and TLSv1.1 protocols are now enabled,
- AES-GCM (AEAD) cipher suites are now enabled,
- MD5, 3DES, export, and static key ECDH cipher suites are now disabled,
- Forward Secrecy cipher suites (ECDHE and DHE) are preferred.


These changes may lead to breakages in HTTPS or TLS/SSL connectivity in a
small number of cases listed below.


Note that the security ProviderInstaller from Google Play services already
offers these changes across Android platform versions back to Android 2.3.

### Server does not support any of the enabled ciphers suites


For example, a server might support only 3DES or MD5 cipher suites. The
preferred fix is to improve the server's configuration to enable stronger and
more modern cipher suites and protocols. Ideally, TLSv1.2 and AES-GCM should
be enabled, and Forward Secrecy cipher suites (ECDHE, DHE) should be enabled
and preferred.


An alternative is to modify the app to use a custom SSLSocketFactory to
communicate with the server. The factory should be designed to create
SSLSocket instances which have some of the cipher suites required by the
server enabled in addition to default cipher suites.

### App is making wrong assumptions about cipher suites used to connect to server


For example, some apps contain a custom X509TrustManager that breaks because
it expects the authType parameter to be RSA but encounters ECDHE_RSA or
DHE_RSA.

### Server is intolerant to TLSv1.1, TLSv1.2 or new TLS extensions


For example, the TLS/SSL handshake with a server is erroneously rejected or
stalls. The preferred fix is to upgrade the server to comply with the TLS/SSL
protocol. This will make the server successfully negotiate these newer
protocols or negotiate TLSv1 or older protocols and ignore TLS extensions it
does not understand. In some cases disabling TLSv1.1 and TLSv1.2 on the
server may work as a stopgap measure until the server software is upgraded.


An alternative is to modify the app to use a custom SSLSocketFactory to
communicate with the server. The factory should be designed to create
SSLSocket instances with only those protocols enabled which are correctly
supported by the server.

## Support for Managed Profiles


Device administrators can add a *managed profile* to a device. This
profile is owned by the administrator, giving the administrator control
over the managed profile while leaving the user's personal profile, and its
storage space, under the user's control.
This change can affect the behavior of your existing app in
the following ways.

### Handling intents

Device administrators can restrict access to system applications from the
managed profile. In this case, if an app fires an intent from the managed
profile that would ordinarily be handled by that application, and there is no
suitable handler for the intent on the managed profile,
the intent causes an exception. For example, the
device administrator can restrict apps on the managed profile from accessing
the system's camera application. If your app is running on the managed profile
and calls [startActivityForResult()](https://developer.android.com/reference/android/app/Activity#startActivityForResult(android.content.Intent, int)) for [MediaStore.ACTION_IMAGE_CAPTURE](https://developer.android.com/reference/android/provider/MediaStore#ACTION_IMAGE_CAPTURE), and there is no app on the managed profile
that can handle the intent, this results in an [ActivityNotFoundException](https://developer.android.com/reference/android/content/ActivityNotFoundException).

You can prevent this by checking
that there is at least one handler for any intent
before firing it. To check for a valid handler, call [Intent.resolveActivity()](https://developer.android.com/reference/android/content/Intent#resolveActivity(android.content.pm.PackageManager)). You can see
an example of this being done in [Take Photos
Simply: Take a Photo with the Camera App](https://developer.android.com/training/camera/photobasics#TaskCaptureIntent).

### Sharing files across profiles

Each profile has its own file storage. Since a file URI refers to a specific
location in the file storage, this means that a file URI that is valid on one
profile is not valid on the other one. This is not ordinarily a problem for an
app, which usually just accesses the files it creates. However, if an app
attaches a file to an intent, it is not safe to attach a file URI, since in some
circumstances, the intent might be handled on the other profile.
For example, a device administrator might specify that image capture events
should be handled by the camera app on the personal profile. If the intent is
fired by an app on the managed profile, the camera needs to be able to write the
image to a location where the managed profile's apps can read it.

To be safe, when
you need to attach a file to an intent that might cross from one profile to the
other, you should create and use a *content URI* for the file. For more
information about sharing files with content URIs, see [Sharing Files](https://developer.android.com/training/secure-file-sharing).
For example, the device administrator might allow [ACTION_IMAGE_CAPTURE](https://developer.android.com/reference/android/provider/MediaStore#ACTION_IMAGE_CAPTURE) to be
handled by the camera in the personal profile. The firing intent's [EXTRA_OUTPUT](https://developer.android.com/reference/android/provider/MediaStore#EXTRA_OUTPUT) should contain a content
URI specifying where the photo should be stored. The camera app can write the
image to the location specified by that URI, and the app that fired the intent
would be able to read that file, even if the app is on the other profile.

### Lockscreen widget support removed

Android 5.0 removes support for lockscreen widgets; it continues to support
widgets on the home screen.