API Level: 16
Android 4.1 (
JELLY_BEAN
) is a progression of the platform that offers improved performance and enhanced user experience. It adds new features for users and app developers. This document provides an introduction to the most notable and useful new APIs for app developers.
Declare your app API Level
To better optimize your app for devices running Android 4.1, you should set your
targetSdkVersion
to
"16"
, install it on an Android 4.1 system image, test it, then publish an update with this change.
You can use APIs in Android 4.1 while also supporting older versions by adding conditions to your code that check for the system API level before executing APIs not supported by your
minSdkVersion
. To learn more about maintaining backward-compatibility, read
Creating Backward-Compatible UIs.
As an app developer, Android 4.1 is available to you from the
SDK Manager as a system image you can run in the Android emulator and an SDK platform against which you can build your app. You should download the system image and platform as soon as possible to build and test your app on Android 4.1.
App Components
Isolated services
Memory management
Content providers
Live Wallpapers
New intent protocol to directly launch the live wallpaper preview activity so you can help users easily select your live wallpaper without forcing them to leave your app and navigate through the Home wallpaper picker.
App stack navigation
Android 4.1 makes it much easier to implement the proper design patterns for Up navigation. All you need to do is add the
android:parentActivityName
to each
<activity>
element in your manifest file. The system uses this information to open the appropriate activity when the user presses the Up button in the action bar (while also finishing the current activity). So if you declare the
android:parentActivityName
for each activity, you don't need the
onOptionsItemSelected()
method to handle click events on the action bar's app icon—the system now handles that event and resumes or creates the appropriate activity.
This is particularly powerful for scenarios in which the user enters one of your app's activities through a "deep dive" intent such as from a notification or an intent from different app (as described in the design guide for
Navigating Between Apps). When the user enters your activity this way, your app may not naturally have a back stack of activities that can be resumed as the user navigates up. However, when you supply the
android:parentActivityName
attribute for your activities, the system recognizes whether or not your app already contains a back stack of parent activities and, if not, constructs a synthetic back stack that contains all parent activities.
Note: When the user enters a deep activity in your app and it creates a new task for your app, the system actually inserts the stack of parent activities into the task. As such, pressing the Back button also navigates back through the stack of parent activities.
When the system creates a synthetic back stack for your app, it builds a basic
Intent
to create a new instance of each parent activity. So there's no saved state for the parent activities the way you'd expect had the user naturally navigated through each activity. If any of the parent activities normally show a UI that's dependent on the user's context, that context information will be missing and you should deliver it when the user navigates back through the stack. For example, if the user is viewing an album in a music app, navigating up might bring them to an activity that lists all albums in a chosen music genre. In this case, if the stack must be created, it's necessary that you inform the parent activity what genre the current album belongs to so that the parent can display the proper list as if the user actually came from that activity. To deliver such information to a synthetic parent activity, you must override the
onPrepareNavigateUpTaskStack()
method. This provides you with a
TaskStackBuilder
object that the system created in order to synthesize the parent activities. The
TaskStackBuilder
contains
Intent
objects that the system uses to create each parent activity. In your implementation of
onPrepareNavigateUpTaskStack()
, you can modify the appropriate
Intent
to add extra data that the parent activity can use to determine the appropriate context and display the appropriate UI.
When the system creates the
TaskStackBuilder
, it adds the
Intent
objects that are used to create the parent activities in their logical order beginning from the top of the activity tree. So, the last
Intent
added to the internal array is the direct parent of the current activity. If you want to modify the
Intent
for the activity's parent, first determine the length of the array with
getIntentCount()
and pass that value to
editIntentAt()
.
If your app structure is more complex, there are several other APIs available that allow you to handle the behavior of Up navigation and fully customize the synthetic back stack. Some of the APIs that give you additional control include:
onNavigateUp()
- Override this to perform a custom action when the user presses the Up button.
navigateUpTo(Intent)
- Call this to finish the current activity and go to the activity indicated by the supplied
Intent
. If the activity exists in the back stack, but is not the closest parent, then all other activities between the current activity and the activity specified with the intent are finished as well.
getParentActivityIntent()
- Call this to get the
Intent
that will start the logical parent for the current activity.
shouldUpRecreateTask(Intent)
- Call this to query whether a synthetic back stack must be created in order to navigate up. Returns true if a synthetic stack must be created, false if the appropropriate stack already exists.
finishAffinity()
- Call this to finish the current activity and all parent activities with the same task affinity that are chained to the current activity. If you override the default behaviors such as
onNavigateUp()
, you should call this method when you create a synthetic back stack upon Up navigation.
onCreateNavigateUpTaskStack
- Override this if you need to fully control how the synthetic task stack is created. If you want to simply add some extra data to the intents for your back stack, you should instead override
onPrepareNavigateUpTaskStack()
Media codecs
The
MediaCodec
class provides access to low-level media codecs for encoding and decoding your media. You can instantiate a
MediaCodec
by calling
createEncoderByType()
to encode media or call
createDecoderByType()
to decode media. Each of these methods take a MIME type for the type of media you want to encode or decode, such as
"video/3gpp"
or
"audio/vorbis"
.
With an instance of
MediaCodec
created, you can then call
configure()
to specify properties such as the media format or whether or not the content is encrypted.
When you're ready to encode or decode, call
dequeueInputBuffer()
to get the index position of the
ByteBuffer
(from the array of input buffers) that you should use to to feed in your source media. After you fill the
ByteBuffer
with your source media, release ownership of the buffer by calling
queueInputBuffer()
.
For more information about how to use codecs, see the
MediaCodec
documentation.
Record audio on cue
New method
startRecording()
allows you to begin audio recording based on a cue defined by a
MediaSyncEvent
. The
MediaSyncEvent
specifies an audio session (such as one defined by
MediaPlayer
), which when complete, triggers the audio recorder to begin recording. For example, you can use this functionality to play an audio tone that indicates the beginning of a recording session and recording automatically begins so you don't have to manually synchronize the tone and the beginning of recording.
Timed text tracks
The
MediaPlayer
now handles both in-band and out-of-band text tracks. In-band text tracks come as a text track within an MP4 or 3GPP media source. Out-of-band text tracks can be added as an external text source via
addTimedTextSource()
method. After all external text track sources are added,
getTrackInfo()
should be called to get the refreshed list of all available tracks in a data source.
To set the track to use with the
MediaPlayer
, you must call
selectTrack()
, using the index position for the track you want to use.
Audio effects
The
AudioEffect
class now supports additional audio pre-processing types when capturing audio:
- Acoustic Echo Canceler (AEC) with
AcousticEchoCanceler
removes the contribution of the signal received from the remote party from the captured audio signal.
- Automatic Gain Control (AGC) with
AutomaticGainControl
automatically normalizes the output of the captured signal.
- Noise Suppressor (NS) with
NoiseSuppressor
removes background noise from the captured signal.
You can apply these pre-processor effects on audio captured with an
AudioRecord
using one of the
AudioEffect
subclasses.
Note: It's not guaranteed that all devices support these effects, so you should always first check availability by calling
isAvailable()
on the corresponding audio effect class.
Gapless playback
You can now perform gapless playback between two separate
MediaPlayer
objects. At any time before your first
MediaPlayer
finishes, call
setNextMediaPlayer()
and Android attempts to start the second player the moment that the first one stops.
Media router. The new APIs MediaRouter, MediaRouteActionProvider, and MediaRouteButton provide standard mechanisms and UI for choosing where to play media.
Camera
Auto focus movement
Camera sounds
The
MediaActionSound
class provides a simple set of APIs to produce standard sounds made by the camera or other media actions. You should use these APIs to play the appropriate sound when building a custom still or video camera.
To play a sound, simply instantiate a
MediaActionSound
object, call
load()
to pre-load the desired sound, then at the appropriate time, call
play()
.
Connectivity
Android Beam
Android Beam™ now supports large payload transfers over Bluetooth. When you define the data to transfer with either the new
setBeamPushUris()
method or the new callback interface
NfcAdapter.CreateBeamUrisCallback
, Android hands off the data transfer to Bluetooth or another alternate transport to achieve faster transfer speeds. This is especially useful for large payloads such as image and audio files and requires no visible pairing between the devices. No additional work is required by your app to take advantage of transfers over Bluetooth.
When using the callback interface, the system calls the interface's
createBeamUris()
method when the user executes a share with Android Beam so that you can define the URIs to share at share-time. This is useful if the URIs to share might vary depending on the user context within the activity, whereas calling
setBeamPushUris()
is useful when the URIs to share are unchanging and you can safely define them ahead of time.
Network service discovery
Android 4.1 adds support for multicast DNS-based service discovery, which allows you to find and connect to services offered by peer devices over Wi-Fi, such as mobile devices, printers, cameras, media players, and others that are registered on the local network.
The new package
android.net.nsd
contains the new APIs that allow you to broadcast your services on the local network, discover local devices on the network, and connect to devices.
Wi-Fi P2P service discovery
The Wi-Fi P2P APIs are enhanced in Android 4.1 to support pre-association service discovery in the
WifiP2pManager
. This allows you to discover and filter nearby devices by services using Wi-Fi P2P before connecting to one, while Network Service Discovery allows you to discover a service on an existing connected network (such as a local Wi-Fi network).
To broadcast your app as a service over Wi-Fi so that other devices can discover your app and connect to it, call
addLocalService()
with a
WifiP2pServiceInfo
object that describes your app services.
Network usage
The new method
isActiveNetworkMetered()
allows you to check whether the device is currently connected to a metered network. By checking this state before performing intensive network transactions, you can help manage the data usage that may cost your users money and make informed decisions about whether to perform the transactions now or later (such as when the device becomes connected to Wi-Fi).
Accessibility
Accessibility service APIs
Accessibility services can also perform actions on behalf of the user, including clicking, scrolling and stepping through text using
performAction
and
setMovementGranularities
. The
performGlobalAction()
method also allows services to perform actions such as Back, Home, and open Recent Apps and Notifications.
Customizable app navigation
More accessible widgets
The new android.view.accessibility.AccessibilityNodeProvider
class allows you to surface complex custom views to accessibility services so they can present the information in a more accessible way. Theandroid.view.accessibility.AccessibilityNodeProvider
allows a user widget with advanced content, such as a calendar grid, to present a logical semantic structure for accessibility services that is completely separate from the widget’s layout structure. This semantic structure allows accessibility services to present a more useful interaction model for users who are visually impaired.
Copy and Paste
Copy and paste with intents
You can now associate a
ClipData
object with an
Intent
using the
setClipData()
method. This is especially useful when using an intent to transfer multiple
content:
URIs to another application, such as when sharing multiple documents. The
content:
URIs supplied this way will also respect the intent's flags to offer read or write access, allowing you to grant access to multiple URIs in an the intent. When starting an
ACTION_SEND
or
ACTION_SEND_MULTIPLE
intent, the URIs supplied in the intent are now automatically propagated to the
ClipData
so that the receiver can have access granted to them.
Support for HTML and string styles
Renderscript
Renderscript computation functionality has been enhanced with the following features:
- Support for multiple kernels within one script.
- Support for reading from allocation with filtered samplers from compute in a new script API
rsSample
.
- Support for different levels of FP precision in
#pragma
.
- Support for querying additional information from RS objects from a compute script.
- Numerous performance improvements.
New pragmas are also available to define the floating point precision required by your compute Renderscripts. This lets you enable NEON like operations such as fast vector math operations on the CPU path that wouldn’t otherwise be possible with full IEEE 754-2008 standard.
Note: The experimental Renderscript graphics engine is now deprecated.
Animation
Activity launch animations
You can now launch an
Activity
using zoom animations or your own custom animations. To specify the animation you want, use the
ActivityOptions
APIs to build a
Bundle
that you can then pass to any of the methods that start an activity, such as
startActivity()
.
The
ActivityOptions
class includes a different method for each type of animation you may want to show as your activity opens:
makeScaleUpAnimation()
- Creates an animation that scales up the activity window from a specified starting position on the screen and a specified starting size. For example, the home screen in Android 4.1 uses this when opening an app.
makeThumbnailScaleUpAnimation()
- Creates an animation that scales up the activity window starting from a specified position and a provided thumbnail image. For example, the Recent Apps window in Android 4.1 uses this when returning to an app.
makeCustomAnimation()
- Creates an animation defined by your own resources: one that defines the animation for the activity opening and another for the activity being stopped.
Time animator
The new
TimeAnimator
provides a simple callback mechanism with the
TimeAnimator.TimeListener
that notifies you upon every frame of the animation. There is no duration, interpolation, or object value-setting with this Animator. The listener's callback receives information for each frame including total elapsed time and the elapsed time since the previous animation frame.
User Interface
Notifications
In Android 4.1, you can create notifications with larger content regions, big image previews, multiple action buttons, and configurable priority.
Notification styles
The new method
setStyle()
allows you to specify one of three new styles for your notification that each offer a larger content region. To specify the style for your large content region, pass
setStyle()
one of the following objects:
Notification.BigPictureStyle
- For notifications that includes a large image attachment.
Notification.BigTextStyle
- For notifications that includes a lot of text, such as a single email.
Notification.InboxStyle
- For notifications that include a list of strings, such as snippets from multiple emails.
Notification actions
There's now support for up to two action buttons that appear at the bottom of the notification message, whether your notification uses the normal or larger style.
To add an action button, call
addAction()
. This method takes three arguments: a drawable resource for an icon, text for the button, and a
PendingIntent
that defines the action to perfrom.
Priorities
You can now hint to the system how important your notification is to affect the order of your notification in the list by setting the priority with
setPriority()
. You can pass this one of five different priority levels defined by
PRIORITY_*
constants in the
Notification
class. The default is
PRIORITY_DEFAULT
, and there's two levels higher and two levels lower.
High priority notifications are things that users generally want to respond to quickly, such as a new instant message, text message, or impending event reminder. Low priority notifications are things like expired calendar events or app promotions.
Controls for system UI
Android 4.0 (Ice Cream Sandwich) added new flags to control the visibility of the system UI elements, such as to dim the appearance of the system bar or make it disappear completely on handsets. Android 4.1 adds a few more flags that allow you to further control the appearance of system UI elements and your activity layout in relation to them by calling
setSystemUiVisibility()
and passing the following flags:
SYSTEM_UI_FLAG_FULLSCREEN
- Hides non-critical system UI (such as the status bar). If your activity uses the action bar in overlay mode (by enabling
android:windowActionBarOverlay
), then this flag also hides the action bar and does so with a coordinated animation when both hiding and showing the two.
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- Sets your activity layout to use the same screen area that's available when you've enabled
SYSTEM_UI_FLAG_FULLSCREEN
even if the system UI elements are still visible. Although parts of your layout will be overlayed by the system UI, this is useful if your app often hides and shows the system UI withSYSTEM_UI_FLAG_FULLSCREEN
, because it avoids your layout from adjusting to the new layout bounds each time the system UI hides or appears.
SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- Sets your activity layout to use the same screen area that's available when you've enabled
SYSTEM_UI_FLAG_HIDE_NAVIGATION
(added in Android 4.0) even if the system UI elements are still visible. Although parts of your layout will be overlayed by the navigation bar, this is useful if your app often hides and shows the navigation bar with SYSTEM_UI_FLAG_HIDE_NAVIGATION
, because it avoids your layout from adjusting to the new layout bounds each time the navigation bar hides or appears.
SYSTEM_UI_FLAG_LAYOUT_STABLE
- You might want to add this flag if you're using
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
and/orSYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
to ensure that when you call fitSystemWindows()
on a view that the bounds defined remain consistent with regard to the available screen space. That is, with this flag set,fitSystemWindows()
will behave as if the visibility of system UI elements is unchanged even after you hide all system UI.
For more discussion about the other related system UI flags, read about those added in
Android 4.0.
Remote views
GridLayout
and
ViewStub
are now remotable views so you can use them in layouts for your app widgets and notification custom layouts.
Font families
Android 4.1 adds several more variants of the Roboto font style for a total of 10 variants, and they're all usable by apps. Your apps now have access to the full set of both light and condensed variants.
The complete set of Roboto font variants available is:
- Regular
- Italic
- Bold
- Bold-italic
- Light
- Light-italic
- Condensed regular
- Condensed italic
- Condensed bold
- Condensed bold-italic
You can apply any one of these with the new
fontFamily
attribute in combination with the
textStyle
attribute.
"sans-serif"
for regular Roboto
"sans-serif-light"
for Roboto Light
"sans-serif-condensed"
for Roboto Condensed
You can then apply bold and/or italic with
textStyle
values
"bold"
and
"italic"
. You can apply both like so:
android:textStyle="bold|italic"
.
You can also use
Typeface.create()
. For example,
Typeface.create("sans-serif-light", Typeface.NORMAL)
.
The new
InputManager
class allows you to query the set of input devices current connected and register to be notified when a new device is added, changed, or removed. This is particularly useful if you're building a game that supports multiple players and you want to detect how many controllers are connected and when there are changes to the number of controllers.
You can query all input devices connected by calling
getInputDeviceIds()
. This returns an array of integers, each of which is an ID for a different input device. You can then call
getInputDevice()
to acquire an
InputDevice
for a specified input device ID.
Vibrate for input controllers
If connected input devices have their own vibrate capabilities, you can now control the vibration of those devices using the existing
Vibrator
APIs simply by calling
getVibrator()
on the
InputDevice
.
Permissions
The following are new permissions:
READ_EXTERNAL_STORAGE
- Provides protected read access to external storage. In Android 4.1 by default all applications still have read access. This will be changed in a future release to require that applications explicitly request read access using this permission. If your application already requests write access, it will automatically get read access as well. There is a new developer option to turn on read access restriction, for developers to test their applications against how Android will behave in the future.
- android.Manifest.permission.READ_USER_DICTIONARY
- Allows an application to read the user dictionary. This should only be required by an IME, or a dictionary editor like the Settings app.
READ_CALL_LOG
- Allows an application to read the system's call log that contains information about incoming and outgoing calls.
WRITE_CALL_LOG
- Allows an application to modify the system's call log stored on your phone
- android.Manifest.permission.WRITE_USER_DICTIONARY
- Allows an application to write to the user's word dictionary.
Device Features
Android 4.1 includes a new feature declaration for devices that are dedicated to displaying the user interface on a television screen:
FEATURE_TELEVISION
. To declare that your app requires a television interface, declare this feature in your manifest file with the
<uses-feature>
element:
<manifest ... >
<uses-feature android:name="android.hardware.type.television"
android:required="true" />
...</manifest>
This feature defines "television" to be a typical living room television experience: displayed on a big screen, where the user is sitting far away and the dominant form of input is be something like a d-pad, and generally not through touch or a mouse/pointer-device.