動作の変更点

M Developer Preview には、新機能以外にもさまざまなシステムの変更点や API の動作の変更点が盛り込まれています。 このドキュメントでは、アプリ開発において把握しておくべき主な変更点について説明します。

過去に Android にアプリを公開したことがある場合は、アプリがこれらの変更による影響を受ける場合があることに注意してください。

実行時パーミッション

このプレビューでは、アプリのパーミッションを実行時にユーザーが直接管理できる新しいパーミッション モデルが採用されました。 このモデルによって、ユーザーに対するパーミッションの可視性と制御性が向上し、アプリ開発者にとってはアプリのインストールや自動アップデート プロセスの効率が上がります。ユーザーはインストール済みアプリのパーミッションを個別に付与したり取り消したりできます。

M Preview を対象としたアプリでは、必ずパーミッションを実行時に確認、要求するようにします。 アプリにパーミッションが付与されているかどうかを確認するには、新しい Context.checkSelfPermission() メソッドを呼び出します。 パーミッションを要求するには、新しい Activity.requestPermission() メソッドを呼び出します。アプリが M を対象としていない場合でも、新しいパーミッション モデルでアプリをテストするようにしてください。

アプリで新しいパーミッションをサポートする際の詳細については、Developer Preview ページの Permissions をご覧ください。 アプリへの影響を評価する際のヒントについては、Testing Guide をご覧ください。

省電力の最適化

このプレビューでは、アイドル中の端末やアプリに対する新しい省電力の最適化機能が採用されています。

Doze

端末が電源に接続されておらず、画面が一定時間オフ状態の場合は Doze モードに入り、システムをスリープ状態に保ちます。 このモードでは、端末は定期的に通常の操作を短時間再開することで、アプリを同期したり、システムが保留中の操作を行ったりすることができます。

Doze 中は、アプリに次の制限が適用されます。

  • アプリで優先度の高い Google Cloud Messaging の通知を受信する場合以外、ネットワーク アクセスは無効になります。
  • Wake ロック は無視されます。
  • AlarmManager クラスを使ってスケジュールされたアラームは無効になりますが、setAlarmClock() メソッドと AlarmManager.setAndAllowWhileIdle() を使って設定したアラームは除きます。
  • WiFi スキャンは実行されません。
  • 同期アダプタ と JobScheduler の同期とジョブは実行できません。

端末が Doze モードでなくなると、保留中のすべての同期とジョブが実行されます。

この機能をテストするには、M Preview を実行する端末を開発マシンに接続して、次のコマンドを呼び出します。

$ adb shell dumpsys battery unplug
$ adb shell dumpsys deviceidle step
$ adb shell dumpsys deviceidle -h

: Google Cloud Messaging の次期リリースでは、高優先度のメッセージを指定できます。 アプリが高優先度の GCM メッセージを受信する場合は、端末が Doze 中でも短時間のネットワーク アクセスが付与されます。

アプリで Doze をテストする方法のヒントについては、 Testing Guide をご覧ください。

App Standby

このプレビューでは、アクティブに使用されていないアプリをシステムがアイドル状態であるとみなす場合があります。 システムが次の信号を検出しない場合、一定時間の経過後にアプリはアイドル状態であるとみなされます。

  • アプリがユーザーによって明示的に起動された。
  • アプリのプロセスが現在フォアグラウンドにある(アクティビティかフォアグラウンド サービスとしてか、他のアクティビティかフォアグラウンド サービスによって使用されている)。
  • アプリがロック画面や通知トレイに表示される通知を生成する。
  • ユーザーが、アプリに最適化が適用されないよう [設定] で明示的に指定する。

端末が電源に接続されていない場合、アイドル中のみなされたアプリのネットワーク アクセスは無効になり、同期とジョブは保留されます。 端末が電源に接続されると、アプリのネットワーク アクセスは許可され、保留中のすべてのジョブと同期が実行されます。 端末が長時間アイドル状態の場合、アイドル中のアプリは 1 日 1 回程度ネットワーク アクセスが許可されます。

この機能をテストするには、M Preview を実行する端末を開発マシンに接続して、次のコマンドを呼び出します。

