| page.title=Behavior Changes | |
| page.keywords=preview,sdk,compatibility | |
| meta.tags="preview", "compatibility" | |
| 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> | |
| <li><a href="#perf">Performance Improvements</a> | |
| <ol> | |
| <li><a href="#doze">Doze</a></li> | |
| <li><a href="#bg-opt">Background Optimizations</a></li> | |
| </ol> | |
| </li> | |
| <li><a href="#perm">Permissions Changes</a> | |
| </li> | |
| <li><a href="#sharing-files">Sharing Files Between Apps</a></li> | |
| <li><a href="#accessibility">Accessibility Improvements</a> | |
| <ol> | |
| <li><a href="#screen-zoom">Screen Zoom</a></li> | |
| <li><a href="#vision-settings">Vision Settings in Setup Wizard</a></li> | |
| </ol> | |
| </li> | |
| <li><a href="#ndk">NDK Apps Linking to Platform Libraries</a></li> | |
| <li><a href="#afw">Android for Work</a></li> | |
| <li><a href="#annotations">Annotations Retention</a></li> | |
| <li><a href="#other">Other Important Points</a></li> | |
| </ol> | |
| <h2>API Differences</h2> | |
| <ol> | |
| <li><a href="{@docRoot}sdk/api_diff/n-preview-4-incr/changes.html"> | |
| Preview 3 to API 24</a></li> | |
| <li><a href="{@docRoot}sdk/api_diff/24/changes.html"> | |
| API 23 to API 24</a></li> | |
| </ol> | |
| <h2>See Also</h2> | |
| <ol> | |
| <li><a href="{@docRoot}preview/api-overview.html"> | |
| Android N for Developers</a></li> | |
| </ol> | |
| </div> | |
| </div> | |
| <p> | |
| Along with new features and capabilities, Android N | |
| includes a variety of system 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 your app | |
| might be affected by these changes in the platform. | |
| </p> | |
| <h2 id="perf">Battery and Memory</h2> | |
| <p> | |
| Android N includes system behavior changes aimed at improving the battery life | |
| of devices and reducing RAM usage. These changes can affect your app’s access to | |
| system resources, along with the way your app interacts with other apps via | |
| certain implicit intents. | |
| </p> | |
| <h3 id="doze">Doze</h3> | |
| <p> | |
| Introduced in Android 6.0 (API level 23), Doze improves battery life by | |
| deferring CPU and network activities when a user leaves a device unplugged, | |
| stationary, and with the screen turned off. Android N brings further | |
| enhancements to Doze by applying a subset of CPU and network restrictions | |
| while the device is unplugged with the screen turned off, but not necessarily | |
| stationary, for example, when a handset is traveling in a user’s pocket. | |
| </p> | |
| <img src="{@docRoot}preview/images/doze-diagram-1.png" | |
| alt="" height="251px" id="figure1" /> | |
| <p class="img-caption"> | |
| <strong>Figure 1.</strong> Illustration of how Doze applies a first level of | |
| system activity restrictions to improve battery life. | |
| </p> | |
| <p> | |
| When a device is on battery power, and the screen has been off for a certain | |
| time, the device enters Doze and applies the first subset of restrictions: It | |
| shuts off app network access, and defers jobs and syncs. If the device is | |
| stationary for a certain time after entering Doze, the system applies the | |
| rest of the Doze restrictions to {@link android.os.PowerManager.WakeLock}, | |
| {@link android.app.AlarmManager} alarms, GPS, and Wi-Fi scans. Regardless of | |
| whether some or all Doze restrictions are being applied, the system wakes the | |
| device for brief maintenance windows, during which applications are allowed | |
| network access and can execute any deferred jobs/syncs. | |
| </p> | |
| <img src="{@docRoot}preview/images/doze-diagram-2.png" | |
| alt="" id="figure2" /> | |
| <p class="img-caption"> | |
| <strong>Figure 2.</strong> Illustration of how Doze applies a second level of | |
| system activity restrictions after the device is stationary for a certain time. | |
| </p> | |
| <p> | |
| Note that activating the screen on or plugging in the device exits Doze and | |
| removes these processing restrictions. The additional behavior does not | |
| affect recommendations and best practices in adapting your app to the prior | |
| version of Doze introduced in Android 6.0 (API level 23), as discussed in | |
| <a href="{@docRoot}training/monitoring-device-state/doze-standby.html"> | |
| Optimizing for Doze and App Standby</a>. You should still | |
| follow those recommendations, such as using Google Cloud Messaging (GCM) to | |
| send and receive messages, and start planning updates to accomodate the | |
| additional Doze behavior. | |
| </p> | |
| <h3 id="bg-opt">Project Svelte: Background Optimizations</h3> | |
| <p> | |
| Android N removes three implicit broadcasts in order to help optimize both | |
| memory use and power consumption. This change is necessary because implicit | |
| broadcasts frequently start apps that have registered to listen for them in | |
| the background. Removing these broadcasts can substantially benefit device | |
| performance and user experience. | |
| </p> | |
| <p> | |
| Mobile devices experience frequent connectivity changes, such as when moving | |
| between Wi-Fi and mobile data. Currently, apps can monitor for changes in | |
| connectivity by registering a receiver for the implicit {@link | |
| android.net.ConnectivityManager#CONNECTIVITY_ACTION} broadcast in their | |
| manifest. Since many apps register to receive this broadcast, a single | |
| network switch can cause them all to wake up and process the broadcast at | |
| once. | |
| </p> | |
| <p> | |
| Similarly, in previous versions of Android, apps could register to receive implicit {@link | |
| android.hardware.Camera#ACTION_NEW_PICTURE} and {@link | |
| android.hardware.Camera#ACTION_NEW_VIDEO} broadcasts from other apps, such as | |
| Camera. When a user takes a picture with the Camera app, these apps wake up | |
| to process the broadcast. | |
| </p> | |
| <p> | |
| To alleviate these issues, Android N applies the following | |
| optimizations: | |
| </p> | |
| <ul> | |
| <li>Apps targeting Android N do not receive {@link | |
| android.net.ConnectivityManager#CONNECTIVITY_ACTION} broadcasts, even if they | |
| have manifest entries to request notification of these events. Apps that are | |
| running can still listen for {@code CONNECTIVITY_CHANGE} on their main thread | |
| if they request notification with a {@link android.content.BroadcastReceiver}. | |
| </li> | |
| <li>Apps cannot send or receive {@link | |
| android.hardware.Camera#ACTION_NEW_PICTURE} or {@link | |
| android.hardware.Camera#ACTION_NEW_VIDEO} broadcasts. This optimization | |
| affects all apps, not only those targeting Android N. | |
| </li> | |
| </ul> | |
| <p>If your app uses any of these intents, you should remove dependencies | |
| on them as soon as possible so that you can target Android N devices properly. | |
| The Android framework provides several solutions to mitigate the need for | |
| these implicit broadcasts. For example, the {@link | |
| android.app.job.JobScheduler} API provides a robust mechanism to schedule | |
| network operations when specified conditions, such as connection to an | |
| unmetered network, are met. You can even use {@link | |
| android.app.job.JobScheduler} to react to changes to content providers. | |
| </p> | |
| <p> | |
| For more information about background optimizations in N and how to adapt your app, | |
| see <a href= | |
| "{@docRoot}preview/features/background-optimization.html">Background | |
| Optimizations</a>. | |
| </p> | |
| <h2 id="perm">Permissions Changes</h2> | |
| <p> | |
| Android N includes changes to permissions that may affect your app. | |
| </p> | |
| <h3 id="permfilesys">File system permission changes</h3> | |
| <p> | |
| In order to improve the security of private files, the private directory of | |
| apps targeting Android N or higher has restricted access (<code>0700</code>). | |
| This setting prevents leakage of metadata of private files, such as their size | |
| or existence. This permission change has multiple side effects: | |
| </p> | |
| <ul> | |
| <li> | |
| Private files’ file permissions should no longer be relaxed by the owner, | |
| and an attempt to do so using | |
| {@link android.content.Context#MODE_WORLD_READABLE} and/or | |
| {@link android.content.Context#MODE_WORLD_WRITEABLE}, will trigger a | |
| {@link java.lang.SecurityException}. | |
| <p class="note"> | |
| <strong>Note:</strong> As of yet, this restriction is not fully enforced. | |
| Apps may still modify permissions to their private directory using | |
| native APIs or the {@link java.io.File File} API. However, we strongly | |
| discourage relaxing the permissions to the private directory. | |
| </p> | |
| </li> | |
| <li> | |
| Passing <code>file://</code> URIs outside the package domain may leave the | |
| receiver with an unaccessible path. Therefore, attempts to pass a | |
| <code>file://</code> URI trigger a | |
| <code>FileUriExposedException</code>. The recommended way to share the | |
| content of a private file is using the {@link | |
| android.support.v4.content.FileProvider}. | |
| </li> | |
| <li> | |
| The {@link android.app.DownloadManager} can no longer share privately | |
| stored files by filename. Legacy applications may end up with an | |
| unaccessible path when accessing {@link | |
| android.app.DownloadManager#COLUMN_LOCAL_FILENAME}. Apps targeting | |
| Android N or higher trigger a {@link java.lang.SecurityException} when | |
| attempting to access | |
| {@link android.app.DownloadManager#COLUMN_LOCAL_FILENAME}. | |
| Legacy applications that set the download location to a public location by | |
| using | |
| {@link | |
| android.app.DownloadManager.Request#setDestinationInExternalFilesDir | |
| DownloadManager.Request.setDestinationInExternalFilesDir()} or | |
| {@link | |
| android.app.DownloadManager.Request#setDestinationInExternalPublicDir | |
| DownloadManager.Request.setDestinationInExternalPublicDir()} | |
| can still access the path in | |
| {@link android.app.DownloadManager#COLUMN_LOCAL_FILENAME}, however, this | |
| method is strongly discouraged. The preferred way of accessing a file | |
| exposed by the {@link android.app.DownloadManager} is using | |
| {@link android.content.ContentResolver#openFileDescriptor | |
| ContentResolver.openFileDescriptor()}. | |
| </li> | |
| </ul> | |
| <h2 id="sharing-files">Sharing Files Between Apps</h2> | |
| <p> | |
| For apps targeting Android N, the Android framework enforces | |
| the {@link android.os.StrictMode} API policy that prohibits exposing {@code file://} URIs | |
| outside your app. If an intent containing a file URI leaves your app, the app fails | |
| with a {@code FileUriExposedException} exception. | |
| </p> | |
| <p> | |
| To share files between applications, you should send a {@code content://} URI | |
| and grant a temporary access permission on the URI. The easiest way to grant this permission is by | |
| using the {@link android.support.v4.content.FileProvider} class. For more information | |
| on permissions and sharing files, | |
| see <a href="{@docRoot}training/secure-file-sharing/index.html">Sharing Files</a>. | |
| </p> | |
| <h2 id="accessibility">Accessibility Improvements</h2> | |
| <p> | |
| Android N includes changes intended to improve the usability of the | |
| platform for users with low or impaired vision. These changes should | |
| generally not require code changes in your app, however you should review | |
| these feature and test them with your app to assess potential impacts to user | |
| experience. | |
| </p> | |
| <h3 id="screen-zoom">Screen Zoom</h3> | |
| <p> | |
| Android N enables users to set <strong>Display size</strong>which magnifies | |
| or shrinks all elements on the screen, thereby improving device accessibility | |
| for users with low vision. Users cannot zoom the screen past a minimum screen | |
| width of <a href= | |
| "http://developer.android.com/guide/topics/resources/providing-resources.html"> | |
| sw320dp</a>, which is the width of a Nexus 4, a common medium-sized phone. | |
| </p> | |
| <div class="cols"> | |
| <div class="col-6"> | |
| <img src="{@docRoot}preview/images/screen-zoom-1.png" alt="" height="XXX" id="figure1" /> | |
| </div> | |
| <div class="col-6"> | |
| <img src="{@docRoot}preview/images/screen-zoom-2.png" alt="" height="XXX" id="figure1" /> | |
| </div> | |
| </div> <!-- end cols --> | |
| <p class="img-caption"> | |
| <strong>Figure 3.</strong> The screen on the right shows the effect of | |
| increasing the Display size of a device running an Android N system image. | |
| </p> | |
| <p> | |
| When the device density changes, the system notifies running apps in the | |
| following ways: | |
| </p> | |
| <ul> | |
| <li>If an app targets API level 23 or lower, the system automatically kills | |
| all its background processes. This means that if a user switches away from | |
| such an app to open the <em>Settings</em> screen and changes the | |
| <strong>Display size</strong> setting, the system kills the app in the same | |
| manner that it would in a low-memory situation. If the app has any foreground | |
| processes, the system notifies those processes of the configuration change as | |
| described in <a href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling | |
| Runtime Changes</a>, just as if the device's orientation had changed. | |
| </li> | |
| <li>If an app targets Android N, all of its processes | |
| (foreground and background) are notified of the configuration change as | |
| described in <a href= | |
| "{@docRoot}guide/topics/resources/runtime-changes.html">Handling | |
| Runtime Changes</a>. | |
| </li> | |
| </ul> | |
| <p> | |
| Most apps do not need to make any changes to support this feature, provided | |
| the apps follow Android best practices. Specific things to check for: | |
| </p> | |
| <ul> | |
| <li>Test your app on a device with screen width <code><a href= | |
| "{@docRoot}guide/topics/resources/providing-resources.html">sw320dp</a></code> | |
| and be sure it performs adequately. | |
| </li> | |
| <li>When the device configuration changes, update any density-dependent | |
| cached information, such as cached bitmaps or resources loaded from the | |
| network. Check for configuration changes when the app resumes from the paused | |
| state. | |
| <p class="note"> | |
| <strong>Note:</strong> If you cache configuration-dependent data, it's a | |
| good idea to include relevant metadata such as the appropriate screen | |
| size or pixel density for that data. Saving this metadata allows you to | |
| decide whether you need to refresh the cached data after a configuration | |
| change. | |
| </p> | |
| </li> | |
| <li>Avoid specifying dimensions with px units, since they do not scale with | |
| screen density. Instead, specify dimensions with <a href= | |
| "{@docRoot}guide/practices/screens_support.html">density-independent | |
| pixel</a> (<code>dp</code>) units. | |
| </li> | |
| </ul> | |
| <h3 id="vision-settings">Vision Settings in Setup Wizard</h3> | |
| <p> | |
| Android N includes Vision Settings on the Welcome screen, where users can | |
| set up the following accessibility settings on a new device: | |
| <strong>Magnification gesture</strong>, <strong>Font size</strong>, | |
| <strong>Display size</strong> and <strong>TalkBack</strong>. This change | |
| increases the visibility of bugs related to different screen settings. To | |
| assess the impact of this feature, you should test your apps with these | |
| settings enabled. You can find the settings under <strong>Settings > | |
| Accessibility</strong>. | |
| </p> | |
| <h2 id="ndk">NDK Apps Linking to Platform Libraries</h2> | |
| <p> | |
| Starting in Android N, the system prevents apps from dynamically linking | |
| against non-NDK libraries, which may cause your app to crash. This change in | |
| behavior aims to create a consistent app experience across platform updates | |
| and different devices. Even though your code might not be linking against | |
| private libraries, it's possible that a third-party static library in your | |
| app could be doing so. Therefore, all developers should check to make sure | |
| that their apps do not crash on devices running Android N. If your app uses | |
| native code, you should only be using <a href= | |
| "{@docRoot}ndk/guides/stable_apis.html">public NDK APIs</a>. | |
| </p> | |
| <p> | |
| There are three ways your app might be trying to access private platform | |
| APIs: | |
| </p> | |
| <ul> | |
| <li>Your app directly accesses private platform libraries. You should update | |
| your app to include its own copy of those libraries or use the <a href= | |
| "{@docRoot}ndk/guides/stable_apis.html">public NDK APIs</a>. | |
| </li> | |
| <li>Your app uses a third-party library that accesses private platform | |
| libraries. Even if you are certain your app doesn't access private libraries | |
| directly, you should still test your app for this scenario. | |
| </li> | |
| <li>Your app references a library that is not included in its APK. For | |
| example, this could happen if you tried to use your own copy of OpenSSL but | |
| forgot to bundle it with your app's APK. The app may run normally on versions | |
| of Android platform that includes <code>libcrypto.so</code>. However, the app | |
| could crash on later versions of Android that do not include this library | |
| (such as, Android 6.0 and later). To fix this, ensure that you bundle all | |
| your non-NDK libraries with your APK. | |
| </li> | |
| </ul> | |
| <p> | |
| Apps should not use native libraries that are not included in the NDK because | |
| they may change or be removed between different versions of Android. The | |
| switch from OpenSSL to BoringSSL is an example of such a change. Also, | |
| because there are no compatibility requirements for platform libraries not | |
| included in the NDK, different devices may offer different levels of | |
| compatibility. | |
| </p> | |
| <p> | |
| In order to reduce the impact that this restriction may have on currently | |
| released apps, a set of libraries that see significant use—such as | |
| <code>libandroid_runtime.so</code>, <code>libcutils.so</code>, | |
| <code>libcrypto.so</code>, and <code>libssl.so</code>—are temporarily | |
| accessible on N for apps targeting API level 23 or lower. If your app loads | |
| one of these libraries, logcat generates a warning and a toast appears on the | |
| target device to notify you. If you see these warnings, you should update | |
| your app to either include its own copy of those libraries or only use the | |
| public NDK APIs. Future releases of the Android platform may restrict the use | |
| of private libraries altogether and cause your app to crash. | |
| </p> | |
| <p> | |
| All apps generate a runtime error when they call an API that is neither | |
| public nor temporarily accessible. The result is that | |
| <code>System.loadLibrary</code> and <code>dlopen(3)</code> both return | |
| <code>NULL</code>, and may cause your app to crash. You should review your | |
| app code to remove use of private platform APIs and thoroughly test your apps | |
| using a preview device or emulator. If you are unsure whether your app uses | |
| private libraries, you can <a href="#ndk-errors">check logcat</a> to identify | |
| the runtime error. | |
| </p> | |
| <p> | |
| The following table describes the behavior you should expect to see from an | |
| app depending on its use of private native libraries and its target API | |
| level (<code>android:targetSdkVersion</code>). | |
| </p> | |
| <table id="ndk-table"> | |
| <col width="15%"> | |
| <col width="15%"> | |
| <col width="15%"> | |
| <col width="20%"> | |
| <col width="20%"> | |
| <col width="20%"> | |
| <tr> | |
| <th scope="col"> | |
| Libraries | |
| </th> | |
| <th scope="col"> | |
| Target API level | |
| </th> | |
| <th scope="col"> | |
| Runtime access via dynamic linker | |
| </th> | |
| <th scope="col"> | |
| N Developer Preview behavior | |
| </th> | |
| <th scope="col"> | |
| Final N Release behavior | |
| </th> | |
| <th scope="col"> | |
| Future Android platform behavior | |
| </th> | |
| </tr> | |
| <tr> | |
| <td> | |
| NDK Public | |
| </td> | |
| <td> | |
| Any | |
| </td> | |
| <td style="background-color:#DCEDC8"> | |
| Accessible | |
| </td> | |
| <td style="background-color:#DCEDC8"> | |
| Works as expected | |
| </td> | |
| <td style="background-color:#DCEDC8"> | |
| Works as expected | |
| </td> | |
| <td style="background-color:#DCEDC8"> | |
| Works as expected | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| Private (temporarily accessible private libraries) | |
| </td> | |
| <td> | |
| 23 or lower | |
| </td> | |
| <td style="background-color:#FFF9C4"> | |
| Temporarily accessible | |
| </td> | |
| <td style="background-color:#FFF9C4"> | |
| Works as expected, but you receive a logcat warning and a message on the | |
| target device. | |
| </td> | |
| <td style="background-color:#FFF9C4"> | |
| Works as expected, but you receive a logcat warning. | |
| </td> | |
| <td style="background-color:#ffcdd2"> | |
| Runtime error | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| Private (temporarily accessible private libraries) | |
| </td> | |
| <td> | |
| 24 or higher | |
| </td> | |
| <td style="background-color:#ffcdd2"> | |
| Restricted | |
| </td> | |
| <td style="background-color:#ffcdd2"> | |
| Runtime error | |
| </td> | |
| <td style="background-color:#ffcdd2"> | |
| Runtime error | |
| </td> | |
| <td style="background-color:#ffcdd2"> | |
| Runtime error | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| Private (other) | |
| </td> | |
| <td> | |
| Any | |
| </td> | |
| <td style="background-color:#ffcdd2"> | |
| Restricted | |
| </td> | |
| <td style="background-color:#ffcdd2"> | |
| Runtime error | |
| </td> | |
| <td style="background-color:#ffcdd2"> | |
| Runtime error | |
| </td> | |
| <td style="background-color:#ffcdd2"> | |
| Runtime error | |
| </td> | |
| </tr> | |
| </table> | |
| <h3 id="ndk-errors"> | |
| Check if your app uses private libraries | |
| </h3> | |
| <p> | |
| To help you identify issues loading private libraries, logcat may generate a | |
| warning or runtime error. For example, if your app targets API level 23 or | |
| lower, and tries to access a private library on a device running Android N, | |
| you may see a warning similar to the following: | |
| </p> | |
| <pre class="no-pretty-print"> | |
| 03-21 17:07:51.502 31234 31234 W linker : library "libandroid_runtime.so" | |
| ("/system/lib/libandroid_runtime.so") needed or dlopened by | |
| "/data/app/com.popular-app.android-2/lib/arm/libapplib.so" is not accessible | |
| for the namespace "classloader-namespace" - the access is temporarily granted | |
| as a workaround for http://b/26394120 | |
| </pre> | |
| <p> | |
| These logcat warnings tell you which which library is trying to access a | |
| private platform API, but will not cause your app to crash. If the app | |
| targets API level 24 or higher, however, logcat generates the following | |
| runtime error and your app may crash: | |
| </p> | |
| <pre class="no-pretty-print"> | |
| java.lang.UnsatisfiedLinkError: dlopen failed: library "libcutils.so" | |
| ("/system/lib/libcutils.so") needed or dlopened by | |
| "/system/lib/libnativeloader.so" is not accessible for the namespace | |
| "classloader-namespace" | |
| at java.lang.Runtime.loadLibrary0(Runtime.java:977) | |
| at java.lang.System.loadLibrary(System.java:1602) | |
| </pre> | |
| <p> | |
| You may also see these logcat outputs if your app uses third-party libraries | |
| that dynamically link to private platform APIs. The readelf tool in the | |
| Android NDK allows you to generate a list of all dynamically linked shared | |
| libraries of a given <code>.so</code> file by running the following command: | |
| </p> | |
| <pre class="no-pretty-print"> | |
| aarch64-linux-android-readelf -dW libMyLibrary.so | |
| </pre> | |
| <h3 id="ndk-update"> | |
| Update your app | |
| </h3> | |
| <p> | |
| Here are some steps you can take to fix these types of errors and make | |
| sure your app doesn't crash on future platform updates: | |
| </p> | |
| <ul> | |
| <li> | |
| If your app uses private platform libraries, you should update it to include | |
| its own copy of those libraries or use the <a href= | |
| "{@docRoot}ndk/guides/stable_apis.html">public NDK APIs</a>. | |
| </li> | |
| <li> | |
| If your app uses a third-party library that accesses private symbols, contact | |
| the library author to update the library. | |
| </li> | |
| <li> | |
| Make sure you package all your non-NDK libraries with your APK. | |
| </li> | |
| <li>Use standard JNI functions instead of <code>getJavaVM</code> and | |
| <code>getJNIEnv</code> from <code>libandroid_runtime.so</code>: | |
| <pre class="no-pretty-print"> | |
| AndroidRuntime::getJavaVM -> GetJavaVM from <jni.h> | |
| AndroidRuntime::getJNIEnv -> JavaVM::GetEnv or | |
| JavaVM::AttachCurrentThread from <jni.h>. | |
| </pre> | |
| </li> | |
| <li>Use {@code __system_property_get} instead of the private {@code property_get} | |
| symbol from {@code libcutils.so}. To do this, use {@code __system_property_get} | |
| with the following include: | |
| <pre> | |
| #include <sys/system_properties.h> | |
| </pre> | |
| <p class="note"> | |
| <strong>Note:</strong> The availability and contents of system properties is | |
| not tested through CTS. A better fix would be to avoid using these | |
| properties altogether. | |
| </p> | |
| </li> | |
| <li>Use a local version of the {@code SSL_ctrl} symbol from {@code | |
| libcrypto.so}. For example, you should statically link {@code libcyrpto.a} in | |
| your {@code .so} file, or include a dynamically linked version of {@code | |
| libcrypto.so} from BoringSSL/OpenSSL and package it in your APK. | |
| </li> | |
| </ul> | |
| <h2 id="afw">Android for Work</h2> | |
| <p> | |
| Android N contains changes for apps that target Android for Work, including | |
| changes to certificate installation, password resetting, secondary user | |
| management, and access to device identifiers. If you are building apps for | |
| Android for Work environments, you should review these changes and modify | |
| your app accordingly. | |
| </p> | |
| <ul> | |
| <li>You must install a delegated certificate installer before the DPC can set | |
| it. For both profile and device-owner apps targeting the N SDK, you should | |
| install the delegated certificate installer before the device policy | |
| controller (DPC) calls | |
| <code>DevicePolicyManager.setCertInstallerPackage()</code>. If the installer | |
| is not already installed, the system throws an | |
| <code>IllegalArgumentException</code>. | |
| </li> | |
| <li>Reset password restrictions for device admins now apply to profile | |
| owners. Device admins can no longer use | |
| {@code DevicePolicyManager.resetPassword()} to clear passwords or change | |
| ones that are already set. Device admins can still set a password, but only | |
| when the device has no password, PIN, or pattern. | |
| </li> | |
| <li>Device and profile owners can manage accounts even if restrictions are | |
| set. Device owners and profile owners can call the Account Management APIs | |
| even if <code>DISALLOW_MODIFY_ACCOUNTS</code> user restrictions are in place. | |
| </li> | |
| <li>Device owners can manage secondary users more easily. When a device is | |
| running in device owner mode, the <code>DISALLOW_ADD_USER</code> restriction | |
| is automatically set. This prevents users from creating unmanaged secondary | |
| users. In addition, the <code>CreateUser()</code> and | |
| <code>createAndInitializeUser()</code> methods are deprecated; the new | |
| <code>DevicePolicyManager.createAndManageUser()</code> method replaces them. | |
| </li> | |
| <li>Device owners can access device identifiers. A Device owner can access the | |
| Wi-Fi MAC address of a device, using | |
| <code>DevicePolicyManagewr.getWifiMacAddress()</code>. If Wi-Fi has never | |
| been enabled on the device, this method returns a value of {@code null}. | |
| </li> | |
| <li>The Work Mode setting controls access to work apps. When work mode is off the | |
| system launcher indicates work apps are unavailable by greying them out. Enabling | |
| work mode again restores normal behavior.</li> | |
| <li>When installing a PKCS #12 file containing a client certificate chain and | |
| the corresponding private key from Settings UI, the CA certificate in the | |
| chain is no longer installed to the trusted credentials storage. This does | |
| not affect the result of {@link android.security.KeyChain#getCertificateChain | |
| KeyChain.getCertificateChain()} when apps attempt to retrieve the client | |
| certificate chain later. If required, the CA certificate should be installed | |
| to the trusted credentials storage via Settings UI separately, with a | |
| DER-encoded format under a .crt or .cer file extension. | |
| </li> | |
| </ul> | |
| <p> | |
| For more information about changes to Android for Work in Android N, see | |
| <a href="{@docRoot}preview/features/afw.html">Android for Work Updates</a>. | |
| </p> | |
| <h2 id="annotations">Annotations Retention</h2> | |
| <p> | |
| Android N fixes a bug where the visibility of annotations was being ignored. | |
| This issue enabled the runtime to access annotations that it should not have been | |
| able to. These annotations included: | |
| </p> | |
| <ul> | |
| <li>{@code VISIBILITY_BUILD}: Intended to be visible only at build time.</li> | |
| <li>{@code VISIBILITY_SYSTEM}: Intended to be visible at runtime, but only to the | |
| underlying system.</li> | |
| </ul> | |
| <p> | |
| If your app has relied on this behavior, please add a retention policy to annotations that must | |
| be available at runtime. You do so by using {@code @Retention(RetentionPolicy.RUNTIME)}. | |
| </p> | |
| <h2 id="other">Other Important Points</h2> | |
| <ul> | |
| <li>When an app is running on Android N, but targets a lower API level, | |
| and the user changes display size, the app process is killed. The app | |
| must be able to gracefully handle this scenario. Otherwise, it crashes | |
| when the user restores it from Recents. | |
| <p> | |
| You should test your app to ensure | |
| that this behavior does not occur. | |
| You can do so by causing an identical crash | |
| when killing the app manually via DDMS. | |
| </p> | |
| <p> | |
| Apps targeting N and above are not automatically killed on density changes; | |
| however, they may still respond poorly to configuration changes. | |
| </p> | |
| </li> | |
| <li> | |
| Apps on Android N should be able to gracefully handle configuration changes, | |
| and should not crash on subsequent starts. You can verify app behavior | |
| by changing font size (<strong>Setting</strong> > | |
| <strong>Display</strong> > <strong>Font size</strong>), and then restoring | |
| the app from Recents. | |
| </li> | |
| <li> | |
| Due to a bug in previous versions of Android, the system did not flag writing | |
| to a TCP socket on the main thread as a strict-mode violation. Android N fixes this bug. | |
| Apps that exhibit this behavior now throw an {@code android.os.NetworkOnMainThreadException}. | |
| Generally, performing network operations on the main thread is a bad idea because these operations | |
| usually have a high tail latency that causes ANRs and jank. | |
| </li> | |
| <li> | |
| The {@code Debug.startMethodTracing()} family of methods now defaults to | |
| storing output in your package-specific directory on shared storage, | |
| instead of at the top level | |
| of the SD card. This means apps no longer need to request the {@code WRITE_EXTERNAL_STORAGE} permission to use these APIs. | |
| </li> | |
| <li> | |
| Many platform APIs have now started checking for large payloads being sent | |
| across {@link android.os.Binder} transactions, and the | |
| system now rethrows {@code TransactionTooLargeExceptions} | |
| as {@code RuntimeExceptions}, instead of silently logging or suppressing them. One | |
| common example is storing too much data in | |
| {@link android.app.Activity#onSaveInstanceState Activity.onSaveInstanceState()}, | |
| which causes {@code ActivityThread.StopInfo} to throw a | |
| {@code RuntimeException} when your app targets Android N. | |
| </li> | |
| <li> | |
| If an app posts {@link java.lang.Runnable} tasks to a {@link android.view.View}, and | |
| the {@link android.view.View} | |
| is not attached to a window, the system | |
| queues the {@link java.lang.Runnable} task with the {@link android.view.View}; | |
| the {@link java.lang.Runnable} task does not execute until the | |
| {@link android.view.View} is attached | |
| to a window. This behavior fixes the following bugs: | |
| <ul> | |
| <li>If an app posted to a {@link android.view.View} from a thread other than the intended | |
| window’s UI thread, the {@link java.lang.Runnable} may run on the wrong thread as a result. | |
| </li> | |
| <li>If the {@link java.lang.Runnable} task was posted from a thread other than | |
| a looper thread, the app could expose the {@link java.lang.Runnable} task.</li> | |
| </ul> | |
| </li> | |
| <li> | |
| If an app on Android N with | |
| {@link android.Manifest.permission#DELETE_PACKAGES DELETE_PACKAGES} | |
| permission tries to delete a package, but a different app had installed that package, | |
| the system requires user confirmation. In this scenario, apps should expect | |
| {@link android.content.pm.PackageInstaller#STATUS_PENDING_USER_ACTION STATUS_PENDING_USER_ACTION} | |
| as the return status when they invoke | |
| {@link android.content.pm.PackageInstaller#uninstall PackageInstaller.uninstall()}. | |
| </li> | |
| <li>The JCA provider called <em>Crypto</em> is deprecated, because its only | |
| algorithm, SHA1PRNG, is cryptographically weak. Apps can no longer use | |
| SHA1PRNG to (insecurely) derive keys, because this provider is no longer | |
| available. For more information, see the blog | |
| post <a href= | |
| "http://android-developers.blogspot.com/2016/06/security-crypto-provider-deprecated-in.html" | |
| class="external-link">Security "Crypto" provider deprecated in Android | |
| N</a>. | |
| </li> | |
| </ul> | |