Android Oの挙動の変更点 抄訳と共にポイントをまとめてみた (Oをtargetにするアプリでの挙動変更編)

# Android O Behavior Changes

https://developer.android.com/preview/behavior-changes.html

Android Oの挙動の変更点についての説明ページが出てきたので、
抄訳と共にポイントをまとめてみた、の、「Oをtargetにするアプリでの挙動変更」編です。

[全てのAPI levelに影響するOの挙動変更編](http://qiita.com/hidenorly/items/3512d42811e1ca37a7de)はこちらです。

# targetSdkVersion=Oのアプリでの挙動変更 (Apps targeting Android O)

> These behavior changes apply exclusively to apps that are targeting the O platform or higher. Apps that compile against Android O or higher or set targetSdkVersion to Android O or higher must modify their apps to support these behaviors properly, where applicable to the app.

抄訳(+補足): これらの変更は、O以降向けのアプリ (targetSdkVersion=O以降)でのみ適用される変更です。AndroidO向けのアプリだったり、targetSdkVersionをAndroid Oやそれより上向けに設定してコンパイルするアプリは、対応可能なものは、これらの変更に適切にサポートするよう変更してください。

## バックグラウンド実行の制限 (Background execution limits)

> To improve device performance, the system limits certain behaviors by apps that are not running in the foreground. Specifically:

> * Apps that are running in the background now have limits on how freely they can access background services.
> * Apps cannot use their manifests to register for most implicit broadcasts (that is, broadcasts that are not targeted specifically at the app).
> For more information, see Background Execution Limits.

抄訳: 

デバイスのパフォーマンスを改善するため、システムは、フォアグラウンドで動作していないアプリに対して、ある挙動の制限を行います。とりわけ、

* バックグラウンドで動作しているアプリは、バックグラウンドサービスへのアクセスが制限されます。
* アプリは、ほとんどの暗黙的ブロードキャストインテントの登録をmanifestで行うことができなくなります(ほとんどの暗黙的なブロードキャストインテントとは、そのアプリ指定のものではないものという意味です。）

詳細に関しては、[バックグラウンド実行の制限(Background Execution Limits)](https://developer.android.com/preview/features/background.html)を参照のこと。

* 対象 : background serviceを持っている、あるいは、アクセスするもの
* 対策 : JobSchedulerなどによる間欠動作で代替 (foreground serviceにすると、notificationに出てしまうので、そういうのが許容されるものはそうするのも手)


## セキュリティ (Security)

> If your app's network security configuration opts out of supporting cleartext traffic, your app's WebView objects cannot access websites over HTTP. Each WebView object must use HTTPS instead.

> For additional guidelines on making your app more secure, see Security for Android Developers.

抄訳:

アプリのネットワークセキュリティについて、クリアテキストをオプトアウトするよう設定すると、WebViewオブジェクトは、HTTPでウェブサイトへのアクセスができなくなります。代わりに個々のWebViewオブジェクトは、HTTPSを必須で使う必要があります。

* 対象: HTTP(クリアテキスト)でアクセスする必要のあるアプリ
* 対策: 基本的に、HTTPSを使うことが推奨 (cleartextをopt outする設定で運用)だが、必要ならば、opt-inする


## プライバシー (Privacy)

> The following changes affect privacy in Android O.
>
> * The system properties net.dns1, net.dns2, net.dns3, and net.dns4 are no longer available, a change that improves privacy on the platform.
> * To obtain networking information such as DNS servers, apps with the ACCESS_NETWORK_STATE permission can register a NetworkRequest or NetworkCallback object. These classes are available in Android 5.0 (API level 21) and higher.
Build.SERIAL is no longer supported, and this field returns an undefined value starting from Android O. Apps needing to know the hardware serial number should instead use the new Build.getSerial() method, which requires the READ_PHONE_STATE permission.
> * The LauncherApps API no longer allows work profile apps to get information about the primary profile. When a user is in a work profile, the LauncherApps API behaves as if no apps are installed in other profiles within the same profile group. As before, attempts to access unrelated profiles causes SecurityExceptions.

抄訳:

Android Oでは以下のプライバシーに関する変更があります。

* プラットフォームとしてのプライバシー向上のため、システムプロパティ ```net.dns1, net.dns2, net.dns3, net.dns4``` は有効ではなくなります。
* DNSサーバーのようなネットワーク情報の取得には、```ACCESS_NETWORK_STATE``` パーミッションをアプリはリクエストする必要があり、```NetworkRequest``` や ```NetworkCallback``` オブジェクトを登録できるようになります。 これらのクラスは、Android 5.0 (API level 21)以降で利用可能です。
```Build.SERIAL```は、有効ではなくなります。Android Oからは、未定義値を返すようになります。ハードウェアのシリアル番号が取得が必要なアプリは、新しい ```Build.getSerial()``` メソッドを利用してください。なお、```READ_PHONE_STATE``` パーミッションが必要です。
> * ```LauncherApps``` APIは、ワークプロファイルアプリに対し、プライマリープロファイルの情報の取得を許さなくなります。ユーザーがワークプロファイルにいると、 ```LauncherApps`` API は、同じプロファイルグループ内の他のプロファイルには何もアプリがインストールされていないように振る舞います。以前のように、関係のないプロファイルへのアクセスは、```SecurityExceptions``` の例外が発生します。

* 対象: net.dnsのようなシステムプロパティを利用しているアプリ
* 対策: 代わりに、ACCESS_NETWORK_STATE permissionを利用して、API経由で取得する

* 対象: Build.SERIALを利用しているアプリ
* 対策: 代わりに、READ_PHONE_STATE permissionを利用して、API経由で取得する


## パーミッション (Permissions)

> Prior to Android O, if an app requested a permission at runtime and the permission was granted, the system also incorrectly granted the app the rest of the permissions that belonged to the same permission group, and that were registered in the manifest.

抄訳: Android以前で、実行時に、パーミッションのリクエストをしてそのパーミッションが許可されていましたが、同じパーミッショングループに属するパーミッションがmanifestに登録されているとそれらのパーミションも間違って許可されていました。

> For apps targeting Android O, this behavior has been corrected. The app is granted only the permissions it has explicitly requested. However, once the user grants a permission to the app, all subsequent requests for permissions in that permission group are automatically granted.

抄訳: O向けのアプリでは、この挙動が正されます。明示的にリクエストされたパーミッションだけが許可されるようになります。しかし、ひとたび、パーミッションがユーザにより許可されると、全てのそれに続いてそのパーミッショングループのパーミッションは自動的に許可されます。

> For example, suppose an app lists both READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE in its manifest. The app requests READ_EXTERNAL_STORAGE and the user grants it. If the app targets API level 24 or lower, the system also grants WRITE_EXTERNAL_STORAGE at the same time, because it belongs to the same STORAGE permission group and is also registered in the manifest. If the app targets Android O, the system grants only READ_EXTERNAL_STORAGE at that time; however, if the app later requests WRITE_EXTERNAL_STORAGE, the system immediately grants that privilege without prompting the user.

抄訳(+補足): 例えば、```READ_EXTERNAL_STORAGE```と```WRITE_EXTERNAL_STORAGE```がmanifestで宣言されているケースにおいて、アプリが```READ_EXTERNAL_STORAGE```をリクエストしユーザーに許可されるとします。アプリがAPI level 24以下向けでは、システムは、```WRITE_EXTERNAL_STORAGE```も同時に許可します。というのは、それが同じ```STORAGE```パーミッショングループに属し、それらがmanifestに登録されているからです。O向けのアプリ(targetSdkVersion=O以降)では、```READ_EXTERNAL_STORAGE```パーミッションだけが許可されます。しかし、仮にそのアプリがその後に、```WRITE_EXTERNAL_STORAGE``` をリクエストすると、システムはユーザへの確認なしに直ちにその権限を許可します。

* 対象: runtime permissionで、個々のpermissionをrequestするのが漏れているアプリ
* 対策: 利用するパーミッションはちゃんと個々にリクエストを発行する。

## メディア (Media)

> * The framework performs audio ducking. Applications do not lose focus in the case of AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK. New APIs are available for applications that need to pause instead of ducking. However, this behavior is not in Android O.

抄訳: フレームワークはオーディオに関してあれこれ行います。アプリケーションは```AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK```のケースではフォーカスを失いません。ポーズが必要なアプリケーション向けに、duckに変わる新APIが利用可能ですが、Android Oでは振る舞いが変わります。

> * When the user takes a phone call, active media streams mute for the duration of the call.

抄訳: ユーザが通話をすると、通話中はアクティブなメディアストリームはミュートされます。

> * Audio stream types should only be used for volume controls; all other uses of stream types (e.g AudioTrack constructor) still work, but the system will log this as an error.

抄訳: 全ての他のストリームタイプの利用は引き続き動作しますが、オーディオストリームは、ボリューム制御のためだけに使われるべきなので、システムはこれをエラーとしてログするようになります。

> * All audio-related APIs use AudioAttributes to describe the audio playback use case.

抄訳: 全てのオーディオ関係のAPIは、オーディオの再生ユースケースを記述するために、```AudioAttributes```を使います。

> * When using an AudioTrack, if the application requests a large enough audio buffer, the framework will try to use the deep buffer output if it is available.

抄訳: オーディオトラックを使うときは、アプリケーションが非常に大きいオーディオバッファーをリクエストするならば、フレームワークは可能ならば、その深い(大きいの意味)アウトプットバッファーを利用しようとします。


## ネイティブライブラリ (Native libraries)

> In apps targeting Android O, native libraries no longer load if they contain any load segment that is both writable and executable. Some apps might stop working because of this change if they have native libraries with incorrect load segments. This is a security-hardening measure.

抄訳: O向けのアプリでは、書き込み可能属性と実行属性の両方を含むセグメントがあるネイティブライブラリをロードすることができません。不正なロードセグメントがあるネイティブラリがある場合は、この変更により幾つかのアプリは動作が停止するかもしれません。

詳細に関しては、[書き込み可能属性と実行可能属性のセグメント(Writable and Executable Segments)](https://android.googlesource.com/platform/bionic/+/master/android-changes-for-ndk-developers.md#Writable-and-Executable-Segments-Enforced-for-API-level-26)参照のこと。

>As with earlier developer-preview releases, Android O also makes all linker-related problems more visible. Linker changes are tied to the API level that an app targets. If there is a linker change at the targeted API level, the app cannot load the library. If you are targeting an API level lower than the API level where the linker change occurs, logcat shows a warning. During a preview release, linker-related problems not only appear in logcat, but also show up as toasts. This change improves visibility of issues before the API level at which a warning becomes an error.

抄訳: デベロッパープレビューの早期リリース版では、Android Oは、全てのlinker関係の問題をより可視化します。linkerの変更は、APIレベルに紐付けられます。ターゲットのAPIレベルでlinkerの変更があると、そのライブラリーをロードすることができません。linkerの変更が起きるターゲットのAPIレベルよりも下のAPIレベル向けにしている場合、warningがlogcat経由で見れます。プレビューリリースの間、linker関係の問題はlogcatにだけあらわれるだけでなく、トーストとしても表示されます。この変更により、warningがエラーになるAPIレベルよりも前に、問題の可視性が向上します。

## コレクションの扱い (Collection handling)

> In Android O, Collections.sort() is implemented on top of List.sort(). The reverse was true in Android 7.x (API levels 24 and 25): The default implementation of List.sort() called Collections.sort().

抄訳: Android Oでは、```Collections.sort()``` は、```List.sort()``` の上に実装されます。Android 7.x (API level 24と25)の上では、逆が成り立ちます。```List.sort()```のdefaultの実装は、```Collections.sort()```の実装を呼び出していました。

> This change allows Collections.sort() to take advantage of optimized List.sort() implementations, but has the following constraints:
抄訳: この変更により、最適化された```List.sort()```の利点を、```Collections.sort()```享受できるようにするものです、しかし、以下の制約があります。

>* Implementations of List.sort() must not call Collections.sort(), because doing so would result in stack overflow due to infinite recursion. Instead, if you want the default behavior in your List implementation, you should avoid overriding sort().
If a parent class implements sort() inappropriately, it’s usually fine to override List.sort() with an implementation built on top of ```List.toArray()```, ```Arrays.sort()```, and ```ListIterator.set()```. For example:

抄訳: ```List.sort()```の実装は、```Collections.sort()```を決して呼び出してはいけません。なぜならば、そんなことをすれば、無限再帰呼び出しになって、スタックオーバーフローが発生するからです。代わりに、あなたのListの実装において、defaultの挙動が必要ならば、```sort()```のoverrideを避けるべきです。

```java
@Override
public void sort(Comparator<? super E> c) {
  Object[] elements = toArray();
  Arrays.sort(elements, c);
  ListIterator<E> iterator = (ListIterator<Object>) listIterator();
  for (Object element : elements) {
    iterator.next();
    iterator.set((E) element);
  }
}
```

抄訳：略

>In most cases, you can also override List.sort() with an implementation that delegates to different default implementations depending on API level. For example:

抄訳: 多くのケースで、API levelに依存して、```List.sort()```をoverrideして、別のdefaultの実装にdelegate (移譲)することもできるかもしれません。例えば、

```java
@Override
public void sort(Comparator<? super E> comparator) {
  if (Build.VERSION.SDK_INT <= 25) {
    Collections.sort(this);
  } else {
    super.sort(comparator);
  }
}
```

> If you're doing the latter only because you want to have a sort() method available on all API levels, consider giving it a unique name, such as sortCompat(), instead of overriding sort().

抄訳: もし、全てのAPIレベルで、```sort()```メソッドを有効にしたいために、後者をするのであれば、```sort()```ではなく、例えば、```sortCompat()```のようなユニークな名前を与えることを検討してください。、


> Collections.sort() now counts as a structural modification in List implementations that call sort(). For example, in versions of the platform prior to Android O, iterating over an ArrayList and calling sort() on it partway through the iteration would have thrown a ConcurrentModificationException if the sorting was done by calling List.sort(). Collections.sort() did not throw an exception.
This change makes the platform behavior more consistent: Either approach now results in a ConcurrentModificationException.

抄訳: ```Collections.sort()```は、```sort()```を呼び出す```List```の実装において、構造的な変更としてカウントを行うようになります。例えば、Android Oよりも前のplatformでは、```ArrayList```のイテレーションの途中で、sort()を呼び出し、sort()を呼ぶとsortが終わった時に、```ConcurrentModificationException```が投げられるでしょう(、本来は。しかし、)```Collections.sort()```は例外を投げませんでした。

* 対象: ```List.sort()```をoverrideしているアプリ
* 対策: ```Collections.sort()```を呼び出さないようにする (必要があれば、```super.sort(comparator);```をOのSDK Versionでは呼び出す)

## アカウントアクセスとディスカバリー容易性 (Account access and discoverability)

> Apps can no longer get access to user accounts unless the authenticator owns the accounts or the user grants that access. The GET_ACCOUNTS permission is no longer sufficient. To be granted access to an account, apps should either use AccountManager.newChooseAccountIntent() or an authenticator-specific method. After getting access to accounts, an app can can call AccountManager.getAccounts() to access them.

抄訳(+補足): アプリケーションは、ユーザーが許可するか、アプリが認証を行うアカウントを除いて、ユーザーアカウントにアクセスできなくなります。(syncproviderを持っているアプリは自分のアカウントにアクセスできる。)

> Android O deprecates LOGIN_ACCOUNTS_CHANGED_ACTION. Apps should instead use addOnAccountsUpdatedListener() to get updates about accounts during runtime.

抄訳: Android Oでは、```LOGIN_ACCOUNTS_CHANGED_ACTION``` が deprecatedになります。アプリは、その代わりに、実行中にアカウントの更新を受け取るためには、```addOnAccountsUpdatedListener()```を利用すべきです。

> For information about new APIs and methods added for account access and discoverability, see Account Access and Discoverability in the New APIs section of this document.

抄訳: 新APIやアカウントアクセスに関する[追加メソッドやディスカバリー容易性](https://developer.android.com/preview/api-overview.html#naa)に関しては、先のドキュメントの新APIの節を参照のこと。

* 対象: ```LOGIN_ACCOUNTS_CHANGED_ACTION```を使っているアプリ
* 対策: ```addOnAccountsUpdatedListener()```を利用 (アプリが動作していない時は受け取れないことに注意。代わりに、アプリ起動時にアカウント情報を取得する)

## Alert windows

> Apps that use the SYSTEM_ALERT_WINDOW permission can no longer use the following window types to display alert windows above other apps and system windows:

抄訳: ```SYSTEM_ALERT_WINDOW``` パーミッションを利用するアプリは、他のアプリやシステムウインドウの上にアラートウインドウを表示するために、以下のウインドウタイプを使うことはできなくなります。

> * TYPE_PHONE
> * TYPE_PRIORITY_PHONE
> * TYPE_SYSTEM_ALERT
> * TYPE_SYSTEM_OVERLAY
> * TYPE_SYSTEM_ERROR

抄訳: 略

> Instead, apps must use a new window type called TYPE_APPLICATION_OVERLAY.

抄訳: 代わりに、アプリは、新ウインドウタイプである```TYPE_APPLICATION_OVERLAY```を使う必要があります。

> When using the TYPE_APPLICATION_OVERLAY window type to display alert windows for your app, keep the following characteristics of the new window type in mind:

```TYPE_APPLICATION_OVERLAY``` ウインドウタイプを利用して、アラートウインドウを表示する場合には、新ウインドウタイプの以下の特徴に気をつけてください。

> * An app's alert windows always appear under critical system windows, such as the status bar and IMEs.
> * The system can move or resize windows that use the TYPE_APPLICATION_OVERLAY window type to improve screen presentation.
> * By opening the notification shade, users can access settings to block an app from displaying alert windows shown using the TYPE_APPLICATION_OVERLAY window type.

抄訳:

* アプリのアラートウインドウは、常に、クリティカルなシステムウインドウの下に表示されるということ。例えば、ステータスバーやIMEのようなものの下です。
* システムは、見栄えを良くするために、```TYPE_APPLICATION_OVERLAY```ウインドウを、スクリーンの移動したり、リサイズできます。
* 通知の陰影をオープンすることによって、ユーザーは、設定にアクセスでき、アプリが```TYPE_APPLICATION_OVERLAY```によるアラートウインドウの表示をブロックすることができます。

* 対象: アラートウインドウを利用しているアプリ
* 対策: ```TYPE_APPLICATION_OVERLAY```ウインドウタイプを利用すること。また、消され得ることを認識してアプリの設計を行うこと。

## コンテンツの変更通知 (Content change notifications)

> Android O changes how ContentResolver.notifyChange() and registerContentObserver(Uri, boolean, ContentObserver) behave for apps targeting Android O.

抄訳: Android Oでは、O向けのアプリにおいて、```ContentResolver.notifyChange()```と```registerContentObserver(Uri, boolean, ContentObserver)```の振る舞いが変わります。

> These APIs now require that a valid ContentProvider is defined for the authority in all Uris. Defining a valid ContentProvider with relevant permissions will help defend your app against content changes from malicious apps, and prevent you from leaking potentially private data to malicious apps.

抄訳: これらのAPIは、すべてのURIのauthorityが正しく定義される```ContentProvider```が必要になります。正しい```ContentProvider```を関係するパーミッションと共に定義することは、不正なアプリからのコンテンツ変更に対して防衛することに役立ち、不正なアプリに対して、潜在的にプライベートなデータが漏れるのを防ぎます。

* 対象: ```ContentProvider```を定義するアプリ
* 対策: その```ContentProvider```において、すべてのURIのauthorityを正しく定義する。