$ adb shell dumpsys battery unplug
$ adb shell am set-idle <packageName> true
$ adb shell am set-idle <packageName> false
$ adb shell am get-idle <packageName>

注: Google Cloud Messaging(GCM)の次期リリースでは、高優先度のメッセージを指定できます。 アプリが高優先度の GCM メッセージを受信する場合は、アプリがアイドル 中でも短時間のネットワーク アクセスが付与されます。

アプリで App Standby をテストする方法のヒントについては、 Testing Guide をご覧ください。

追加可能なストレージ端末

このプレビューでは、SD カードなどの外部ストレージ端末を追加できます。外部ストレージ端末を追加すると、端末が内部ストレージのように動作するよう暗号化とフォーマットが行われます。 この機能によって、アプリとアプリの個人データをストレージ端末間で移動できるようになります。 アプリを移動する際、システムはマニフェストの android:installLocation を遵守します。

アプリが次の API やフィールドにアクセスする場合は、アプリが内部ストレージ端末と外部ストレージ端末間で移動する際に返されるファイルパスが動的に変化することに注意してください。ファイルパスの構築時は、これらの API を動的に呼び出すことを強くお勧めします。ハードコードされたファイル パスを使用したり、過去にビルドした完全修飾ファイルパスをそのまま使用したりしないでください。

Developer Preview のこの機能をデバッグするには、USB On-The-Go(OTG)ケーブルで Android 端末に接続された USB ドライブの追加を有効にして、次のコマンドを実行します。

$ adb shell sm set-force-adoptable true

Apache HTTP Client の削除

このプレビューでは、Apache HTTP クライアントのサポートが削除されました。アプリでこのクライアントを使用していて、Android 2.3(API レベル 9)以上を対象としている場合は、代わりに HttpURLConnection クラスを使用します。 この API は透過的データ圧縮と応答のキャッシュによってネットワーク使用を軽減し、電源の消費を最小化するため、効率性が向上します。 Apache HTTP API を引き続き使用するには、まず build.gradle ファイルで次のコンパイル時の依存関係を宣言する必要があります。

android {
    useLibrary 'org.apache.http.legacy'
}

Android は、OpenSSL から BoringSSL ライブラリに移行しています。 アプリで Android NDK を使用している場合は、libcrypto.solibssl.so など、NDK API の一部でない暗号化ライブラリにリンクしないでください。 これらのライブラリは パブリック API ではなく、リリースや端末に対する通知なしで変更されたり、中断したりする可能性があります。また、セキュリティ上の脆弱性を露呈する場合もあります。 代わりに、ネイティブ コードを変更して JNI 経由で Java の暗号化 API を呼び出すか、希望の暗号化ライブラリに静的リンクします。

AudioManager の変更点

AudioManager クラスで音量を直接設定したり、特定のストリームをミュートにしたりする方法はサポートされなくなりました。 setStreamSolo() メソッドは廃止されたため、代わりに AudioManager.requestAudioFocus() メソッドを呼び出す必要があります。同様に、 setStreamMute() メソッドも廃止され、代わりに AudioManager.adjustStreamVolume() メソッドを呼び出して、値に ADJUST_MUTEADJUST_UNMUTE を渡します。

テキスト選択

ユーザーがアプリ内でテキストを選択するとき、 切り取りコピー貼り付けなどのテキスト選択のアクションを フローティング ツール バーに表示できるようになりました。 個別のビューに対してコンテキスト アクション モードを有効にするにあるように、コンテキスト アクションバーに関するユーザー操作の実装も同様です。

テキスト選択にフローティング ツール バーを実装するには、既存のアプリに次の変更を加えます。

  1. View オブジェクトか Activity オブジェクトで、ActionMode の呼び出しを startActionMode(Callback) から startActionMode(Callback, ActionMode.TYPE_FLOATING) に変更します。
  2. 既存の ActionMode.Callback の実装を、ActionMode.Callback2 に拡張します。
  3. Callback2.onGetContentRect() メソッドをオーバーライドして、ビューのコンテンツの Rect オブジェクト)テキスト選択の四角形など)の座標を指定します。
  4. 四角形の位置が有効でなくなり、無効な要素がこれのみである場合は、ActionMode.invalidateContentRect() メソッドを呼び出します。

