API Level: 16
Android 4.1 (
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.
To better optimize your app for devices running Android 4.1,
you should set your
"16", install it on an Android 4.1 system image,
test it, then publish an update with this change.
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
To learn more about
maintaining backward-compatibility, read Creating Backward-Compatible
More information about how API levels work is available in What is API Level?
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.
ComponentCallbacks2 constants such as
TRIM_MEMORY_RUNNING_CRITICAL provide foreground
processes more information about
memory state before the system calls
getMyMemoryState(ActivityManager.RunningAppProcessInfo) method allows you to
retrieve the general memory state.
A new method,
acquireUnstableContentProviderClient(), allows you to access a
ContentProviderClient that may be "unstable" such that your app will not crash if
the content provider does. It's useful when you are interacting with content providers in a separate
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.
To launch the live wallpaper picker, call
startActivity() with an
ACTION_CHANGE_LIVE_WALLPAPER and an extra
that specifies your live wallpaper
ComponentName as a string in
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
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
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
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
Intent objects that the system uses to create each parent activity. In your
onPrepareNavigateUpTaskStack(), you can modify the appropriate
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
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:
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.
Intentthat will start the logical parent for the current activity.
onNavigateUp(), you should call this method when you create a synthetic back stack upon Up navigation.
However, most apps don't need to use these APIs or implement
onPrepareNavigateUpTaskStack(), but can can achieve the correct behavior simply by
android:parentActivityName to each
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
Whether you're encoding or decoding your media, the rest of the process is the same after you
MediaCodec. First call
getInputBuffers() to get an array of input
getOutputBuffers() to get an array of output
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
Likewise for the output buffer, call
dequeueOutputBuffer() to get the index position of the
where you'll receive the results. After you read the output from the
release ownership by calling
For more information about how to use codecs, see the
you to begin audio recording based on a cue defined by a
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
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.
AudioEffect class now supports additional audio
pre-processing types when capturing audio:
AcousticEchoCancelerremoves the contribution of the signal received from the remote party from the captured audio signal.
AutomaticGainControlautomatically normalizes the output of the captured signal.
NoiseSuppressorremoves background noise from the captured signal.
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.
You can now perform gapless playback between two separate
MediaPlayer objects. At any time before your first
setNextMediaPlayer() and Android
attempts to start the second player the moment that the first one stops.
The new interface
Camera.AutoFocusMoveCallback allows you to listen
for changes to the auto focus movement. You can register your interface with
setAutoFocusMoveCallback(). Then when the camera
is in a continuous autofocus mode (
FOCUS_MODE_CONTINUOUS_PICTURE), you'll receive a call
which tells you whether auto focus has started moving or has stopped moving.
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.
Android Beam™ now supports large payload transfers over Bluetooth. When you define the data
to transfer with either the new
method or the new callback interface
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.
setBeamPushUris() method takes an array of
Uri objects that specify the data you want to transfer from your app.
Alternatively, you can implement the
interface, which you can specify for your activity by calling
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
useful when the URIs to share are unchanging and you can safely define them ahead of time.
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.
NsdManager.DiscoveryListener receives callbacks about services
found, you need to resolve the service by calling
resolveService(), passing it an
NsdManager.ResolveListener that receives
NsdServiceInfo object that contains information about the
discovered service, allowing you to initiate the connection.
The Wi-Fi P2P APIs are enhanced in Android 4.1 to support pre-association service discovery in
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
To initiate discover of nearby devices over Wi-Fi, you need to first decide whether you'll
communicate using Bonjour or Upnp. To use Bonjour, first set up some callback listeners with
setDnsSdResponseListeners(), which takes both a
WifiP2pManager.DnsSdTxtRecordListener. To use Upnp, call
setUpnpServiceResponseListener(), which takes a
Before you can start discovering services on local devices, you also need to call
addServiceRequest(). When the
WifiP2pManager.ActionListener you pass to this method receives a
successful callback, you can then begin discovering services on local devices by calling
When local services are discovered, you'll receive a callback to either the
WifiP2pManager.UpnpServiceResponseListener, depending on whether you
registered to use Bonjour or Upnp. The callback received in either case contains a
WifiP2pDevice object representing the peer device.
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).
The reach of accessibility service APIs has been significantly increased in Android 4.1. It now
allows you to build services that monitor and respond to more input events, such as complex gestures
onGesture() and other
input events through additions to the
Accessibility services can also perform actions on behalf of the user, including clicking,
scrolling and stepping through text using
also allows services to perform actions such as Back, Home, and open Recent
Apps and Notifications.
When building an Android app, you can now customize navigation schemes by finding focusable
elements and input widgets using
focusSearch(), and set focus
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. The
android.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
You can now associate a
ClipData object with an
Intent using the
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_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.
Renderscript computation functionality has been enhanced with the following features:
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.
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
ActivityOptions class includes a different method for each
type of animation you may want to show as your activity opens:
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.
In Android 4.1, you can create notifications with larger content regions, big image previews, multiple action buttons, and configurable priority.
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:
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.
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
can pass this one of five different priority levels defined by
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.
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
and passing the following flags:
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_FULLSCREENeven 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 with
SYSTEM_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_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_HIDE_NAVIGATIONto 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.
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:
Supported values for
"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
"italic". You can apply both like so:
You can also use
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
InputDevice for a specified input device ID.
The following are new permissions:
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
<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.