Docs: Early fixes to pages and infrastructure files for N Developer Preview 1
Updating TOC, adjusting page names...that sort of thing. Change-Id: I1a6cf66291344e5c210f287c1d38c65d621cfe91
This commit is contained in:
@@ -4,565 +4,8 @@ page.tags="preview", "developer preview"
|
||||
page.image=images/cards/card-n-overview_2x.png
|
||||
@jd:body
|
||||
|
||||
|
||||
<div id="qv-wrapper">
|
||||
<div id="qv">
|
||||
|
||||
<h2>In this document
|
||||
<a href="#" onclick="hideNestedItems('#toc44',this);return false;" class="header-toggle">
|
||||
<span class="more">show more</span>
|
||||
<span class="less" style="display:none">show less</span></a></h2>
|
||||
|
||||
<ol id="toc44" class="hide-nested">
|
||||
<li><a href="#app-linking">App Linking</a></li>
|
||||
<li><a href="#backup">Auto Backup for Apps</a></li>
|
||||
<li><a href="#authentication">Authentication</a>
|
||||
<ol>
|
||||
<li><a href="#fingerprint-authentication">Fingerprint Authentication</a></li>
|
||||
<li><a href="#confirm-credential">Confirm Credential</a></li>
|
||||
</ol>
|
||||
</li>
|
||||
<li><a href="#direct-share">Direct Share</a></li>
|
||||
<li><a href="#voice-interactions">Voice Interactions</a></li>
|
||||
<li><a href="#assist">Assist API</a></li>
|
||||
<li><a href="#notifications">Notifications</a></li>
|
||||
<li><a href="#bluetooth-stylus">Bluetooth Stylus Support</a></li>
|
||||
<li><a href="#ble-scanning">Improved Bluetooth Low Energy Scanning</a></li>
|
||||
<li><a href="#hotspot">Hotspot 2.0 Release 1 Support</a></li>
|
||||
<li><a href="#4K-display">4K Display Mode</a></li>
|
||||
<li><a href="#behavior-themeable-colorstatelists">Themeable ColorStateLists</a></li>
|
||||
<li><a href="#audio">Audio Features</a></li>
|
||||
<li><a href="#video">Video Features</a></li>
|
||||
<li><a href="#camera">Camera Features</a>
|
||||
<ol>
|
||||
<li><a href="#flashlight">Flashlight API</a></li>
|
||||
<li><a href="#reprocessing">Camera Reprocessing</a></li>
|
||||
</ol>
|
||||
</li>
|
||||
<li><a href="#afw">Android for Work Features</a></li>
|
||||
</ol>
|
||||
|
||||
<h2>API Differences</h2>
|
||||
<ol>
|
||||
<li><a href="{@docRoot}sdk/api_diff/23/changes.html">API level 22 to 23 (Preview 3) »</a> </li>
|
||||
</ol>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>The M Developer Preview gives you an advance look at the upcoming release
|
||||
for the Android platform, which offers new features for users and app
|
||||
developers. This document provides an introduction to the most notable APIs.</p>
|
||||
|
||||
<p>
|
||||
The M Developer Preview 3 release includes the <strong>final APIs for Android 6.0 (API level
|
||||
23)</strong>. If you are preparing an app for use on Android 6.0,
|
||||
<a href="{@docRoot}preview/setup-sdk.html">download the latest SDK</a> and to complete your
|
||||
final updates and release testing. You can review the final APIs in the
|
||||
<a href="{@docRoot}reference/packages.html">API Reference</a> and see the API differences in
|
||||
the <a href="{@docRoot}sdk/api_diff/23/changes.html">Android API Differences Report</a>.
|
||||
</p>
|
||||
|
||||
</p>
|
||||
|
||||
<p class="caution"><strong>Important:</strong>
|
||||
You may now publish apps that target Android 6.0 (API level 23) to the Google Play store.
|
||||
</p>
|
||||
|
||||
<p class="note"><strong>Note:</strong>
|
||||
If you have been working with previous preview releases and want to see the differences
|
||||
between the final API and previous preview versions, download the additional difference
|
||||
reports included in the <a href="{@docRoot}preview/download.html#docs">preview docs
|
||||
reference</a>.
|
||||
</p>
|
||||
|
||||
<h3>Important behavior changes</h3>
|
||||
|
||||
<p>If you have previously published an app for Android, be aware that your app might be affected
|
||||
by changes in the platform.</p>
|
||||
|
||||
<p>Please see <a href="behavior-changes.html">Behavior Changes</a> for complete information.</p>
|
||||
|
||||
<h2 id="app-linking">App Linking</h2>
|
||||
<p>This preview enhances Android’s intent system by providing more powerful app linking.
|
||||
This feature allows you to associate an app with a web domain you own. Based on this
|
||||
association, the platform can determine the default app to use to handle a particular
|
||||
web link and skip prompting users to select an app. To learn how to implement this feature, see
|
||||
<a href="{@docRoot}preview/features/app-linking.html">App Linking</a>.
|
||||
|
||||
<h2 id="backup">Auto Backup for Apps</h2>
|
||||
<p>The system now performs automatic full data backup and restore for apps. For the
|
||||
duration of the <a href="{@docRoot}preview/overview.html">M Developer Preview program</a>, all
|
||||
apps are backed up, independent of which SDK version they target. After the final M SDK release,
|
||||
your app must target M to enable this behavior; you do not need to add any additional code. If users
|
||||
delete their Google accounts, their backup data is deleted as well. To learn how this feature
|
||||
works and how to configure what to back up on the file system, see
|
||||
<a href="{@docRoot}preview/backup/index.html">Auto Backup for Apps</a>.</p>
|
||||
|
||||
<h2 id="authentication">Authentication</h2>
|
||||
<p>This preview offers new APIs to let you authenticate users by using their fingerprint scans on
|
||||
supported devices, and check how recently the user was last authenticated using a device unlocking
|
||||
mechanism (such as a lockscreen password). Use these APIs in conjunction with
|
||||
the <a href="{@docRoot}training/articles/keystore.html">Android Keystore system</a>.</p>
|
||||
|
||||
<h3 id="fingerprint-authentication">Fingerprint Authentication</h3>
|
||||
|
||||
<p>To authenticate users via fingerprint scan, get an instance of the new
|
||||
{@link android.hardware.fingerprint.FingerprintManager} class and call the
|
||||
{@link android.hardware.fingerprint.FingerprintManager#authenticate(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.CancellationSignal, int, android.hardware.fingerprint.FingerprintManager.AuthenticationCallback, android.os.Handler) authenticate()}
|
||||
method. Your app must be running on a compatible
|
||||
device with a fingerprint sensor. You must implement the user interface for the fingerprint
|
||||
authentication flow on your app, and use the standard Android fingerprint icon in your UI.
|
||||
The Android fingerprint icon ({@code c_fp_40px.png}) is included in the
|
||||
<a href="https://github.com/googlesamples/android-FingerprintDialog"
|
||||
class="external-link">sample app</a>. If you are developing multiple apps that use fingerprint
|
||||
authentication, note that each app must authenticate the user’s fingerprint independently.
|
||||
</p>
|
||||
|
||||
<p>To use this feature in your app, first add the
|
||||
{@link android.Manifest.permission#USE_FINGERPRINT} permission in your manifest.</p>
|
||||
|
||||
<pre>
|
||||
<uses-permission
|
||||
android:name="android.permission.USE_FINGERPRINT" />
|
||||
</pre>
|
||||
<img src="{@docRoot}preview/images/fingerprint-screen.png"
|
||||
srcset="{@docRoot}preview/images/fingerprint-screen.png 1x, {@docRoot}preview/images/fingerprint-screen_2x.png 2x"
|
||||
style="float:right; margin:0 0 10px 20px" width="282" height="476" />
|
||||
|
||||
<p>To see an app implementation of fingerprint authentication, refer to the
|
||||
<a href="https://github.com/googlesamples/android-FingerprintDialog" class="external-link">
|
||||
Fingerprint Dialog sample</a>. For a demonstration of how you can use these authentication
|
||||
APIs in conjunction with other Android APIs, see the video
|
||||
<a class="video-shadowbox-button" href="https://www.youtube.com/watch?v=VOn7VrTRlA4">
|
||||
Fingerprint and Payment APIs</a>.</p>
|
||||
|
||||
<p>If you are testing this feature, follow these steps:</p>
|
||||
<ol>
|
||||
<li>Install Android SDK Tools Revision 24.3, if you have not done so.</li>
|
||||
<li>Enroll a new fingerprint in the emulator by going to
|
||||
<strong>Settings > Security > Fingerprint</strong>, then follow the enrollment instructions.</li>
|
||||
<li>Use an emulator to emulate fingerprint touch events with the
|
||||
following command. Use the same command to emulate fingerprint touch events on the lockscreen or
|
||||
in your app.
|
||||
<pre class="no-prettyprint">
|
||||
adb -e emu finger touch <finger_id>
|
||||
</pre>
|
||||
<p>On Windows, you may have to run {@code telnet 127.0.0.1 <emulator-id>} followed by
|
||||
{@code finger touch <finger_id>}.
|
||||
</p>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<h3 id="confirm-credential">Confirm Credential</h3>
|
||||
<p>Your app can authenticate users based on how recently they last unlocked their device. This
|
||||
feature frees users from having to remember additional app-specific passwords, and avoids the need
|
||||
for you to implement your own authentication user interface. Your app should use this feature in
|
||||
conjunction with a public or secret key implementation for user authentication.</p>
|
||||
|
||||
<p>To set the timeout duration for which the same key can be re-used after a user is successfully
|
||||
authenticated, call the new
|
||||
{@link android.security.keystore.KeyGenParameterSpec.Builder#setUserAuthenticationValidityDurationSeconds(int) setUserAuthenticationValidityDurationSeconds()}
|
||||
method when you set up a {@link javax.crypto.KeyGenerator} or
|
||||
{@link java.security.KeyPairGenerator}.</p>
|
||||
|
||||
<p>Avoid showing the re-authentication dialog excessively -- your apps should try using the
|
||||
cryptographic object first and if the the timeout expires, use the
|
||||
{@link android.app.KeyguardManager#createConfirmDeviceCredentialIntent(java.lang.CharSequence, java.lang.CharSequence) createConfirmDeviceCredentialIntent()}
|
||||
method to re-authenticate the user within your app.
|
||||
</p>
|
||||
|
||||
<p>To see an app implementation of this feature, refer to the
|
||||
<a href="https://github.com/googlesamples/android-ConfirmCredential" class="external-link">
|
||||
Confirm Credential sample</a>.</p>
|
||||
|
||||
<h2 id="direct-share">Direct Share</h2>
|
||||
|
||||
<img src="{@docRoot}preview/images/direct-share-screen.png"
|
||||
srcset="{@docRoot}preview/images/direct-share-screen.png 1x, {@docRoot}preview/images/direct-share-screen_2x.png 2x"
|
||||
style="float:right; margin:0 0 20px 30px" width="312" height="329" />
|
||||
|
||||
<p>This preview provides you with APIs to make sharing intuitive and quick for users. You can now
|
||||
define <em>direct share targets</em> that launch a specific activity in your app. These direct share
|
||||
targets are exposed to users via the <em>Share</em> menu. This feature allows users to share
|
||||
content to targets, such as contacts, within other apps. For example, the direct share target might
|
||||
launch an activity in another social network app, which lets the user share content directly to a
|
||||
specific friend or community in that app.</p>
|
||||
|
||||
<p>To enable direct share targets you must define a class that extends the
|
||||
{@link android.service.chooser.ChooserTargetService} class. Declare your
|
||||
service in the manifest. Within that declaration, specify the
|
||||
{@link android.Manifest.permission#BIND_CHOOSER_TARGET_SERVICE} permission and an
|
||||
intent filter using the
|
||||
{@link android.service.chooser.ChooserTargetService#SERVICE_INTERFACE SERVICE_INTERFACE} action.</p>
|
||||
<p>The following example shows how you might declare the
|
||||
{@link android.service.chooser.ChooserTargetService} in your manifest.</p>
|
||||
<pre>
|
||||
<service android:name=".ChooserTargetService"
|
||||
android:label="@string/service_name"
|
||||
android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
|
||||
<intent-filter>
|
||||
<action android:name="android.service.chooser.ChooserTargetService" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
</pre>
|
||||
|
||||
<p>For each activity that you want to expose to
|
||||
{@link android.service.chooser.ChooserTargetService}, add a
|
||||
{@code <meta-data>} element with the name
|
||||
{@code "android.service.chooser.chooser_target_service"} in your app manifest.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
<activity android:name=".MyShareActivity”
|
||||
android:label="@string/share_activity_label">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
</intent-filter>
|
||||
<meta-data
|
||||
android:name="android.service.chooser.chooser_target_service"
|
||||
android:value=".ChooserTargetService" />
|
||||
</activity>
|
||||
</pre>
|
||||
|
||||
<h2 id="voice-interactions">Voice Interactions</h2>
|
||||
<p>
|
||||
This preview provides a new voice interaction API which, together with
|
||||
<a href="https://developers.google.com/voice-actions/" class="external-link">Voice Actions</a>,
|
||||
allows you to build conversational voice experiences into your apps. Call the
|
||||
{@link android.app.Activity#isVoiceInteraction()} method to determine if a voice action triggered
|
||||
your activity. If so, your app can use the
|
||||
{@link android.app.VoiceInteractor} class to request a voice confirmation from the user, select
|
||||
from a list of options, and more.</p>
|
||||
|
||||
<p>Most voice interactions originate from a user voice action. A voice interaction activity can
|
||||
also, however, start without user input. For example, another app launched through a voice
|
||||
interaction can also send an intent to launch a voice interaction. To determine if your activity
|
||||
launched from a user voice query or from another voice interaction app, call the
|
||||
{@link android.app.Activity#isVoiceInteractionRoot()} method. If another app launched your
|
||||
activity, the method returns {@code false}. Your app may then prompt the user to confirm that
|
||||
they intended this action.</p>
|
||||
|
||||
<p>To learn more about implementing voice actions, see the
|
||||
<a href="https://developers.google.com/voice-actions/interaction/"
|
||||
class="external-link">Voice Actions developer site</a>.
|
||||
</p>
|
||||
|
||||
<h2 id="assist">Assist API</h2>
|
||||
<p>
|
||||
This preview offers a new way for users to engage with your apps through an assistant. To use this
|
||||
feature, the user must enable the assistant to use the current context. Once enabled, the user
|
||||
can summon the assistant within any app, by long-pressing on the <strong>Home</strong> button.</p>
|
||||
<p>Your app can elect to not share the current context with the assistant by setting the
|
||||
{@link android.view.WindowManager.LayoutParams#FLAG_SECURE} flag. In addition to the
|
||||
standard set of information that the platform passes to the assistant, your app can share
|
||||
additional information by using the new {@link android.app.assist.AssistContent} class.</p>
|
||||
|
||||
<p>To provide the assistant with additional context from your app, follow these steps:</p>
|
||||
|
||||
<ol>
|
||||
<li>Implement the {@link android.app.Application.OnProvideAssistDataListener} interface.</li>
|
||||
<li>Register this listener by using
|
||||
{@link android.app.Application#registerOnProvideAssistDataListener(android.app.Application.OnProvideAssistDataListener) registerOnProvideAssistDataListener()}.</li>
|
||||
<li>In order to provide activity-specific contextual information, override the
|
||||
{@link android.app.Activity#onProvideAssistData(android.os.Bundle) onProvideAssistData()}
|
||||
callback and, optionally, the new
|
||||
{@link android.app.Activity#onProvideAssistContent(android.app.assist.AssistContent) onProvideAssistContent()}
|
||||
callback.
|
||||
</ol>
|
||||
|
||||
<h2 id="notifications">Notifications</h2>
|
||||
<p>This preview adds the following API changes for notifications:</p>
|
||||
<ul>
|
||||
<li>New {@link android.app.NotificationManager#INTERRUPTION_FILTER_ALARMS} filter level that
|
||||
corresponds to the new <em>Alarms only</em> do not disturb mode.</li>
|
||||
<li>New {@link android.app.Notification#CATEGORY_REMINDER} category value that is used to
|
||||
distinguish user-scheduled reminders from other events
|
||||
({@link android.app.Notification#CATEGORY_EVENT}) and alarms
|
||||
({@link android.app.Notification#CATEGORY_ALARM}).</li>
|
||||
<li>New {@link android.graphics.drawable.Icon} class that you can attach to your notifications
|
||||
via the
|
||||
{@link android.app.Notification.Builder#setSmallIcon(android.graphics.drawable.Icon) setSmallIcon()}
|
||||
and {@link android.app.Notification.Builder#setLargeIcon(android.graphics.drawable.Icon) setLargeIcon()}
|
||||
methods. Similarly, the
|
||||
{@link android.app.Notification.Builder#addAction(int, java.lang.CharSequence, android.app.PendingIntent)
|
||||
addAction()} method now accepts an {@link android.graphics.drawable.Icon} object instead of a
|
||||
drawable resource ID.</li>
|
||||
<li>New {@link android.app.NotificationManager#getActiveNotifications()} method that allows your
|
||||
apps to find out which of their notifications are currently alive. To see an app implementation
|
||||
that uses this feature, see the <a href="https://github.com/googlesamples/android-ActiveNotifications"
|
||||
class="external-link">Active Notifications sample</a>.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="bluetooth-stylus">Bluetooth Stylus Support</h2>
|
||||
<p>This preview provides improved support for user input using a Bluetooth stylus. Users can pair
|
||||
and connect a compatible Bluetooth stylus with their phone or tablet. While connected, position
|
||||
information from the touch screen is fused with pressure and button information from the stylus to
|
||||
provide a greater range of expression than with the touch screen alone. Your app can listen for
|
||||
stylus button presses and perform secondary actions, by registering
|
||||
{@link android.view.View.OnContextClickListener} and
|
||||
{@link android.view.GestureDetector.OnContextClickListener} objects in your activity.</p>
|
||||
|
||||
<p>Use the {@link android.view.MotionEvent} methods and constants to detect stylus button
|
||||
interactions:</p>
|
||||
<ul>
|
||||
<li>If the user touches a stylus with a button on the screen of your app, the
|
||||
{@link android.view.MotionEvent#getToolType(int) getTooltype()} method returns
|
||||
{@link android.view.MotionEvent#TOOL_TYPE_STYLUS}.</li>
|
||||
<li>For apps targeting M Preview, the
|
||||
{@link android.view.MotionEvent#getButtonState() getButtonState()}
|
||||
method returns {@link android.view.MotionEvent#BUTTON_STYLUS_PRIMARY} when the user
|
||||
presses the primary stylus button. If the stylus has a second button, the same method returns
|
||||
{@link android.view.MotionEvent#BUTTON_STYLUS_SECONDARY} when the user presses it. If the user presses
|
||||
both buttons simultaneously, the method returns both values OR'ed together
|
||||
({@link android.view.MotionEvent#BUTTON_STYLUS_PRIMARY}|{@link android.view.MotionEvent#BUTTON_STYLUS_SECONDARY}).</li>
|
||||
<li>
|
||||
For apps targeting a lower platform version, the
|
||||
{@link android.view.MotionEvent#getButtonState() getButtonState()} method returns
|
||||
{@link android.view.MotionEvent#BUTTON_SECONDARY} (for primary stylus button press),
|
||||
{@link android.view.MotionEvent#BUTTON_TERTIARY} (for secondary stylus button press), or both.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="ble-scanning">Improved Bluetooth Low Energy Scanning</h2>
|
||||
<p>
|
||||
If your app performs performs Bluetooth Low Energy scans, use the new
|
||||
{@link android.bluetooth.le.ScanSettings.Builder#setCallbackType(int) setCallbackType()}
|
||||
method to specify that you want the system to notify callbacks when it first finds, or sees after a
|
||||
long time, an advertisement packet matching the set {@link android.bluetooth.le.ScanFilter}. This
|
||||
approach to scanning is more power-efficient than what’s provided in the previous platform version.
|
||||
</p>
|
||||
|
||||
<h2 id="hotspot">Hotspot 2.0 Release 1 Support</h2>
|
||||
<p>
|
||||
This preview adds support for the Hotspot 2.0 Release 1 spec on Nexus 6 and Nexus 9 devices. To
|
||||
provision Hotspot 2.0 credentials in your app, use the new methods of the
|
||||
{@link android.net.wifi.WifiEnterpriseConfig} class, such as
|
||||
{@link android.net.wifi.WifiEnterpriseConfig#setPlmn(java.lang.String) setPlmn()} and
|
||||
{@link android.net.wifi.WifiEnterpriseConfig#setRealm(java.lang.String) setRealm()}. In the
|
||||
{@link android.net.wifi.WifiConfiguration} object, you can set the
|
||||
{@link android.net.wifi.WifiConfiguration#FQDN} and the
|
||||
{@link android.net.wifi.WifiConfiguration#providerFriendlyName} fields.
|
||||
The new {@link android.net.wifi.ScanResult#isPasspointNetwork()} method indicates if a detected
|
||||
network represents a Hotspot 2.0 access point.
|
||||
</p>
|
||||
|
||||
<h2 id="4K-display">4K Display Mode</h2>
|
||||
<p>The platform now allows apps to request that the display resolution be upgraded to 4K rendering
|
||||
on compatible hardware. To query the current physical resolution, use the new
|
||||
{@link android.view.Display.Mode} APIs. If the UI is drawn at a lower logical resolution and is
|
||||
upscaled to a larger physical resolution, be aware that the physical resolution the
|
||||
{@link android.view.Display.Mode#getPhysicalWidth()} method returns may differ from the logical
|
||||
resolution reported by {@link android.view.Display#getSize(android.graphics.Point) getSize()}.</p>
|
||||
|
||||
<p>You can request the system to change the physical resolution in your app as it runs, by setting
|
||||
the {@link android.view.WindowManager.LayoutParams#preferredDisplayModeId} property of your app’s
|
||||
window. This feature is useful if you want to switch to 4K display resolution. While in 4K display
|
||||
mode, the UI continues to be rendered at the original resolution (such as 1080p) and is upscaled to
|
||||
4K, but {@link android.view.SurfaceView} objects may show content at the native resolution.</p>
|
||||
|
||||
<h2 id="behavior-themeable-colorstatelists">Themeable ColorStateLists</h2>
|
||||
<p>Theme attributes are now supported in
|
||||
{@link android.content.res.ColorStateList} for devices running the M Preview. The
|
||||
{@link android.content.res.Resources#getColorStateList(int) getColorStateList()} and
|
||||
{@link android.content.res.Resources#getColor(int) getColor()} methods have been deprecated. If
|
||||
you are calling these APIs, call the new
|
||||
{@link android.content.Context#getColorStateList(int) getColorStateList()} or
|
||||
{@link android.content.Context#getColor(int) getColor()} methods instead. These methods are also
|
||||
available in the v4 appcompat library via {@link android.support.v4.content.ContextCompat}.</p>
|
||||
|
||||
<h2 id="audio">Audio Features</h2>
|
||||
|
||||
<p>This preview adds enhancements to audio processing on Android, including: </p>
|
||||
<ul>
|
||||
<li>Support for the <a href="http://en.wikipedia.org/wiki/MIDI" class="external-link">MIDI</a>
|
||||
protocol, with the new {@link android.media.midi} APIs. Use these APIs to send and receive MIDI
|
||||
events.</li>
|
||||
<li>New {@link android.media.AudioRecord.Builder} and {@link android.media.AudioTrack.Builder}
|
||||
classes to create digital audio capture and playback objects respectively, and configure audio
|
||||
source and sink properties to override the system defaults.</li>
|
||||
<li>API hooks for associating audio and input devices. This is particularly useful if your app
|
||||
allows users to start a voice search from a game controller or remote control connected to Android
|
||||
TV. The system invokes the new
|
||||
{@link android.app.Activity#onSearchRequested(android.view.SearchEvent) onSearchRequested()}
|
||||
callback when the user starts a search. To determine if the user's input device has a built-in
|
||||
microphone, retrieve the {@link android.view.InputDevice} object from that callback, then call the
|
||||
new {@link android.view.InputDevice#hasMicrophone()} method.</li>
|
||||
<li>New {@link android.media.AudioManager#getDevices(int) getDevices()} method which lets you
|
||||
retrieve a list of all audio devices currently connected to the system. You can also register an
|
||||
{@link android.media.AudioDeviceCallback} object if you want the system to notify your app
|
||||
when an audio device connects or disconnects.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="video">Video Features</h2>
|
||||
<p>This preview adds new capabilities to the video processing APIs, including:</p>
|
||||
<ul>
|
||||
<li>New {@link android.media.MediaSync} class which helps applications to synchronously render
|
||||
audio and video streams. The audio buffers are submitted in non-blocking fashion and are
|
||||
returned via a callback. It also supports dynamic playback rate.
|
||||
</li>
|
||||
<li>New {@link android.media.MediaDrm#EVENT_SESSION_RECLAIMED} event, which indicates that a
|
||||
session opened by the app has been reclaimed by the resource manager. If your app uses DRM sessions,
|
||||
you should handle this event and make sure not to use a reclaimed session.
|
||||
</li>
|
||||
<li>New {@link android.media.MediaCodec.CodecException#ERROR_RECLAIMED} error code, which indicates
|
||||
that the resource manager reclaimed the media resource used by the codec. With this exception, the
|
||||
codec must be released, as it has moved to terminal state.
|
||||
</li>
|
||||
<li>New {@link android.media.MediaCodecInfo.CodecCapabilities#getMaxSupportedInstances()
|
||||
getMaxSupportedInstances()} interface to get a hint for the max number of the supported
|
||||
concurrent codec instances.
|
||||
</li>
|
||||
<li>New {@link android.media.MediaPlayer#setPlaybackParams(android.media.PlaybackParams)
|
||||
setPlaybackParams()} method to set the media playback rate for fast or
|
||||
slow motion playback. It also stretches or speeds up the audio playback automatically in
|
||||
conjunction with the video.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="camera">Camera Features</h2>
|
||||
<p>This preview includes the following new APIs for accessing the camera’s flashlight and for
|
||||
camera reprocessing of images:</p>
|
||||
|
||||
<h3 id="flashlight">Flashlight API</h3>
|
||||
<p>If a camera device has a flash unit, you can call the
|
||||
{@link android.hardware.camera2.CameraManager#setTorchMode(java.lang.String, boolean) setTorchMode()}
|
||||
method to switch the flash unit’s torch mode on or off without opening the camera device. The app
|
||||
does not have exclusive ownership of the flash unit or the camera device. The torch mode is turned
|
||||
off and becomes unavailable whenever the camera device becomes unavailable, or when other camera
|
||||
resources keeping the torch on become unavailable. Other apps can also call
|
||||
{@link android.hardware.camera2.CameraManager#setTorchMode(java.lang.String, boolean) setTorchMode()}
|
||||
to turn off the torch mode. When the last app that turned on the torch mode is closed, the torch
|
||||
mode is turned off.</p>
|
||||
|
||||
<p>You can register a callback to be notified about torch mode status by calling the
|
||||
{@link android.hardware.camera2.CameraManager#registerTorchCallback(android.hardware.camera2.CameraManager.TorchCallback, android.os.Handler) registerTorchCallback()}
|
||||
method. The first time the callback is registered, it is immediately called with the torch mode
|
||||
status of all currently known camera devices with a flash unit. If the torch mode is turned on or
|
||||
off successfully, the
|
||||
{@link android.hardware.camera2.CameraManager.TorchCallback#onTorchModeChanged(java.lang.String, boolean) onTorchModeChanged()}
|
||||
method is invoked.</p>
|
||||
|
||||
<h3 id="reprocessing">Reprocessing API</h3>
|
||||
<p>The {@link android.hardware.camera2 Camera2} API is extended to support YUV and private
|
||||
opaque format image reprocessing. To determine if these reprocessing capabilities are available,
|
||||
call {@link android.hardware.camera2.CameraManager#getCameraCharacteristics(java.lang.String)
|
||||
getCameraCharacteristics()} and check for the
|
||||
{@link android.hardware.camera2.CameraCharacteristics#REPROCESS_MAX_CAPTURE_STALL} key. If a
|
||||
device supports reprocessing, you can create a reprocessable camera capture session by calling
|
||||
<a href="/reference/android/hardware/camera2/CameraDevice.html#createReprocessableCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler)"><code>createReprocessableCaptureSession()</code></a>,
|
||||
and create requests for input buffer reprocessing.</p>
|
||||
|
||||
<p>Use the {@link android.media.ImageWriter} class to connect the input buffer flow to the camera
|
||||
reprocessing input. To get an empty buffer, follow this programming model:</p>
|
||||
|
||||
<ol>
|
||||
<li>Call the {@link android.media.ImageWriter#dequeueInputImage()} method.</li>
|
||||
<li>Fill the data into the input buffer.</li>
|
||||
<li>Send the buffer to the camera by calling the
|
||||
{@link android.media.ImageWriter#queueInputImage(android.media.Image) queueInputImage()} method.</li>
|
||||
</ol>
|
||||
|
||||
<p>If you are using a {@link android.media.ImageWriter} object together with an
|
||||
{@link android.graphics.ImageFormat#PRIVATE} image, your app cannot access the image
|
||||
data directly. Instead, pass the {@link android.graphics.ImageFormat#PRIVATE} image directly to the
|
||||
{@link android.media.ImageWriter} by calling the
|
||||
{@link android.media.ImageWriter#queueInputImage(android.media.Image) queueInputImage()} method
|
||||
without any buffer copy.</p>
|
||||
|
||||
<p>The {@link android.media.ImageReader} class now supports
|
||||
{@link android.graphics.ImageFormat#PRIVATE} format image streams. This support allows your app to
|
||||
maintain a circular image queue of {@link android.media.ImageReader} output images, select one or
|
||||
more images, and send them to the {@link android.media.ImageWriter} for camera reprocessing.</p>
|
||||
|
||||
<h2 id="afw">Android for Work Features</h2>
|
||||
<p>This preview includes the following new APIs for Android for Work:</p>
|
||||
<ul>
|
||||
<li><strong>Enhanced controls for Corporate-Owned, Single-Use devices:</strong> The Device Owner
|
||||
can now control the following settings to improve management of
|
||||
Corporate-Owned, Single-Use (COSU) devices:
|
||||
<ul>
|
||||
<li>Disable or re-enable the keyguard with the
|
||||
{@link android.app.admin.DevicePolicyManager#setKeyguardDisabled(android.content.ComponentName, boolean)
|
||||
setKeyguardDisabled()} method.</li>
|
||||
<li>Disable or re-enable the status bar (including quick settings, notifications, and the
|
||||
navigation swipe-up gesture that launches Google Now) with the
|
||||
{@link android.app.admin.DevicePolicyManager#setStatusBarDisabled(android.content.ComponentName, boolean) setStatusBarDisabled()}
|
||||
method.</li>
|
||||
<li>Disable or re-enable safe boot with the {@link android.os.UserManager} constant
|
||||
{@link android.os.UserManager#DISALLOW_SAFE_BOOT}.</li>
|
||||
<li>Prevent the screen from turning off while plugged in with the
|
||||
{@link android.provider.Settings.Global#STAY_ON_WHILE_PLUGGED_IN} constant.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Silent install and uninstall of apps by Device Owner:</strong> A Device Owner can now
|
||||
silently install and uninstall applications using the {@link android.content.pm.PackageInstaller}
|
||||
APIs, independent of Google Play for Work. You can now provision devices through a Device Owner that
|
||||
fetches and installs apps without user interaction. This feature is useful for enabling one-touch
|
||||
provisioning of kiosks or other such devices without activating a Google account.</li>
|
||||
<li><strong>Silent enterprise certificate access: </strong> When an app calls
|
||||
{@link android.security.KeyChain#choosePrivateKeyAlias(android.app.Activity,android.security.KeyChainAliasCallback,java.lang.String[],java.security.Principal[],java.lang.String,int,java.lang.String) choosePrivateKeyAlias()},
|
||||
prior to the user being prompted to select a certificate, the Profile or Device Owner can now call
|
||||
the {@link android.app.admin.DeviceAdminReceiver#onChoosePrivateKeyAlias(android.content.Context, android.content.Intent, int, android.net.Uri, java.lang.String) onChoosePrivateKeyAlias()}
|
||||
method to provide the alias silently to the requesting application. This feature lets you grant
|
||||
managed apps access to certificates without user interaction.</li>
|
||||
<li><strong>Auto-acceptance of system updates.</strong> By setting a system update policy with
|
||||
{@link android.app.admin.DevicePolicyManager#setSystemUpdatePolicy(android.content.ComponentName, android.app.admin.SystemUpdatePolicy) setSystemUpdatePolicy()},
|
||||
a Device Owner can now auto-accept a system
|
||||
update, for instance in the case of a kiosk device, or postpone the update and prevent it being
|
||||
taken by the user for up to 30 days. Furthermore, an administrator can set a daily time window in
|
||||
which an update must be taken, for example during the hours when a kiosk device is not in use. When
|
||||
a system update is available, the system checks if the Work Policy Controller app has set a system
|
||||
update policy, and behaves accordingly.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Delegated certificate installation:</strong> A Profile or Device Owner can now grant a
|
||||
third-party app the ability to call these {@link android.app.admin.DevicePolicyManager} certificate
|
||||
management APIs:
|
||||
<ul>
|
||||
<li>{@link android.app.admin.DevicePolicyManager#getInstalledCaCerts(android.content.ComponentName)
|
||||
getInstalledCaCerts()}</li>
|
||||
<li>{@link android.app.admin.DevicePolicyManager#hasCaCertInstalled(android.content.ComponentName,byte[])
|
||||
hasCaCertInstalled()}</li>
|
||||
<li>{@link android.app.admin.DevicePolicyManager#installCaCert(android.content.ComponentName,byte[])
|
||||
installCaCert()}</li>
|
||||
<li>{@link android.app.admin.DevicePolicyManager#uninstallCaCert(android.content.ComponentName,byte[])
|
||||
uninstallCaCert()}</li>
|
||||
<li>{@link android.app.admin.DevicePolicyManager#uninstallAllUserCaCerts(android.content.ComponentName)
|
||||
uninstallAllUserCaCerts()}</li>
|
||||
<li>{@link android.app.admin.DevicePolicyManager#installKeyPair(android.content.ComponentName,java.security.PrivateKey,java.security.cert.Certificate,java.lang.String)
|
||||
installKeyPair()}</li>
|
||||
</ul>
|
||||
</li>
|
||||
<img src="{@docRoot}preview/images/work-profile-screen.png"
|
||||
srcset="{@docRoot}preview/images/work-profile-screen.png 1x, {@docRoot}preview/images/work-profile-screen_2x.png 2x"
|
||||
style="float:right; margin:0 0 10px 20px" width="282" height="476" />
|
||||
<li><strong>Data usage tracking.</strong> A Profile or Device Owner can now query for the
|
||||
data usage statistics visible in <strong>Settings > Data</strong> usage by using the new
|
||||
{@link android.app.usage.NetworkStatsManager} methods. Profile Owners are automatically granted
|
||||
permission to query data on the profile they manage, while Device Owners get access to usage data
|
||||
of the managed primary user.</li>
|
||||
<li><strong>Runtime permission management:</strong>
|
||||
<p>A Profile or Device Owner can set a permission policy
|
||||
for all runtime requests of all applications using
|
||||
{@link android.app.admin.DevicePolicyManager#setPermissionPolicy(android.content.ComponentName, int)
|
||||
setPermissionPolicy()}, to either prompt the user to grant the permission or automatically grant or
|
||||
deny the permission silently. If the latter policy is set, the user cannot
|
||||
modify the selection made by the Profile or Device Owner within the app’s permissions screen in
|
||||
<strong>Settings</strong>.</p></li>
|
||||
<li><strong>VPN in Settings:</strong> VPN apps are now visible in
|
||||
<strong>Settings > More > VPN</strong>.
|
||||
Additionally, the notifications that accompany VPN usage are now specific to how that VPN is
|
||||
configured. For Profile Owner, the notifications are specific to whether the VPN is configured
|
||||
for a managed profile, a personal profile, or both. For a Device Owner, the notifications are
|
||||
specific to whether the VPN is configured for the entire device.</li>
|
||||
<li><strong>Work status notification:</strong> A status bar briefcase icon now appears whenever
|
||||
an app from the managed profile has an activity in the foreground. Furthermore, if the device is
|
||||
unlocked directly to the activity of an app in the managed profile, a toast is displayed notifying
|
||||
the user that they are within the work profile.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p class="note">
|
||||
For a detailed view of all API changes in the M Developer Preview, see the <a href=
|
||||
"{@docRoot}preview/download.html">API Differences Report</a>.
|
||||
This page is under construction. For now, please see
|
||||
<a href="https://docs.google.com/document/d/1TA8Vzoa7KQ99bj1GVD81ps3Ux4wY0Ctkz7dC7bNnslU/edit">
|
||||
this page</a> for information.
|
||||
</p>
|
||||
|
||||
@@ -5,440 +5,8 @@ page.tags="preview", "developer preview"
|
||||
page.image=images/cards/card-n-changes_2x.png
|
||||
@jd:body
|
||||
|
||||
<div id="qv-wrapper">
|
||||
<div id="qv">
|
||||
|
||||
<h2>In this document</h2>
|
||||
|
||||
<ol id="toc44" class="hide-nested">
|
||||
<li><a href="#behavior-runtime-permissions">Runtime Permissions</a></li>
|
||||
<li><a href="#behavior-power">Power-Saving Optimizations</a></li>
|
||||
<li><a href="#behavior-adoptable-storage">Adoptable Storage Devices</a></li>
|
||||
<li><a href="#behavior-apache-http-client">Apache HTTP Client Removal</a></li>
|
||||
<li><a href="#behavior-audiomanager-Changes">AudioManager Changes</a></li>
|
||||
<li><a href="#behavior-notifications">Notifications</a></li>
|
||||
<li><a href="#behavior-test-selection">Text Selection</a></li>
|
||||
<li><a href="#behavior-keystore">Android Keystore Changes</a></li>
|
||||
<li><a href="#behavior-network">Wi-Fi and Networking Changes</a></li>
|
||||
<li><a href="#behavior-camera">Camera Service Changes</a></li>
|
||||
<li><a href="#behavior-runtime">Runtime</a></li>
|
||||
<li><a href="#behavior-hardware-id">Access to Hardware Identifier</a></li>
|
||||
<li><a href="#behavior-apk-validation">APK Validation</a></li>
|
||||
<li><a href="#behavior-usb">USB Connection</a></li>
|
||||
<li><a href="#behavior-afw">Android for Work Changes</a></li>
|
||||
</ol>
|
||||
|
||||
<h2>API Differences</h2>
|
||||
<ol>
|
||||
<li><a href="{@docRoot}preview/download.html">API level 22 to M Preview »</a> </li>
|
||||
</ol>
|
||||
|
||||
|
||||
<h2>See Also</h2>
|
||||
<ol>
|
||||
<li><a href="{@docRoot}preview/api-overview.html">M Developer Preview API Overview</a> </li>
|
||||
</ol>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>Along with new features and capabilities, the M Developer Preview includes a variety of
|
||||
system changes and API behavior changes. This document highlights
|
||||
some of the key changes that you should understand and account for in your apps.</p>
|
||||
|
||||
<p>If you have previously published an app for Android, be aware that these changes in the
|
||||
platform affect your app.</p>
|
||||
|
||||
<h2 id="behavior-runtime-permissions">Runtime Permissions</h1>
|
||||
<p>This preview introduces a new permissions model, where users can now directly manage
|
||||
app permissions at runtime. This model gives users improved visibility and control over
|
||||
permissions, while streamlining the installation and auto-update processes for app developers.
|
||||
Users can grant or revoke permissions individually for installed apps. </p>
|
||||
|
||||
<p>On your apps that target the M Preview release or higher, make sure to check for and request
|
||||
permissions at runtime. To determine if your app has been granted a permission, call the
|
||||
new {@link android.content.Context#checkSelfPermission(java.lang.String) checkSelfPermission()}
|
||||
method. To request a permission, call the new
|
||||
{@link android.app.Activity#requestPermissions(java.lang.String[], int) requestPermissions()}
|
||||
method. Even if your app is not targeting the M Preview release, you should test your app under
|
||||
the new permissions model.</p>
|
||||
|
||||
<p>For details on supporting the new permissions model in your app, see the
|
||||
<a href="{@docRoot}preview/features/runtime-permissions.html">
|
||||
Permissions</a> developer preview page. For tips on how to assess the impact on your app,
|
||||
see the <a href="{@docRoot}preview/testing/guide.html#runtime-permissions">Testing Guide</a></p>
|
||||
|
||||
<h2 id="behavior-power">Power-Saving Optimizations</h2>
|
||||
<p>This preview introduces new power-saving optimizations for idle devices and apps.</p>
|
||||
<ul>
|
||||
<li><strong>Doze</strong>: If a user unplugs a device and leaves it stationary, with its screen off,
|
||||
for a period of time, the device goes into <em>Doze</em> mode, where it attempts to keep the system
|
||||
in a sleep state. In this mode, devices periodically resume normal operations for brief periods of
|
||||
time so that app syncing can occur and the system can perform any pending operations.
|
||||
<li><strong>App Standby</strong>: App Standby allows the system to determine that an app is idle
|
||||
when the user is not actively using it. The system makes this determination when the user does not
|
||||
touch the app for a certain period of time. If the device is unplugged, the system disables network
|
||||
access and suspends syncs and jobs for the apps it deems idle.</li>
|
||||
</ul>
|
||||
|
||||
<p>To learn more about these power-saving changes, see
|
||||
<a href="{@docRoot}preview/features/power-mgmt.html">Power-Saving Optimizations</a>.</p>
|
||||
|
||||
<h2 id="behavior-adoptable-storage">Adoptable Storage Devices</h2>
|
||||
<p>
|
||||
With this preview, users can <em>adopt</em> external storage devices such as SD cards. Adopting an
|
||||
external storage device encrypts and formats the device to behave like internal storage. This
|
||||
feature allows users to move both apps and private data of those apps between storage devices. When
|
||||
moving apps, the system respects the
|
||||
<a href="{@docRoot}guide/topics/manifest/manifest-element.html#install">{@code android:installLocation}</a>
|
||||
preference in the manifest.</p>
|
||||
|
||||
<p>If your app accesses the following APIs or fields, be aware that the file paths they return
|
||||
will dynamically change when the app is moved between internal and external storage devices.
|
||||
When building file paths, it is strongly recommended that you always call these APIs dynamically.
|
||||
Don’t use hardcoded file paths or persist fully-qualified file paths that were built previously.</p>
|
||||
|
||||
<ul>
|
||||
<li>{@link android.content.Context} methods:
|
||||
<ul>
|
||||
<li>{@link android.content.Context#getFilesDir() getFilesDir()}</li>
|
||||
<li>{@link android.content.Context#getCacheDir() getCacheDir()}</li>
|
||||
<li>{@link android.content.Context#getCodeCacheDir() getCodeCacheDir()}</li>
|
||||
<li>{@link android.content.Context#getDatabasePath(java.lang.String) getDatabasePath()}</li>
|
||||
<li>{@link android.content.Context#getDir(java.lang.String,int) getDir()}</li>
|
||||
<li>{@link android.content.Context#getNoBackupFilesDir() getNoBackupFilesDir()}</li>
|
||||
<li>{@link android.content.Context#getFileStreamPath(java.lang.String) getFileStreamPath()}</li>
|
||||
<li>{@link android.content.Context#getPackageCodePath() getPackageCodePath()}</li>
|
||||
<li>{@link android.content.Context#getPackageResourcePath() getPackageResourcePath()}</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>{@link android.content.pm.ApplicationInfo} fields:
|
||||
<ul>
|
||||
<li>{@link android.content.pm.ApplicationInfo#dataDir dataDir}</li>
|
||||
<li>{@link android.content.pm.ApplicationInfo#sourceDir sourceDir}</li>
|
||||
<li>{@link android.content.pm.ApplicationInfo#nativeLibraryDir nativeLibraryDir}</li>
|
||||
<li>{@link android.content.pm.ApplicationInfo#publicSourceDir publicSourceDir}</li>
|
||||
<li>{@link android.content.pm.ApplicationInfo#splitSourceDirs splitSourceDirs}</li>
|
||||
<li>{@link android.content.pm.ApplicationInfo#splitPublicSourceDirs splitPublicSourceDirs}</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>To debug this feature in the developer preview, you can enable adoption of a USB drive that is
|
||||
connected to an Android device through a USB On-The-Go (OTG) cable, by running this command:</p>
|
||||
|
||||
<pre class="no-prettyprint">
|
||||
$ adb shell sm set-force-adoptable true
|
||||
</pre>
|
||||
|
||||
<h2 id="behavior-apache-http-client">Apache HTTP Client Removal</h2>
|
||||
<p>This preview removes support for the Apache HTTP client. If your app is using this client and
|
||||
targets Android 2.3 (API level 9) or higher, use the {@link java.net.HttpURLConnection} class
|
||||
instead. This API is more efficient because it reduces network use through transparent compression
|
||||
and response caching, and minimizes power consumption. To continue using the Apache HTTP APIs, you
|
||||
must first declare the following compile-time dependency in your {@code build.gradle} file:
|
||||
</p>
|
||||
<pre>
|
||||
android {
|
||||
useLibrary 'org.apache.http.legacy'
|
||||
}
|
||||
</pre>
|
||||
<p>Android is moving away from OpenSSL to the
|
||||
<a href="https://boringssl.googlesource.com/boringssl/" class="external-link">BoringSSL</a>
|
||||
library. If you’re using the Android NDK in your app, don't link against cryptographic libraries
|
||||
that are not a part of the NDK API, such as {@code libcrypto.so} and {@code libssl.so}. These
|
||||
libraries are not public APIs, and may change or break without notice across releases and devices.
|
||||
In addition, you may expose yourself to security vulnerabilities. Instead, modify your
|
||||
native code to call the Java cryptography APIs via JNI or to statically link against a
|
||||
cryptography library of your choice.</p>
|
||||
|
||||
<h2 id="behavior-audiomanager-Changes">AudioManager Changes</h2>
|
||||
<p>Setting the volume directly or muting specific streams via the {@link android.media.AudioManager}
|
||||
class is no longer supported. The {@link android.media.AudioManager#setStreamSolo(int,boolean)
|
||||
setStreamSolo()} method is deprecated, and you should call the
|
||||
{@link android.media.AudioManager#requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int) requestAudioFocus()}
|
||||
method instead. Similarly, the
|
||||
{@link android.media.AudioManager#setStreamMute(int,boolean) setStreamMute()} method is
|
||||
deprecated; instead, call the {@link android.media.AudioManager#adjustStreamVolume(int, int, int)
|
||||
adjustStreamVolume()} method and pass in the direction value
|
||||
{@link android.media.AudioManager#ADJUST_MUTE} or
|
||||
{@link android.media.AudioManager#ADJUST_UNMUTE}.</p>
|
||||
|
||||
<h2 id="behavior-notifications">Notifications</h2>
|
||||
<p>
|
||||
This release removes the {@code Notification.setLatestEventInfo()} method. Use the
|
||||
{@link android.app.Notification.Builder} class instead to construct notifications. To update a
|
||||
notification repeatedly, reuse the {@link android.app.Notification.Builder} instance. Call the
|
||||
{@link android.app.Notification.Builder#build()} method to get
|
||||
updated {@link android.app.Notification} instances.
|
||||
</p>
|
||||
<p>The {@code adb shell dumpsys notification} command no longer prints out your notification text.
|
||||
Use the {@code adb shell dumpsys notification --noredact} command instead to print out the text
|
||||
in a notification object.</p>
|
||||
|
||||
<h2 id="behavior-test-selection">Text Selection</h2>
|
||||
|
||||
<img src="{@docRoot}preview/images/text-selection.gif"
|
||||
style="float:right; margin:0 0 20px 30px" width="360" height="640" />
|
||||
|
||||
<p>When users select text in your app, you can now display text selection actions such as
|
||||
<em>Cut</em>, <em>Copy</em>, and <em>Paste</em> in a
|
||||
<a href="http://www.google.com/design/spec/patterns/selection.html#selection-text-selection"
|
||||
class="external-link">floating toolbar</a>. The user interaction implementation is similar to that
|
||||
for the contextual action bar, as described in
|
||||
<a href="{@docRoot}guide/topics/ui/menus.html#CABforViews">
|
||||
Enabling the contextual action mode for individual views</a>.</p>
|
||||
|
||||
<p>To implement a floating toolbar for text selection, make the following changes in your existing
|
||||
apps:</p>
|
||||
<ol>
|
||||
<li>In your {@link android.view.View} or {@link android.app.Activity} object, change your
|
||||
{@link android.view.ActionMode} calls from
|
||||
{@code startActionMode(Callback)} to {@code startActionMode(Callback, ActionMode.TYPE_FLOATING)}.</li>
|
||||
<li>Take your existing implementation of {@code ActionMode.Callback} and make it extend
|
||||
{@link android.view.ActionMode.Callback2} instead.</li>
|
||||
<li>Override the
|
||||
{@link android.view.ActionMode.Callback2#onGetContentRect(android.view.ActionMode, android.view.View, android.graphics.Rect) onGetContentRect()}
|
||||
method to provide the coordinates of the content {@link android.graphics.Rect} object
|
||||
(such as a text selection rectangle) in the view.</li>
|
||||
<li>If the rectangle positioning is no longer valid, and this is the only element to be invalidated,
|
||||
call the {@link android.view.ActionMode#invalidateContentRect() invalidateContentRect()} method.</li>
|
||||
</ol>
|
||||
|
||||
<p>If you are using <a href="{@docRoot}tools/support-library/index.html">
|
||||
Android Support Library</a> revision 22.2, be aware that floating toolbars are not
|
||||
backward-compatible and appcompat takes control over {@link android.view.ActionMode} objects by
|
||||
default. This prevents floating toolbars from being displayed. To enable
|
||||
{@link android.view.ActionMode} support in an
|
||||
{@link android.support.v7.app.AppCompatActivity}, call
|
||||
{@link android.support.v7.app.AppCompatActivity#getDelegate()}, then call
|
||||
{@link android.support.v7.app.AppCompatDelegate#setHandleNativeActionModesEnabled(boolean)
|
||||
setHandleNativeActionModesEnabled()} on the returned
|
||||
{@link android.support.v7.app.AppCompatDelegate} object and set the input
|
||||
parameter to {@code false}. This call returns control of {@link android.view.ActionMode} objects to
|
||||
the framework. In devices running the M Preview, that allows the framework to support
|
||||
{@link android.support.v7.app.ActionBar} or floating toolbar modes, while on pre-M Preview devices,
|
||||
only the {@link android.support.v7.app.ActionBar} modes are supported.</p>
|
||||
|
||||
<h2 id="behavior-keystore">Android Keystore Changes</h2>
|
||||
<p>With this preview, the
|
||||
<a href="{@docRoot}training/articles/keystore.html">Android Keystore provider</a> no longer supports
|
||||
DSA. ECDSA is still supported.</p>
|
||||
|
||||
<p>Keys which do not require encryption at rest will no longer be deleted when secure lock screen
|
||||
is disabled or reset (for example, by the user or a Device Administrator). Keys which require
|
||||
encryption at rest will be deleted during these events.</p>
|
||||
|
||||
<h2 id="behavior-network">Wi-Fi and Networking Changes</h2>
|
||||
|
||||
<p>This preview introduces the following behavior changes to the Wi-Fi and networking APIs.</p>
|
||||
<ul>
|
||||
<li>Your apps can now change the state of {@link android.net.wifi.WifiConfiguration} objects only
|
||||
if you created these objects. You are not permitted to modify or delete
|
||||
{@link android.net.wifi.WifiConfiguration} objects created by the user or by other apps.
|
||||
</li>
|
||||
<li>
|
||||
Previously, if an app forced the device to connect to a specific Wi-Fi network by using
|
||||
{@link android.net.wifi.WifiManager#enableNetwork(int,boolean) enableNetwork()} with the
|
||||
{@code disableAllOthers=true} setting, the device disconnected from other networks such as
|
||||
cellular data. In this preview, the device no longer disconnects from such other networks. If
|
||||
your app’s {@code targetSdkVersion} is {@code “20”} or lower, it is pinned to the selected
|
||||
Wi-Fi network. If your app’s {@code targetSdkVersion} is {@code “21”} or higher, use the
|
||||
multinetwork APIs (such as
|
||||
{@link android.net.Network#openConnection(java.net.URL) openConnection()},
|
||||
{@link android.net.Network#bindSocket(java.net.Socket) bindSocket()}, and the new
|
||||
{@link android.net.ConnectivityManager#bindProcessToNetwork(android.net.Network)
|
||||
bindProcessToNetwork()} method) to ensure that its network traffic is sent on the selected network.</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="behavior-camera">Camera Service Changes</h2>
|
||||
<p>In this preview, the model for accessing shared resources in the camera service has been changed
|
||||
from the previous “first come, first serve” access model to an access model where high-priority
|
||||
processes are favored. Changes to the service behavior include:</p>
|
||||
<ul>
|
||||
<li>Access to camera subsystem resources, including opening and configuring a camera device, is
|
||||
awarded based on the “priority” of the client application process. Application processes with
|
||||
user-visible or foreground activities are generally given a higher-priority, making camera resource
|
||||
acquisition and use more dependable.</li>
|
||||
<li>Active camera clients for lower priority apps may be “evicted” when a higher priority
|
||||
application attempts to use the camera. In the deprecated {@link android.hardware.Camera} API,
|
||||
this results in
|
||||
{@link android.hardware.Camera.ErrorCallback#onError(int,android.hardware.Camera) onError()} being
|
||||
called for the evicted client. In the {@link android.hardware.camera2 Camera2} API, it results in
|
||||
{@link android.hardware.camera2.CameraDevice.StateCallback#onDisconnected(android.hardware.camera2.CameraDevice) onDisconnected()}
|
||||
being called for the evicted client.</li>
|
||||
<li>On devices with appropriate camera hardware, separate application processes are able to
|
||||
independently open and use separate camera devices simultaneously. However, multi-process use
|
||||
cases, where simultaneous access causes significant degradation of performance or capabilities of
|
||||
any of the open camera devices, are now detected and disallowed by the camera service. This change
|
||||
may result in “evictions” for lower priority clients even when no other app is directly
|
||||
attempting to access the same camera device.
|
||||
</li>
|
||||
<li>
|
||||
Changing the current user causes active camera clients in apps owned by the previous user account
|
||||
to be evicted. Access to the camera is limited to user profiles owned by the current device user.
|
||||
In practice, this means that a “Guest” account, for example, will not be able to leave running
|
||||
processes that use the camera subsystem when the user has switched to a different account.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="behavior-runtime">Runtime</h2>
|
||||
<p>The ART runtime now properly implements access rules for the
|
||||
{@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()} method. This
|
||||
change fixes a problem where Dalvik was checking access rules incorrectly in previous versions.
|
||||
If your app uses the
|
||||
{@link java.lang.reflect.Constructor#newInstance(java.lang.Object...) newInstance()} method and you
|
||||
want to override access checks, call the
|
||||
{@link java.lang.reflect.Constructor#setAccessible(boolean) setAccessible()} method with the input
|
||||
parameter set to {@code true}. If your app uses the
|
||||
<a href="{@docRoot}tools/support-library/features.html#v7-appcompat">v7 appcompat library</a> or the
|
||||
<a href="{@docRoot}tools/support-library/features.html#v7-recyclerview">v7 recyclerview library</a>,
|
||||
you must update your app to use to the latest versions of these libraries. Otherwise, make sure that
|
||||
any custom classes referenced from XML are updated so that their class constructors are accessible.</p>
|
||||
|
||||
<p>This preview updates the behavior of the dynamic linker. The dynamic linker now understands the
|
||||
difference between a library’s {@code soname} and its path
|
||||
(<a href="https://code.google.com/p/android/issues/detail?id=6670" class="external-link">
|
||||
public bug 6670</a>), and search by {@code soname} is now
|
||||
implemented. Apps which previously worked that have bad {@code DT_NEEDED} entries
|
||||
(usually absolute paths on the build machine’s file system) may fail when loaded.</p>
|
||||
|
||||
<p>The {@code dlopen(3) RTLD_LOCAL} flag is now correctly implemented. Note that
|
||||
{@code RTLD_LOCAL} is the default, so calls to {@code dlopen(3)} that didn’t explicitly use
|
||||
{@code RTLD_LOCAL} will be affected (unless your app explicitly used {@code RTLD_GLOBAL}). With
|
||||
{@code RTLD_LOCAL}, symbols will not be made available to libraries loaded by later calls to
|
||||
{@code dlopen(3)} (as opposed to being referenced by {@code DT_NEEDED} entries).</p>
|
||||
</p>
|
||||
|
||||
<h2 id="behavior-hardware-id">Access to Hardware Identifier</h2>
|
||||
<p>To provide users with greater data protection, starting in this release, Android
|
||||
removes programmatic access to the device’s local hardware identifier for
|
||||
apps using the Wi-Fi and Bluetooth APIs. The
|
||||
{@link android.net.wifi.WifiInfo#getMacAddress() WifiInfo.getMacAddress()} and the
|
||||
{@link android.bluetooth.BluetoothAdapter#getAddress() BluetoothAdapter.getAddress()} methods
|
||||
now return a constant value of {@code 02:00:00:00:00:00}.</p>
|
||||
|
||||
<p>To access the hardware identifiers of nearby external devices via Bluetooth and Wi-Fi scans,
|
||||
your app must now have the following permissions:</p>
|
||||
<ul>
|
||||
<li>{@link android.net.wifi.WifiManager#getScanResults() WifiManager.getScanResults()}:
|
||||
Your app must have {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
|
||||
{@link android.Manifest.permission#ACCESS_COARSE_LOCATION} permission.</li>
|
||||
<li>{@link android.bluetooth.BluetoothDevice#ACTION_FOUND BluetoothDevice.ACTION_FOUND}:
|
||||
Your app must have {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} permission.</li>
|
||||
<li>{@link android.bluetooth.le.BluetoothLeScanner#startScan(android.bluetooth.le.ScanCallback)
|
||||
BluetoothLeScanner.startScan()}: Your app must have
|
||||
{@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
|
||||
{@link android.Manifest.permission#ACCESS_COARSE_LOCATION} permission.</li>
|
||||
</ul>
|
||||
|
||||
<p class="note"><strong>Note</strong>: When a device running M Developer Preview initiates a
|
||||
background Wi-Fi or Bluetooth scan, the operation is visible to external devices as
|
||||
originating from a randomized MAC address.</p>
|
||||
|
||||
<h2 id="behavior-apk-validation">APK Validation</h2>
|
||||
<p>The platform now performs stricter validation of APKs. An APK is considered corrupt if a file is
|
||||
declared in the manifest but not present in the APK itself. An APK must be re-signed if any of the
|
||||
contents are removed.</p>
|
||||
|
||||
<h2 id="behavior-usb">USB Connection</h2>
|
||||
<p>Device connections through the USB port are now set to charge-only mode by default. To access
|
||||
the device and its content over a USB connection, users must explicitly grant permission for such
|
||||
interactions. If your app supports user interactions with the device over a USB port, take into
|
||||
consideration that the interaction must be explicitly enabled.
|
||||
</p>
|
||||
|
||||
<h2 id="behavior-afw">Android for Work Changes</h2>
|
||||
<p>This preview includes the following behavior changes for Android for Work:</p>
|
||||
<ul>
|
||||
<li><strong>Work contacts in personal contexts.</strong> The Google Dialer
|
||||
Call Log now displays work contacts when the user views past calls.
|
||||
Setting
|
||||
{@link android.app.admin.DevicePolicyManager#setCrossProfileCallerIdDisabled(android.content.ComponentName, boolean) setCrossProfileCallerIdDisabled()}
|
||||
to {@code true} hides the work profile contacts in the Google Dialer Call Log. Work contacts can be
|
||||
displayed along with personal contacts to devices over Bluetooth only if
|
||||
you set {@link android.app.admin.DevicePolicyManager#setBluetoothContactSharingDisabled(android.content.ComponentName, boolean)
|
||||
setBluetoothContactSharingDisabled()} to {@code false}. By default, it is set to {@code true}.
|
||||
</li>
|
||||
<li><strong>Wi-Fi configuration removal:</strong> Wi-Fi configurations added by a Profile Owner
|
||||
(for example, through calls to the
|
||||
{@link android.net.wifi.WifiManager#addNetwork(android.net.wifi.WifiConfiguration)
|
||||
addNetwork()} method) are now removed if that work profile is deleted.
|
||||
</li>
|
||||
<li><strong>Wi-Fi configuration lockdown:</strong> Any Wi-Fi configuration created by
|
||||
an active Device Owner can no longer be modified or deleted by the user if
|
||||
{@link android.provider.Settings.Global#WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN} is non-zero.
|
||||
The user can still create and modify their own Wi-Fi configurations. Active Device
|
||||
Owners have the privilege of editing or removing any Wi-Fi configurations, including
|
||||
those not created by them.
|
||||
</li>
|
||||
<li><strong>Download Work Policy Controller via Google account addition:</strong> When a Google
|
||||
account that requires management via a Work Policy Controller (WPC) app is added to a device
|
||||
outside of a managed context, the add account flow now prompts the user to install the
|
||||
appropriate WPC. This behavior also applies to accounts added via
|
||||
<strong>Settings > Accounts</strong> and in the initial device setup wizard.</li>
|
||||
<li><strong>Changes to specific {@link android.app.admin.DevicePolicyManager} API behaviors:</strong>
|
||||
<ul>
|
||||
<li>Calling the
|
||||
{@link android.app.admin.DevicePolicyManager#setCameraDisabled(android.content.ComponentName,boolean) setCameraDisabled()}
|
||||
method affects the camera for the calling user only; calling it from the managed profile doesn’t
|
||||
affect camera apps running on the primary user.</li>
|
||||
<li>In addition, the
|
||||
{@link android.app.admin.DevicePolicyManager#setKeyguardDisabledFeatures(android.content.ComponentName,int) setKeyguardDisabledFeatures()}
|
||||
method is now available for Profile Owners, as well as to Device Owners. </li>
|
||||
<li>A Profile Owner can set these keyguard restrictions:
|
||||
<ul>
|
||||
<li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_TRUST_AGENTS} and
|
||||
{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_FINGERPRINT}, which affect the
|
||||
keyguard settings for the profile’s parent user.</li>
|
||||
<li>{@link android.app.admin.DevicePolicyManager#KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS}, which
|
||||
only affects notifications generated by applications in the managed profile.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>The {@link android.app.admin.DevicePolicyManager#createAndInitializeUser(android.content.ComponentName, java.lang.String, java.lang.String, android.content.ComponentName, android.os.Bundle) createAndInitializeUser()} and {@link android.app.admin.DevicePolicyManager#createUser(android.content.ComponentName, java.lang.String) createUser()} methods have been deprecated.</li>
|
||||
<li>The {@link android.app.admin.DevicePolicyManager#setScreenCaptureDisabled(android.content.ComponentName, boolean) setScreenCaptureDisabled()}
|
||||
method now also blocks the assist structure when an app of the given user is in the foreground. </li>
|
||||
<li>{@link android.app.admin.DevicePolicyManager#EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM}
|
||||
now defaults to SHA-256. SHA-1 is still supported for backwards compatibility but will be removed
|
||||
in future.
|
||||
{@link android.app.admin.DevicePolicyManager#EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM}
|
||||
now only accepts SHA-256.</li>
|
||||
<li>Device initializer APIs which existed in the M Developer Preview are now removed.</li>
|
||||
<li><code>EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS</code> is removed so NFC bump
|
||||
provisioning cannot programmatically unlock a factory reset protected device.</li>
|
||||
<li>You can now use the {@link android.app.admin.DevicePolicyManager#EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}
|
||||
extra to pass data to the device owner app during NFC provisioning of the managed device.</li>
|
||||
<li>Android for Work APIs are optimized for M runtime permissions, including Work profiles,
|
||||
assist layer, and others. New {@link android.app.admin.DevicePolicyManager} permission APIs don't
|
||||
affect pre-M apps.</li>
|
||||
<li>When users back out of the synchronous part of the setup flow initiated through an
|
||||
{@link android.app.admin.DevicePolicyManager#ACTION_PROVISION_MANAGED_PROFILE} or
|
||||
{@link android.app.admin.DevicePolicyManager#ACTION_PROVISION_MANAGED_DEVICE} intent, the system
|
||||
now returns a {@link android.app.Activity#RESULT_CANCELED} result code.</li>
|
||||
</ul></li>
|
||||
|
||||
<li><strong>Changes to other APIs</strong>:
|
||||
<ul>
|
||||
<li>Data Usage: The {@code android.app.usage.NetworkUsageStats} class has been renamed
|
||||
{@link android.app.usage.NetworkStats}.</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li><strong>Changes to global settings</strong>:
|
||||
<ul>
|
||||
<li>These settings can no longer be set via {@link android.app.admin.DevicePolicyManager#setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String) setGlobalSettings()}</code>:
|
||||
<ul>
|
||||
<li><code>BLUETOOTH_ON</code></li>
|
||||
<li><code>DEVELOPMENT_SETTINGS_ENABLED</code></li>
|
||||
<li><code>MODE_RINGER</code></li>
|
||||
<li><code>NETWORK_PREFERENCE</code></li>
|
||||
<li><code>WIFI_ON</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>These global settings can now be set via {@link android.app.admin.DevicePolicyManager#setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String) setGlobalSettings()}:
|
||||
<ul>
|
||||
<li>{@link android.provider.Settings.Global#WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN}</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
This page is under construction. For now,
|
||||
<a href="https://docs.google.com/document/d/1TA8Vzoa7KQ99bj1GVD81ps3Ux4wY0Ctkz7dC7bNnslU/edit">this
|
||||
doc</a> contains information on upcoming behavior changes.
|
||||
</p>
|
||||
@@ -1,4 +1,4 @@
|
||||
page.title=Downloads
|
||||
page.title=Image Downloads and OTA Updates
|
||||
page.image=images/cards/card-download_16-9_2x.png
|
||||
meta.tags="preview", "system image"
|
||||
page.tags="preview", "developer preview"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
page.title=N Developer Preview Background Optimizations
|
||||
page.title=Background Optimizations
|
||||
page.metaDescription=New restrictions to implicit broadcasts.
|
||||
page.keywords="android N", "implicit broadcasts", "job scheduler"
|
||||
@jd:body
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
page.title=N Developer Preview Data Saver
|
||||
page.title=Data Saver
|
||||
metaDescription=User-enabled data usage optimization.
|
||||
page.keywords="android N", "data usage", "metered network"
|
||||
@jd:body
|
||||
@@ -143,4 +143,4 @@ if (connMgr.isActiveNetworkMetered()) {
|
||||
android.content.Context#registerReceiver Context.registerReceiver()}. Apps
|
||||
that register to receive this broadcast in their manifest will not receive
|
||||
them.
|
||||
</p>
|
||||
</p>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
page.title=Using ICU4J Android Framework APIs
|
||||
page.title=ICU4J Support in Framework
|
||||
|
||||
@jd:body
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
page.title=N Developer Preview Multi-Window Support
|
||||
page.title=Multi-Window Support
|
||||
page.metaDescription=New support in the N Developer Preview for showing more than one app at a time.
|
||||
page.keywords="multi-window", "android N", "split screen", "free-form"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
page.title=Supporting Multilingual Users
|
||||
page.title=Language and Locale
|
||||
@jd:body
|
||||
|
||||
<div id="tb-wrapper">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
page.title=N Developer Preview Notification Features
|
||||
page.title=Bundled Notifications
|
||||
page.tags=notifications
|
||||
helpoutsWidget=true
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
page.title=Android TV Recording APIs
|
||||
page.title=TV Recording APIs
|
||||
page.keywords=preview,sdk,tv,recording
|
||||
page.tags=androidn
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
page.title=Permission changes
|
||||
page.title=Permissions
|
||||
page.metaDescription=Updates to permissions in the N Developer Preview.
|
||||
page.keywords="android N", "permissions"
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
ru-lang="Настройка пакета SDK Preview"
|
||||
zh-cn-lang="设置预览版 SDK"
|
||||
zh-tw-lang="設定預覽版 SDK">
|
||||
Preview SDK</a></div>
|
||||
SDK Setup</a></div>
|
||||
</li>
|
||||
|
||||
|
||||
@@ -28,6 +28,11 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="nav-section">
|
||||
<div class="nav-section-header"><a href="<?cs var:toroot ?>preview/behavior-changes.html"
|
||||
es-lang="Cambios en los comportamientos"
|
||||
@@ -39,12 +44,14 @@
|
||||
zh-tw-lang="行為變更">Behavior Changes
|
||||
</a></div>
|
||||
<ul>
|
||||
<li><a href="<?cs var:toroot ?>preview/doze-lite.html"
|
||||
>Doze Lite</a></li>
|
||||
<li><a href="<?cs var:toroot ?>preview/background-check.html"
|
||||
>Background Check</a></li>
|
||||
<li><a href="<?cs var:toroot ?>preview/direct-boot.html"
|
||||
>Direct Boot</a></li>
|
||||
<li><a href="<?cs var:toroot ?>preview/features/background-optimization.html"
|
||||
>Background Optimizations</a></li>
|
||||
<li><a href="<?cs var:toroot ?>preview/features/notification-updates.html"
|
||||
>Bundled Notifications</a></li>
|
||||
<li><a href="<?cs var:toroot ?>preview/features/multilingual-support.html"
|
||||
>Language and Locale</a></li>
|
||||
<li><a href="<?cs var:toroot ?>preview/permission-changes.html"
|
||||
>Permissions</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
@@ -59,28 +66,34 @@
|
||||
zh-tw-lang="API 總覽">New APIs and Features
|
||||
</a></div>
|
||||
<ul>
|
||||
<li><a href="<?cs var:toroot ?>preview/multiwindow.html"
|
||||
>Multiwindow Support</a></li>
|
||||
<li><a href="<?cs var:toroot ?>preview/notifications.html"
|
||||
>Notification Enhancements</a></li>
|
||||
<li><a href="<?cs var:toroot ?>preview/scoped-access.html"
|
||||
>Scoped Access to Files & Folders</a></li>
|
||||
<li><a href="<?cs var:toroot ?>preview/quicksettings.html"
|
||||
>Quick Settings</a></li>
|
||||
|
||||
<li><a href="<?cs var:toroot ?>preview/features/multi-window.html"
|
||||
>Multi-Window Support</a></li>
|
||||
|
||||
<li><a href="<?cs var:toroot ?>preview/features/data-saver.html"
|
||||
>Data Saver</a></li>
|
||||
|
||||
<li><a href="<?cs var:toroot ?>preview/features/tv-recording-api.html"
|
||||
>TV Recording APIs</a></li>
|
||||
|
||||
<li><a href="<?cs var:toroot ?>preview/features/icu4j-framework.html"
|
||||
>ICU4J Support in Framework</a></li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="nav-section">
|
||||
<div class="nav-section-header empty"><a href="<?cs var:toroot ?>preview/testing/guide.html"
|
||||
es-lang="Guía de prueba"
|
||||
ja-lang="テストガイド"
|
||||
ko-lang="테스트 가이드"
|
||||
pt-br-lang="Guia de teste"
|
||||
ru-lang="Руководство по тестированию"
|
||||
zh-cn-lang="测试指南"
|
||||
zh-tw-lang="測試指南">
|
||||
Testing Guide</a></div>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="nav-section">
|
||||
@@ -95,20 +108,15 @@
|
||||
Samples</a></div>
|
||||
</li>
|
||||
|
||||
<li class="nav-section">
|
||||
<div class="nav-section-header empty"><a href="<?cs var:toroot ?>preview/ota.html"
|
||||
>Device Image Downloads</a></div>
|
||||
</li>
|
||||
|
||||
<li class="nav-section">
|
||||
<div class="nav-section-header empty"><a href="<?cs var:toroot ?>preview/download.html"
|
||||
>OTA Device Updates</a></div>
|
||||
>Image Downloads and OTA Updates</a></div>
|
||||
</li>
|
||||
|
||||
|
||||
<li class="nav-section">
|
||||
<div class="nav-section-header empty"><a href="<?cs var:toroot ?>preview/support.html">
|
||||
Support & Release Notes</a></div>
|
||||
Support and Release Notes</a></div>
|
||||
</li>
|
||||
|
||||
<li class="nav-section">
|
||||
|
||||
Reference in New Issue
Block a user