Android Support Library revision 22.2 を使用している場合、フローティング ツール バーに下方互換性はなく、デフォルトで appcompat が代わりに ActionMode オブジェクトを制御することに注意してください。 これにより、フローティング ツール バーは表示されなくなります。 AppCompatActivityActionMode がサポートされるようにするには、 android.support.v7.app.AppCompatActivity.getDelegate() を呼び出して、返された AppCompatDelegate オブジェクトで android.support.v7.app.AppCompatDelegate.setHandleNativeActionModesEnabled() を呼び出し、 入力パラメータを false に設定します。 この呼び出して、ActionMode オブジェクトの制御がフレームワークに戻ります。 M Preview を実行する端末ではフレームワークによる ActionBar やフローティング ツール バー モードのサポートが可能ですが、M Preview 以前の端末では ActionBar モードのみがサポートされます。

Android キーストロークの変更点

このプレビューでは、 Android Keystore プロバイダによる DSA のサポートがなくなります。 ECDSA は引き続きサポートされます。

停止時に暗号化を必要としないキーが、ロック画面の(ユーザーや端末の管理者などによる)無効時やリセット時に削除されなくなりました。 停止時に暗号化を必要とするキーは、これらのイベント時に削除されます。

Wi-Fi とネットワークの変更点

このプレビューでは、Wi-Fi API とネットワーク API の動作に次のような変更点が追加されました。

  • オブジェクトの作成者である場合のみ、アプリでWifiConfiguration オブジェクトの状態を変更できます。 ユーザーや他のアプリによって作成された WifiConfiguration オブジェクトは変更、削除できません。
  • 以前は、 enableNetwork()disableAllOthers=true 設定を使ってアプリから端末を特定の Wi-Fi ネットワークに接続させた場合、端末はセルラー データなどの他のネットワークから切断されていました。 このプレビューでは、端末が他のネットワークから切断されないようになりました。アプリの targetSdkVersion“20” 以下の場合は、選択した Wi-Fi ネットワークに固定されます。 アプリの targetSdkVersion“21” 以上の場合は、マルチネットワーク API( openConnection()メソッド、 bindSocket()メソッド、新しい ConnectivityManager.bindProcessToNetwork() メソッドなど)を使用してネットワーク トラフィックが選択したネットワークに送られるようにします。

カメラ サービスの変更点

このプレビューでは、カメラ サービスの共有リソースへのアクセスモデルが、以前の "先着順" モデルから、"優先度順" に変更されました。 この動作の変更には、次のようなものがあります。

  • カメラ端末を開いて構成するなど、カメラのサブシステム リソースへのアクセスは、クライアント アプリケーション プロセスの "優先度" に基づいて与えられます。 通常、ユーザーに表示されているアクティビティやフォアグラウンドにあるアクティビティのあるアプリケーション プロセスの優先度が最も高くなり、カメラ リソースの取得や使用の信頼性が高まります。
  • 優先度の低いアプリでアクティブなカメラ クライアントは、より優先度の高いアプリケーションがカメラを使おうとした際に使用が中断される場合があります。 廃止された Camera API では、使用が中断されたクライアントに onError() が呼び出されます。 Camera2 API では、使用が中断されたクライアントに onDisconnected() が呼び出されます。
  • 適切なカメラ ハードウェア付きの端末では、別のアプリケーション プロセスを独立して開き、別のカメラ端末を同時に使用できます。 ただし、同時アクセスによってパフォーマンスや開いているカメラ端末の性能が著しく低下するマルチプロセスの使用が検出可能になり、カメラ サービスでは許可されなくなりました。 この変更によって、同じカメラ端末にアクセスしようとしているアプリが他になくても、優先度の低いクライアントによる使用が中断される場合があります。
  • 現在のユーザーを変更すると、アプリ内で前のユーザー アカウントで所有していたアクティブなカメラ クライアントが中断させられることになります。 カメラへのアクセスは、現在の端末ユーザーが所有するユーザー プロファイルのみに制限されます。つまり、ユーザーが別のアカウントに切り替えた場合、"ゲスト" アカウントはカメラのサブシステムを使用するプロセスを実行したまま去ることはできません。

