blob: 84a56d0614c5734f569388b69b7ab7dbdb664da0 [file] [log] [blame]
page.title=Android 7.0 Behavior Changes
page.keywords=preview,sdk,compatibility
meta.tags="Nougat", "android n", "compatibility"
page.tags="Android 7.0", "Nougat", "android n"
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/24/changes.html">
API 23 to API 24</a></li>
</ol>
<h2>See Also</h2>
<ol>
<li><a href="{@docRoot}about/versions/nougat/android-7.0.html">
Android 7.0 for Developers</a></li>
</ol>
</div>
</div>
<p>
Along with new features and capabilities, Android 7.0
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 7.0 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 7.0 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}images/android-7.0/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}images/android-7.0/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 7.0 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 7.0 applies the following
optimizations:
</p>
<ul>
<li>Apps targeting Android 7.0 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 7.0.
</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 7.0 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 7.0 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 7.0 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 7.0 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 7.0, 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 7.0 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 7.0 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}images/android-7.0/screen-zoom-1.png" alt="" height="XXX" id="figure1" />
</div>
<div class="col-6">
<img src="{@docRoot}images/android-7.0/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 7.0 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 7.0, 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 7.0 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 &gt;
Accessibility</strong>.
</p>
<h2 id="ndk">NDK Apps Linking to Platform Libraries</h2>
<p>
Starting in Android 7.0, 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 7.0. 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 7.0,
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 7.0DK 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 -&gt; GetJavaVM from &lt;jni.h&gt;
AndroidRuntime::getJNIEnv -&gt; JavaVM::GetEnv or
JavaVM::AttachCurrentThread from &lt;jni.h&gt;.
</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 &lt;sys/system_properties.h&gt;
</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 7.0 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>
<li>Starting in Android 7.0, fingerprint enrollment and storage are managed per user.
If a profile owner’s Device Policy Client (DPC) targets pre-N on an N device,
the user is still able to set fingerprint on the device, but work
applications cannot access device fingerprint. When the DPC targets N and
above, the user can set fingerprint specifically for work profile by going to
<strong>Settings &gt; Security &gt; Work profile security</strong>.
</li>
<li>A new encryption status <code>ENCRYPTION_STATUS_ACTIVE_PER_USER</code> is
returned by <code>DevicePolicyManager.getStorageEncryptionStatus()</code>, to
indicate that encryption is active and the encryption key is tied to the
user. The new status is only returned if DPC targets API Level 24 and above.
For apps targeting earlier API levels, <code>ENCRYPTION_STATUS_ACTIVE</code>
is returned, even if the encryption key is specific to the user or profile.
</li>
<li>In Android 7.0, several methods that would ordinarily affect the entire
device behave differently if the device has a work profile installed with a
separate work challenge. Rather than affecting the entire device, these
methods apply only to the work profile. (The complete list of such methods is
in the {@link android.app.admin.DevicePolicyManager#getParentProfileInstance
DevicePolicyManager.getParentProfileInstance()} documentation.) For example,
{@link android.app.admin.DevicePolicyManager#lockNow
DevicePolicyManager.lockNow()} locks just the work profile, instead of
locking the entire device. For each of these methods, you can get the old
behavior by calling the method on the parent instance of the
{@link android.app.admin.DevicePolicyManager}; you can get this parent by
calling {@link android.app.admin.DevicePolicyManager#getParentProfileInstance
DevicePolicyManager.getParentProfileInstance()}. So for example, if you call
the parent instance's {@link android.app.admin.DevicePolicyManager#lockNow}
method, the entire device is locked.
</li>
</ul>
<p>
For more information about changes to Android for Work in Android 7.0, see
<a href="{@docRoot}preview/features/afw.html">Android for Work Updates</a>.
</p>
<h2 id="annotations">Annotations Retention</h2>
<p>
Android 7.0 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 7.0, 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 7.0 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 7.0 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 7.0.
</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 7.0 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>