Android 6.0(API レベル 23)では、新機能に加えて、さまざまなシステム変更や API 動作の変更が行われています。このドキュメントでは、アプリで理解および考慮すべき主な変更点について説明します。
以前に Android 向けアプリを公開したことがある場合は、プラットフォームのこうした変更がアプリに影響することに留意してください。
実行時の権限
このリリースでは、新しい権限モデルが導入され、ユーザーが実行時にアプリの権限を直接管理できるようになりました。このモデルにより、ユーザーによる権限の可視性と制御が改善されるとともに、アプリ デベロッパー向けのインストールと自動更新のプロセスが合理化されます。ユーザーはインストール済みのアプリに対して個別に権限を付与または取り消すことができます。
Android 6.0(API レベル 23)以降をターゲットとするアプリでは、必ず実行時に権限を確認し、リクエストしてください。アプリに権限が付与されているかどうかを確認するには、新しい checkSelfPermission()
メソッドを呼び出します。権限をリクエストするには、新しい requestPermissions()
メソッドを呼び出します。アプリが Android 6.0(API レベル 23)を対象としていない場合でも、新しい権限モデルでアプリをテストする必要があります。
アプリで新しい権限モデルをサポートする方法について詳しくは、 システム権限の操作をご覧ください。アプリへの影響を評価する方法については、権限の使用上の注意をご覧ください。
Doze とアプリ スタンバイ
このリリースでは、アイドル状態のデバイスとアプリに対する新しい省電力の最適化機能が導入されています。これらの機能はすべてのアプリに影響するため、これらの新しいモードでアプリをテストしてください。
- Doze: ユーザーがデバイスを電源から外し、画面がオフの状態で一定時間放置すると、デバイスは Doze モードになり、システムのスリープ状態を維持しようとします。このモードでは、デバイスは定期的に通常のオペレーションを短時間再開するため、アプリの同期とシステムが保留中のオペレーションを実行できるようになります。
- アプリ スタンバイ: アプリ スタンバイを使用すると、ユーザーが実際にアプリを使用していないときに、システムがアプリがアイドル状態であると判断できます。この判断は、ユーザーが一定時間アプリをタップしなかった場合に行われます。デバイスが電源から外されると、システムはネットワーク アクセスを無効にし、アイドル状態と見なしたアプリの同期とジョブを一時停止します。
省電力に関するこれらの変更について詳しくは、Doze とアプリ スタンバイの最適化をご覧ください。
Apache HTTP クライアントの削除
Android 6.0 リリースでは、Apache HTTP クライアントのサポートが削除されました。アプリがこのクライアントを使用していて、Android 2.3(API レベル 9)以降をターゲットとしている場合は、代わりに HttpURLConnection
クラスを使用します。この API は、透過的な圧縮とレスポンスのキャッシュによってネットワーク使用量を削減し、消費電力を最小限に抑えているため、より効率的です。Apache HTTP API を引き続き使用するには、まず build.gradle
ファイルで次のコンパイル時の依存関係を宣言する必要があります。
android { useLibrary 'org.apache.http.legacy' }
BoringSSL
Android は、OpenSSL から BoringSSL ライブラリに移行しています。アプリで Android NDK を使用している場合は、NDK API の一部ではない暗号ライブラリ(libcrypto.so
や libssl.so
など)にリンクしないでください。これらのライブラリは公開 API ではなく、リリースやデバイス間で予告なく変更または中断される場合があります。加えて、セキュリティの脆弱性にさらされる可能性もあります。代わりに、ネイティブ コードを変更して、JNI 経由で Java 暗号 API を呼び出すか、任意の暗号ライブラリに静的にリンクします。
ハードウェア ID へのアクセス
ユーザーのデータ保護を強化するため、Android ではこのリリース以降、Wi-Fi API と Bluetooth API を使用するアプリによる、デバイスのローカル ハードウェア識別子へのプログラマティックなアクセスを削除しました。WifiInfo.getMacAddress()
メソッドと BluetoothAdapter.getAddress()
メソッドは定数値 02:00:00:00:00:00
を返すようになりました。
Bluetooth スキャンと Wi-Fi スキャンを介して付近の外部デバイスのハードウェア ID にアクセスするには、アプリに ACCESS_FINE_LOCATION
権限または ACCESS_COARSE_LOCATION
権限が付与されている必要があります。
注: Android 6.0(API レベル 23)を搭載したデバイスがバックグラウンドで Wi-Fi スキャンまたは Bluetooth スキャンを開始すると、そのオペレーションはランダム化された MAC アドレスから発信されたものとして外部デバイスに表示されます。
通知
このリリースでは、Notification.setLatestEventInfo()
メソッドが削除されました。代わりに Notification.Builder
クラスを使用して通知を作成してください。通知を繰り返し更新するには、Notification.Builder
インスタンスを再利用します。build()
メソッドを呼び出して、更新された Notification
インスタンスを取得します。
adb shell dumpsys notification
コマンドで通知テキストが出力されなくなりました。通知オブジェクトのテキストを出力するには、代わりに adb shell dumpsys notification --noredact
コマンドを使用します。
AudioManager の変更
AudioManager
クラスを使用して音量を直接設定することや、特定のストリームをミュートすることはサポートされなくなりました。setStreamSolo()
メソッドは非推奨となったため、代わりに requestAudioFocus()
メソッドを呼び出す必要があります。同様に、setStreamMute()
メソッドのサポートも終了しました。代わりに adjustStreamVolume()
メソッドを呼び出して、方向の値 ADJUST_MUTE
または ADJUST_UNMUTE
を渡します。
テキストの選択
ユーザーがアプリ内でテキストを選択すると、フローティング ツールバーに、切り取り、コピー、貼り付けなどのテキスト選択操作を表示できるようになりました。ユーザー操作の実装は、 個々のビューでコンテキスト アクション モードを有効にするで説明されているように、コンテキスト アクションバーの実装と似ています。
テキスト選択用にフローティング ツールバーを実装するには、既存のアプリに次の変更を加えます。
View
オブジェクトまたはActivity
オブジェクトで、ActionMode
呼び出しをstartActionMode(Callback)
からstartActionMode(Callback, ActionMode.TYPE_FLOATING)
に変更します。ActionMode.Callback
の既存の実装を取得し、代わりにActionMode.Callback2
を拡張します。onGetContentRect()
メソッドをオーバーライドして、ビュー内のコンテンツRect
オブジェクト(テキスト選択の長方形など)の座標を指定します。- 長方形の位置が無効になり、これが無効になる唯一の要素である場合は、
invalidateContentRect()
メソッドを呼び出します。
Android サポート ライブラリのリビジョン 22.2 を使用している場合、フローティング ツールバーには下位互換性がなく、デフォルトでは appcompat が ActionMode
オブジェクトを制御することに注意してください。これにより、フローティング ツールバーが表示されなくなります。AppCompatActivity
で ActionMode
サポートを有効にするには、getDelegate()
を呼び出し、返された AppCompatDelegate
オブジェクトで setHandleNativeActionModesEnabled()
を呼び出し、入力パラメータを false
に設定します。この呼び出しは、ActionMode
オブジェクトの制御をフレームワークに返します。Android 6.0(API レベル 23)を搭載したデバイスでは、フレームワークが ActionBar
またはフローティング ツールバー モードをサポートできます。一方、Android 5.1(API レベル 22)以前を搭載したデバイスでは、ActionBar
モードのみがサポートされます。
ブラウザ ブックマークの変更
このリリースでは、グローバル ブックマークのサポートが削除されました。android.provider.Browser.getAllBookmarks()
メソッドと android.provider.Browser.saveBookmark()
メソッドが削除されました。同様に、READ_HISTORY_BOOKMARKS
権限と WRITE_HISTORY_BOOKMARKS
権限が削除されます。アプリが Android 6.0(API レベル 23)以降をターゲットとしている場合は、グローバル プロバイダからブックマークにアクセスしたり、ブックマークの権限を使用したりしないでください。代わりに、ブックマーク データを内部に保存する必要があります。
Android Keystore の変更
このリリースにより、Android Keystore プロバイダは DSA をサポートしなくなりました。ECDSA は引き続きサポートされます。
保存データの暗号化を必要としない鍵は、(ユーザーやデバイスの管理者などによって)セキュアロック画面が無効化またはリセットされても、削除されなくなります。保存時に暗号化を必要とする鍵は、これらのイベント中に削除されます。
Wi-Fi とネットワークの変更
このリリースでは、Wi-Fi API とネットワーキング API に以下の動作変更が導入されます。
- オブジェクトを作成した場合にのみ、アプリで
WifiConfiguration
オブジェクトの状態を変更できるようになりました。ユーザーまたは他のアプリが作成したWifiConfiguration
オブジェクトを変更または削除することはできません。 -
以前は、アプリが
disableAllOthers=true
設定でenableNetwork()
を使用してデバイスを特定の Wi-Fi ネットワークに接続すると、デバイスはモバイルデータなどの他のネットワークから切断されていました。このリリースでは、デバイスがこのような他のネットワークから切断されることはなくなりました。アプリのtargetSdkVersion
が“20”
以下の場合、選択した Wi-Fi ネットワークに固定されています。アプリのtargetSdkVersion
が“21”
以上の場合は、マルチネットワーク API(openConnection()
、bindSocket()
、新しいbindProcessToNetwork()
メソッドなど)を使用して、選択したネットワークでネットワーク トラフィックが送信されるようにします。
カメラサービスの変更
このリリースでは、カメラサービスの共有リソースにアクセスするモデルが、以前の「先着順」のアクセスモデルから、優先度の高いプロセスを優先するアクセスモデルに変更されました。サービスの動作の変更点は次のとおりです。
- カメラデバイスの起動や設定など、カメラのサブシステム リソースへのアクセスは、クライアント アプリ プロセスの「優先度」に基づいて付与されます。通常、ユーザーに表示されるアクティビティやフォアグラウンドでのアクティビティがあるアプリ プロセスの優先度が高くなり、カメラリソースの取得と使用の信頼性が高まります。
- 優先度の高いアプリがカメラを使用しようとすると、優先度の低いアプリでアクティブなカメラ クライアントが「強制排除」されることがあります。これにより、非推奨の
Camera
API では、強制排除されたクライアントに対してonError()
が呼び出されます。Camera2
API では、強制排除されたクライアントに対してonDisconnected()
が呼び出されます。 - 適切なカメラ ハードウェアを備えたデバイスでは、個別のアプリプロセスを個別に開いて、別々のカメラデバイスを同時に使用できます。ただし、同時にアクセスすると、開いているカメラデバイスのパフォーマンスや機能が大幅に低下するマルチプロセスのユースケースは、カメラサービスによって検出され、禁止されるようになりました。この変更により、同じカメラデバイスに直接アクセスしようとするアプリが他にない場合でも、優先度の低いクライアントで「エビクション」が発生することがあります。
- 現在のユーザーを変更すると、以前のユーザー アカウントが所有していたアプリ内のアクティブなカメラ クライアントが強制排除されます。カメラへのアクセスは、現在のデバイス ユーザーが所有するユーザー プロファイルに限定されます。 つまり実際には、「ゲスト」アカウントは、ユーザーが別のアカウントに切り替えたときに、カメラのサブシステムを使用するプロセスを実行したままにすることはできません。
ランタイム
ART ランタイムで、newInstance()
メソッドのアクセスルールが適切に実装されるようになりました。この変更により、以前のバージョンで Dalvik がアクセスルールを正しくチェックしない問題を修正しました。アプリで newInstance()
メソッドを使用していて、アクセス チェックをオーバーライドする場合は、入力パラメータを true
に設定して setAccessible()
メソッドを呼び出します。アプリで v7 appcompat ライブラリまたは v7 recyclerview ライブラリを使用している場合は、これらのライブラリの最新バージョンを使用するようにアプリを更新する必要があります。それ以外の場合は、XML から参照されるカスタムクラスを更新して、クラス コンストラクタにアクセスできるようにしてください。
このリリースでは、ダイナミック リンカーの動作が更新されました。ダイナミック リンカーがライブラリの soname
とそのパスの違いを認識するようになり(
公開バグ 6670)、soname
による検索が実装されるようになりました。以前は動作していたアプリで、不正な DT_NEEDED
エントリを持つもの(通常はビルドマシンのファイル システムの絶対パス)が、読み込み時に失敗することがあります。
dlopen(3) RTLD_LOCAL
フラグが正しく実装されました。RTLD_LOCAL
はデフォルトで、RTLD_LOCAL
を明示的に使用しなかった dlopen(3)
の呼び出しは影響を受けます(アプリが RTLD_GLOBAL
を明示的に使用した場合を除く)。RTLD_LOCAL
を使用すると、後で dlopen(3)
を呼び出したときに読み込まれたライブラリでシンボルを使用できなくなります(DT_NEEDED
エントリによって参照されるのではなく)。
以前のバージョンの Android では、アプリがテキストの再配置を伴う共有ライブラリの読み込みをシステムにリクエストすると、システムは警告を表示しましたが、ライブラリの読み込みは許可していました。このリリース以降、アプリのターゲット SDK バージョンが 23 以降の場合、このライブラリはシステムによって拒否されます。ライブラリの読み込みに失敗したかどうかを検出するには、アプリで dlopen(3)
エラーをログに記録し、dlerror(3)
呼び出しから返される問題の説明テキストを含める必要があります。テキストの再配置の処理について詳しくは、こちらのガイドをご覧ください。
APK の検証
プラットフォームでの APK の検証がより厳密に行われるようになりました。APK がマニフェストで宣言されているのに APK 自体に存在しない場合、その APK は破損していると見なされます。APK のコンテンツのいずれかが削除された場合、再署名する必要があります。
USB 接続
USB ポートを介したデバイス接続が、デフォルトで充電専用モードに設定されるようになりました。USB 接続を介してデバイスとそのコンテンツにアクセスするには、ユーザーはそのような操作に対する権限を明示的に付与する必要があります。USB ポートを介したデバイスのユーザー操作をアプリがサポートしている場合は、その操作を明示的に有効にする必要があることを考慮してください。
Android for Work の変更点
このリリースには、Android for Work で以下の動作変更が含まれています。
- プライベートでの仕事用の連絡先。ユーザーが過去の通話を表示したときに、Google 電話アプリの通話履歴に仕事用の連絡先が表示されるようになりました。
setCrossProfileCallerIdDisabled()
をtrue
に設定すると、仕事用プロファイルの連絡先が Google 電話アプリの通話履歴に表示されなくなります。setBluetoothContactSharingDisabled()
をfalse
に設定した場合のみ、仕事用の連絡先と個人用の連絡先を Bluetooth 経由でデバイスに表示できます。デフォルトではtrue
に設定されています。 - Wi-Fi 設定の削除: 仕事用プロファイルが削除されると、プロファイル所有者が(
addNetwork()
メソッドの呼び出しなどを通じて)追加した Wi-Fi 設定も削除されるようになりました。 - Wi-Fi 設定のロックダウン:
WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN
がゼロ以外の場合、アクティブなデバイス所有者によって作成された Wi-Fi 設定は、ユーザーが変更または削除できなくなります。 ユーザーは引き続き自分の Wi-Fi 設定の作成や変更を行えます。アクティブなデバイス所有者は、自身が作成していないものも含め、すべての Wi-Fi 設定を編集または削除する権限を持っています。 - Google アカウントの追加による Device Policy Controller のダウンロード: Device Policy Controller(DPC)アプリによる管理を必要とする Google アカウントが、管理対象コンテキスト以外のデバイスに追加された場合、アカウント追加フローで、適切な WPC のインストールを求めるメッセージが表示されるようになりました。この動作は、[設定] > [アカウント] で追加したアカウント、および最初のデバイス設定ウィザードで追加したアカウントにも適用されます。
- 特定の
DevicePolicyManager
API の動作の変更:setCameraDisabled()
メソッドを呼び出しても、呼び出し元のユーザーのカメラにのみ影響します。管理対象プロファイルから呼び出しても、プライマリ ユーザーで実行されているカメラアプリには影響しません。- さらに、デバイス所有者だけでなくプロファイル所有者が
setKeyguardDisabledFeatures()
メソッドを使用できるようになりました。 - プロファイル オーナーは、次のキーガード制限を設定できます。
KEYGUARD_DISABLE_TRUST_AGENTS
とKEYGUARD_DISABLE_FINGERPRINT
は、プロファイルの親ユーザーのキーガード設定に影響します。KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS
。管理対象プロファイル内のアプリによって生成された通知にのみ影響します。
DevicePolicyManager.createAndInitializeUser()
メソッドとDevicePolicyManager.createUser()
メソッドが非推奨になりました。- また、
setScreenCaptureDisabled()
メソッドは、特定のユーザーのアプリがフォアグラウンドにある場合に、アシスト構造をブロックするようになりました。 EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM
のデフォルトが SHA-256 になりました。SHA-1 は下位互換性を確保するために引き続きサポートされますが、今後削除される予定です。EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM
が SHA-256 のみを受け入れるようになりました。- Android 6.0(API レベル 23)で存在していたデバイス初期化 API が削除されました。
EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS
は削除されたため、NFC バンプ プロビジョニングは出荷時設定へのリセットで保護されたデバイスをプログラムでロック解除できません。EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE
エクストラを使用して、管理対象デバイスの NFC プロビジョニング中にデバイス所有者アプリにデータを渡せるようになりました。- Android for Work API は、仕事用プロファイル、アシストレイヤなどを含む M の実行時の権限向けに最適化されています。新しい
DevicePolicyManager
権限 API は、M より前のアプリには影響しません。 ACTION_PROVISION_MANAGED_PROFILE
またはACTION_PROVISION_MANAGED_DEVICE
インテントを通じて開始されたセットアップ フローの同期部分からユーザーが戻ったときに、システムからRESULT_CANCELED
結果コードが返されるようになりました。
- 他の API の変更:
- データの使用:
android.app.usage.NetworkUsageStats
クラスの名前がNetworkStats
に変更されました。
- データの使用:
- グローバル設定の変更:
- 次の設定は、
setGlobalSettings()
で設定できなくなりました。BLUETOOTH_ON
DEVELOPMENT_SETTINGS_ENABLED
MODE_RINGER
NETWORK_PREFERENCE
WIFI_ON
- 次のグローバル設定を
setGlobalSettings()
で設定できるようになりました。
- 次の設定は、