ART ランタイム

ART ランタイムで、 newInstance() メソッドに対するアクセスルールを正常に実装できるようになりました。この変更によって、以前のバージョンで Dalvik がアクセス ルールを正しく確認できなかった問題が解決しました。アプリで newInstance() メソッドを使用していて、アクセス チェックをオーバーライドしたい場合は、 setAccessible() メソッドを使って入力パラメータを true に設定します。 アプリで v7 appcompat ライブラリv7 recyclerview ライブラリを使用する場合は、これらのライブラリの最新バージョンを使用するようアプリをアップデートする必要があります。 アップデートしない場合は、XML から参照するカスタム クラスがアップデートされていて、クラス コンストラクタがアクセス可能であることを確認しておく必要があります。

このプレビューでは、動的リンクの動作がアップデートされました。動的リンクでは、ライブラリの soname とそのパス( public bug 6670)の違いを認識でき、soname が実装されています。 以前動作していたアプリで間違った DT_NEEDED エントリを持つもの(ビルドマシンのファイル システムの絶対パスなど)は、読み込み時に失敗する場合があります。

dlopen(3) RTLD_LOCAL フラグは正常に実装されました。 RTLD_LOCAL はデフォルトのため、 RTLD_LOCAL を明示的に使用しない dlopen(3) への呼び出しは影響を受けます(アプリで明示的に RTLD_GLOBAL を使用している場合を除く)。 RTLD_LOCAL では、後に dlopen(3) への呼び出しで読み込まれたライブラリで記号は使用できません(DT_NEEDED エントリによって参照された場合とは逆)。

APK の検証

プラットフォームでより厳しい APK の検証が行われるようになりました。APK がマニフェスト ファイルで宣言されているにもかかわらず、APK 自体に存在しない場合、その APK は破損しているとみなされます。 コンテンツが一部でも削除された場合は、APK の再署名が必要になります。

Android for Work の変更点

このプレビューには、次のような Android for Work に関する動作の変更点が含まれています。

  • 個人のコンテキストでの仕事用の連絡先ユーザーが過去の通話履歴を表示したときに、Google Dialer Call Log に仕事用の連絡先が表示されるようになりました。DevicePolicyManager.setCrossProfileCallerIdDisabled()true に設定すると、Google Dialer Call Log に仕事用プロファイルの連絡先は表示されなくなります。 DevicePolicyManager.setBluetoothContactSharingDisabled()false に設定した場合のみ、Bluetooth 経由で端末に仕事用の連絡先と個人用の連絡先を表示できます。 デフォルトでは、true に設定されています。
  • WiFi 設定の削除:プロファイル オーナーによって追加された WiFi 設定(@link android.net.wifi.WifiManager#addNetwork(android.net.wifi.WifiConfiguration) addNetwork()} メソッドへの呼び出しなどを介して)は、その仕事用プロファイルが削除されると同時に削除されます。
  • WiFi 設定のロック:アクティブなデバイス オーナーによって作成された WiFi 設定は、ユーザーが修正したり削除したりできなくなりました。 ユーザーに UserManager 定数 DISALLOW_CONFIG_WIFI が設定されていない限り、ユーザー自身の WiFi 設定を作成、修正することはできます。
  • Google アカウントの追加経由での Work Policy Controller のダウンロード:Work Policy Controller(WPC)アプリ経由で管理する必要のある Google アカウントがマネージド コンテキスト外で端末に追加されると、アカウントの追加フローでユーザーに適切な WPC をインストールするよう要求します。この動作は、初期の端末のセットアップ ウィザードでの [設定]> [アカウント] で追加されるアカウントにも適用されます。
  • 特定の DevicePolicyManager API の動作の変更点: setCameraDisabled() メソッドの呼び出しは、呼び出し元のユーザーのカメラにのみ影響を与えます。マネージド プロファイルから呼び出した場合は、プライマリ ユーザーで実行しているカメラ アプリに影響はありません。 さらに、 setKeyguardDisabledFeatures() メソッドは、デバイス オーナーに加えてプロファイル オーナーでも利用可能になりました。 プロファイル オーナーは、これらのキーガード制限を設定できます: