Android 8.0 の機能と API

Android 8.0(API レベル 26)では、ユーザーやデベロッパー向けのさまざまな新機能が導入されています。このドキュメントでは、デベロッパー向けの新機能について説明します。

また、プラットフォームの変更がアプリに影響する領域については、 Android 8.0 の動作変更もご覧ください。

ユーザー エクスペリエンス

ピクチャー イン ピクチャー モード

Android 8.0 のピクチャー イン ピクチャー

Android 8.0(API レベル 26)では、アクティビティをピクチャー イン ピクチャー(PIP)モードで起動できます。PIP は特別なタイプのマルチウィンドウ モードで、主に動画の再生に使用されます。PIP モードは、元々 Android TV でのみ利用可能でしたが、Android 8.0 では他の Android デバイスでも利用可能になりました。

アクティビティが PIP モードのときは一時停止状態になりますが、コンテンツは引き続き表示されます。このため、アプリが onPause() ハンドラで再生を一時停止しないようにする必要があります。代わりに、動画は onStop() で一時停止し、onStart() で再生を再開してください。詳細については、マルチウィンドウ ライフサイクルをご覧ください。

アクティビティが PIP モードを使用できることを指定するには、マニフェストで android:supportsPictureInPicture を true に設定します。(Android 8.0 以降、PIP では android:resizeableActivity マニフェスト属性は不要です。ただし、アクティビティが他のマルチウィンドウ モードをサポートしている場合は、android:resizeableActivity を true に設定する必要があります)。

Android 8.0(API レベル 26)では、新しいオブジェクト PictureInPictureParams が導入されました。このオブジェクトを PIP メソッドに渡して、PIP モードのときのアクティビティの動作を指定できます。このオブジェクトは、アクティビティの優先アスペクト比などのプロパティを指定します。

ピクチャー イン ピクチャーの追加で説明されている既存の PIP メソッドが、Android TV だけでなく、すべての Android デバイスで使用できるようになりました。さらに、Android 8.0 には、PIP モードをサポートする以下のメソッドが用意されています。

  • Activity.enterPictureInPictureMode(PictureInPictureParams args): アクティビティをピクチャー イン ピクチャー モードに配置します。アクティビティのアスペクト比やその他の構成設定は、args で指定されます。args のいずれかのフィールドが空の場合は、最後に Activity.setPictureInPictureParams() を呼び出したときに設定された値が使用されます。

    指定したアクティビティは画面の隅に配置され、画面の残りの部分は、画面上に表示されていた以前のアクティビティで埋められます。 PIP モードに入るアクティビティは一時停止状態になりますが、開始されたままになります。ユーザーが PIP アクティビティをタップすると、ユーザーが操作するためのメニューがシステムに表示されます。PIP 状態のアクティビティにタッチイベントは到達しません。

  • Activity.setPictureInPictureParams(): アクティビティの PIP 構成設定を更新します。アクティビティが現在 PIP モードになっている場合は、設定が更新されます。これは、アクティビティのアスペクト比が変更された場合に便利です。アクティビティが PIP モードでない場合、呼び出す enterPictureInPictureMode() メソッドに関係なく、これらの設定が使用されます。

通知

Android 8.0(API レベル 26)では通知が再設計され、通知の動作と設定をより簡単かつ一貫した方法で管理できるようになりました。変更点は以下のとおりです。

    Android 8.0(API レベル 26)の通知の長押しメニュー

    Android 8.0 では、アプリ ランチャー アイコンを長押しして通知を表示できます。

  • 通知チャンネル: Android 8.0 には、表示する通知の種類ごとにユーザーがカスタマイズ可能な通知チャンネルを作成できる通知チャンネルが導入されています。ユーザー インターフェースでは、通知チャンネルは通知カテゴリと呼ばれます。通知チャンネルの実装方法については、通知チャンネルの管理をご覧ください。
  • 通知ドット: Android 8.0 では、アプリ ランチャー アイコン上にドットまたはバッジを表示できるようになりました。通知ドットは、ユーザーがまだ閉じていないか、または操作していない通知が存在することを表します。 通知ドットの使い方については、通知バッジをご覧ください。
  • スヌーズ: 通知をスヌーズできます。スヌーズを使用すると、通知が一定時間消えた後、再び表示されます。通知は、最初に表示されたのと同じ重要度で再表示されます。アプリはスヌーズされた通知を削除または更新できますが、スヌーズされた通知を更新しても、再度表示されることはありません。
  • 通知のタイムアウト: setTimeoutAfter() を使用して通知を作成するときに、タイムアウトを設定できます。このメソッドを使用して、通知をキャンセルする期間を指定できます。必要に応じて、指定したタイムアウト時間が経過する前に通知をキャンセルできます。
  • 通知設定: setSettingsText() を呼び出して、Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES インテントを使用して、通知からアプリの通知設定へのリンクを作成するときに表示されるテキストを設定できます。システムは、アプリがユーザーに表示する必要がある設定をフィルタリングするインテントに、EXTRA_CHANNEL_IDNOTIFICATION_TAGNOTIFICATION_ID のエクストラを提供できます。
  • 通知の消去: ユーザーは自分で通知を閉じることができます。アプリはプログラムで通知を削除できます。通知を閉じるタイミングと閉じた理由を特定するには、NotificationListenerService クラスから onNotificationRemoved() メソッドを実装します。
  • 背景色: 通知の背景色を設定して有効にできます。この機能は、ユーザーが一目でわかるように進行中のタスクの通知でのみ使用してください。たとえば、運転ルートや進行中の通話に関する通知の背景色を設定できます。setColor() を使用して背景色を設定することもできます。これにより、setColorized() を使用して通知の背景色を有効にできます。
  • メッセージ スタイル: Android 8.0 では、MessagingStyle クラスを使用する通知は、折りたたみフォームにより多くのコンテンツを表示します。メッセージング関連の通知には、MessagingStyle クラスを使用する必要があります。また、addHistoricMessage() メソッドを使用して、メッセージ関連の通知に履歴メッセージを追加して、会話にコンテキストを提供することもできます。

自動入力フレームワーク

アカウントの作成、ログイン、クレジット カードによるトランザクションには時間がかかり、エラーが発生しやすくなります。ユーザーは、この種の反復的なタスクを必要とするアプリにイライラする可能性があります。

Android 8.0(API レベル 26)では、自動入力フレームワークの導入により、ログイン フォームやクレジット カード フォームなどのフォームへの入力が容易になります。ユーザーが自動入力を有効にすると、既存のアプリと新しいアプリが自動入力フレームワークと連携します。

アプリとフレームワークの動作を最適化するには、いくつかの手順を実施します。詳細については、自動入力フレームワークの概要をご覧ください。

ダウンロード可能なフォント

Android 8.0(API レベル 26)と Android サポート ライブラリ 26 では、フォントを APK にバンドルしたり、APK でフォントをダウンロードさせたりする代わりに、プロバイダ アプリにフォントをリクエストできます。この機能により、APK のサイズが小さくなり、アプリのインストールの成功率が向上し、複数のアプリで同じフォントを共有できます。

フォントのダウンロードの詳細については、ダウンロード可能フォントをご覧ください。

XML フォント

Android 8.0(API レベル 26)では、フォントをリソースとして使用するための新機能「Fonts in XML」が導入されています。つまり、フォントをアセットとしてバンドルする必要はありません。フォントは R ファイルにコンパイルされ、リソースとしてシステムで自動的に使用可能になります。新しいリソースタイプ font を使用すると、これらのフォントにアクセスできます。

サポート ライブラリ 26 は、API バージョン 14 以降を搭載しているデバイスで、この機能を完全にサポートしています。

フォントをリソースとして使用し、システム フォントを取得する方法について詳しくは、XML のフォントをご覧ください。

TextView の自動サイズ設定

Android 8.0(API レベル 26)では、TextView のサイズに基づいて自動的にテキストを拡張または縮小するサイズを設定できます。つまり、さまざまな画面や動的コンテンツでテキストサイズを簡単に最適化できます。Android 8.0 での TextView の自動サイズ調整について詳しくは、TextView の自動サイズ設定をご覧ください。

アダプティブ アイコン

Android 8.0(API レベル 26)では、アダプティブ ランチャー アイコンが導入されています。アダプティブ アイコンは視覚効果をサポートし、デバイスモデルごとに異なる形状を表示できます。アダプティブ アイコンの作成方法については、アダプティブ アイコンのガイドをご覧ください。

カラー マネージメント

画像アプリの Android デベロッパーは、広色域対応ディスプレイを備えた新しいデバイスを活用できるようになりました。広色域画像を表示するには、アプリで(アクティビティごとに)フラグを有効にし、広色域プロファイル(AdobeRGB、Pro Photo RGB、DCI-P3 など)を埋め込んだビットマップを読み込む必要があります。

WebView API

Android 8.0 には、アプリでウェブ コンテンツを表示する WebView オブジェクトの管理に役立つ複数の API が用意されています。これらの API には、アプリの安定性とセキュリティを向上させるための次のような API が用意されています。

  • Version API
  • Google SafeBrowsing API
  • Termination Handle API
  • Renderer Importance API

これらの API の使用方法について詳しくは、WebView の管理をご覧ください。

WebView クラスに、ウェブ ブラウジングのセキュリティを強化するための Safe Browsing API が追加されました。詳しくは、Google Safe Browsing API をご覧ください。

ショートカットとウィジェットの固定

Android 8.0(API レベル 26)では、ショートカットとウィジェットのアプリ内固定が導入されています。アプリでは、ユーザーの権限に応じて、サポートされているランチャーの固定ショートカットとウィジェットを作成できます。

詳しくは、ショートカットとウィジェットの固定機能ガイドをご覧ください。

最大画面アスペクト比

Android 8.0(API レベル 26)では、アプリの最大アスペクト比の設定方法が変更されています。

まず、Android 8.0 では、アプリの最大アスペクト比の設定に使用できる maxAspectRatio 属性が導入されています。また、Android 8.0 以降では、アプリのデフォルトの最大アスペクト比は、アプリが実行されているデバイスのネイティブ アスペクト比になります。

最大アスペクト比の宣言について詳しくは、複数画面のサポートをご覧ください。

マルチディスプレイのサポート

Android 8.0(API レベル 26)以降、プラットフォームでは複数ディスプレイのサポートが強化されています。アクティビティがマルチウィンドウ モードをサポートし、複数のディスプレイを備えたデバイスで実行されている場合、ユーザーはディスプレイ間でアクティビティを移動できます。アプリは、アクティビティを起動する際に、アクティビティを実行するディスプレイを指定できます。

注: アクティビティがマルチウィンドウ モードをサポートしている場合、Android 8.0 では、そのアクティビティのマルチディスプレイのサポートが自動的に有効になります。アプリがマルチディスプレイ環境で適切に動作することをテストする必要があります。

アプリに複数のディスプレイがある場合でも、再開状態にできるアクティビティは一度に 1 つのみです。フォーカスされているアクティビティは再開状態です。表示されているその他のアクティビティはすべて一時停止されますが、停止はされません。複数のアクティビティが表示されている場合のアクティビティのライフサイクルについて詳しくは、マルチウィンドウ ライフサイクルをご覧ください。

ユーザーがアクティビティをあるディスプレイから別のディスプレイに移動すると、システムはアクティビティのサイズを変更し、必要に応じてランタイムの変更を発行します。アクティビティは構成の変更自体を処理できます。また、アクティビティを含むプロセスを破棄し、新しいディメンションで再作成することもできます。詳細については、構成の変更の処理をご覧ください。

ActivityOptions には、複数のディスプレイをサポートする 2 つの新しいメソッドが用意されています。

setLaunchDisplayId()
起動時にアクティビティを表示するディスプレイを指定します。
getLaunchDisplayId()
アクティビティの現在の起動画面を返します。

adb シェルは、複数のディスプレイをサポートするように拡張されています。これで、shell start コマンドを使用してアクティビティを起動し、アクティビティのターゲット ディスプレイを指定できるようになりました。

adb shell start <activity_name> --display <display_id>

統一されたレイアウト マージンとパディング

Android 8.0(API レベル 26)では、View 要素の両側で同じマージンまたはパディングを使用する状況を指定しやすくなります。具体的には、レイアウト XML ファイルで次の属性を使用できるようになりました。

注: テキスト方向など、さまざまな言語や文化をサポートするようにアプリのロジックをカスタマイズする場合、これらの属性は layout_marginStart layout_marginEnd paddingStart paddingEnd の値には影響しません。新しい縦方向と横方向のレイアウト属性に加えて、これらの値を自分で設定して、テキスト方向に依存するレイアウト動作を作成できます。

ポインタ キャプチャ

ゲーム、リモート デスクトップ、仮想化クライアントなどの一部のアプリでは、マウスポインタを制御することで多くのメリットが得られます。ポインタ キャプチャは、Android 8.0(API レベル 26)の新機能であり、すべてのマウスイベントをアプリ内のフォーカスされているビューに配信することで、このような制御を提供します。

Android 8.0 以降では、アプリの View でポインタ キャプチャをリクエストし、キャプチャされたポインタ イベントを処理するリスナーを定義できます。このモードでは、マウスポインタは表示されません。マウス情報が必要なくなったら、ビューはポインタ キャプチャを解放できます。また、ユーザーが別のアプリを開くときなど、ビューがフォーカスを失ったときにポインタ キャプチャを解放することもできます。

アプリでこの機能を使用する方法については、ポインタ キャプチャをご覧ください。

アプリのカテゴリ

Android 8.0(API レベル 26)では、各アプリが該当するカテゴリを必要に応じて宣言できます。これらのカテゴリは、データ使用量、バッテリー使用量、ストレージ使用量など、ユーザーに提示する際に、目的や機能が似ているアプリをクラスタ化するために使用されます。アプリのカテゴリを定義するには、<application> マニフェスト タグで android:appCategory 属性を設定します。

Android TV ランチャー

Android 8.0(API レベル 26)には、コンテンツ中心の新しい Android TV ホーム画面エクスペリエンスが含まれており、Android 8.0 用の Android TV エミュレータと Nexus Player デバイス イメージで利用できます。新しいホーム画面では、動画コンテンツがチャンネルに対応する行に並んで表示されます。各チャンネルには、システム上のアプリによって番組が表示されます。アプリは複数のチャンネルを公開でき、ユーザーはホーム画面に表示するチャンネルを構成できます。Android TV のホーム画面には Watch Next 行もあり、ユーザーの視聴習慣に基づいてアプリのプログラムが表示されます。アプリでは動画プレビューを提供することもできます。動画プレビューは、ユーザーが番組にフォーカスすると自動的に再生されます。チャンネルと番組を入力するための API は TvProvider API の一部であり、Android 8.0 で Android サポート ライブラリ モジュールとして配布されます。

AnimatorSet

Android 8.0(API レベル 26)以降、AnimatorSet API でシークと逆方向の再生がサポートされるようになりました。シークを行うと、アニメーション セットの位置を特定の時点に設定できます。逆再生は、元に戻すことができるアクションのアニメーションがアプリに含まれている場合に便利です。2 つのアニメーション セットを別々に定義する代わりに、同じアニメーション セットを逆方向に再生することができます。

入力とナビゲーション

キーボード ナビゲーション クラスタ

図 2 のような複雑なビュー階層をアプリ内のアクティビティで使用する場合は、UI 要素のグループをクラスタ化して、キーボードでの操作を容易にすることを検討してください。Chromebook デバイスでは、Meta+Tab キーまたは Search+Tab キーを押して、クラスタ間を移動できます。クラスタの適切な例としては、サイドパネル、ナビゲーション バー、メイン コンテンツ エリア、多数の子要素を含む可能性のある要素などがあります。

ユーザーがキーボード ナビゲーション クラスタ ショートカットを使用して移動できる 5 つのナビゲーション クラスタを含むアクティビティの例。クラスタは、上部パネル、左側のパネル、メイン コンテンツ領域、下部パネル、フローティング アクション ボタンの配置で表示されます。
図 2. 5 つのナビゲーション クラスタを含むアクティビティ

View 要素または ViewGroup 要素をクラスタにするには、要素のレイアウト XML ファイルで android:keyboardNavigationCluster 属性を true に設定するか、アプリの UI ロジックの setKeyboardNavigationCluster()true を渡します。

注: クラスタはネストできませんが、ネストされていないクラスタが階層のさまざまなレベルに表示される場合があります。クラスタをネストしようとすると、フレームワークは最上位の ViewGroup 要素のみをクラスタとして扱います。

タッチスクリーンを備えたデバイスでは、クラスタ指定の ViewGroup オブジェクトの android:touchscreenBlocksFocus 要素を true に設定すると、クラスタでのみそのクラスタ内外に移動できるようになります。この構成をクラスタに適用すると、ユーザーは Tab キーまたは矢印キーを使用してクラスタ内外に移動することはできません。代わりにクラスタ ナビゲーションのキーボードの組み合わせを押す必要があります。

デフォルトのフォーカスを表示

Android 8.0(API レベル 26)では、(再作成された)アクティビティが再開され、ユーザーがキーボード ナビゲーション キー(Tab キーなど)を押した後にフォーカスを受け取る View を割り当てることができます。この「デフォルトでフォーカスされる」設定を適用するには、UI 要素を含むレイアウト XML ファイルで View 要素の android:focusedByDefault 属性を true に設定するか、アプリの UI ロジックで truesetFocusedByDefault() に渡します。

音声出力

アクティビティとサービスでは、TextToSpeech のインスタンスを使用して、コンテンツの音声入力と発音を行えます。Android 8.0(API レベル 26)以降では、テキスト読み上げエンジンが個々の合成単語の読み上げを開始するタイミングについて、エンジンがこの情報を提供している限り、より正確なタイミング情報を取得できます。この機能を使用すると、テキスト読み上げエンジンが特定の単語を読み上げるときに、その単語に注意を引くことができます。

このような改善されたテキスト読み上げエンジンをアプリで使用するには、UtteranceProgressListener のインスタンスを登録します。登録プロセスの一環として、onRangeStart() メソッドのハンドラを含めます。

テキスト読み上げエンジンは、rangeStart() を呼び出して、特定の範囲のテキストの音声再生が開始されると期待する時点を記録します。そのテキスト範囲の音声の再生が開始されると、アプリの onRangeStart() メソッドが実行されます。アプリは、発話に関連付けられているテキスト範囲をハイライト表示するなどして、このコールバックに応答できます。

テキスト読み上げエンジンの再生進行状況のトラッキングについて詳しくは、UtteranceProgressListener クラスのリファレンスをご覧ください。

システム

新しい StrictMode 検出機能

Android 8.0(API レベル 26)では、アプリの潜在的なバグの特定に役立つ 3 つの新しい StrictMode 検出機能が追加されています。

  • detectUnbufferedIo() は、パフォーマンスに大きな影響を与える可能性のあるバッファリングなしで、アプリがデータの読み取りと書き込みを行ったタイミングを検出します。
  • detectContentUriWithoutPermission() は、アプリ外でアクティビティを開始したときに、アプリが別のアプリに権限の付与を誤って忘れている場合に検出します。
  • detectUntaggedSockets() は、デバッグ目的でトラフィックにタグを付けるために setThreadStatsTag(int) を使用せずに、アプリがネットワーク トラフィックを実行するタイミングを検出します。

キャッシュ データ

Android 8.0(API レベル 26)では、キャッシュされたデータに関するガイダンスと動作が改善されています。各アプリに、getCacheQuotaBytes(UUID) によって返される、キャッシュに保存されたデータ用のディスク容量の割り当てが追加されました。

システムでディスク スペースを解放する必要がある場合は、まず、割り当てられた割り当てを最も多いアプリからキャッシュ ファイルを削除します。したがって、キャッシュに保存されたデータを割り当てられた割り当て内に収めると、キャッシュに保存されたファイルはシステム上で必要に応じて消去される最後のファイルの一部になります。システムは、キャッシュに保存されているファイルのうちどれをアプリ内で削除するかを決定するときは、最も古いファイル(変更時刻から判断)から先に検討します。

また、システムがキャッシュ データを解放する方法を制御するために、ディレクトリ単位で有効にできる新しい動作が 2 つあります。

  • StorageManager.setCacheBehaviorAtomic() を使用すると、ディレクトリとそのすべてのコンテンツを 1 つのアトミック単位として削除するよう指示できます。
  • setCacheBehaviorTombstone(File, boolean) を使用すると、ディレクトリ内のファイルを削除するのではなく、空のファイルをそのまま残し、長さが 0 バイトに切り詰められます。

最後に、大きなファイルにディスク容量を割り当てる必要がある場合は、新しい allocateBytes(FileDescriptor, long) API の使用を検討してください。この API は、リクエストを満たすために、他のアプリに属するキャッシュされたファイルを(必要に応じて)自動的に消去します。デバイスに新しいデータを保持するのに十分なディスク容量があるかどうかを判断する際は、getUsableSpace() を使用する代わりに getAllocatableBytes(UUID) を呼び出します。前者は、システムが消去するキャッシュ データをすべて考慮するためです。

コンテンツ プロバイダのページング

コンテンツ プロバイダが更新され、大規模なデータセットを 1 ページずつ読み込む機能が追加されました。たとえば、何千枚もの画像を含む写真アプリでは、ページに表示するデータのサブセットをクエリできます。コンテンツ プロバイダから返される結果の各ページは、1 つの Cursor オブジェクトで表されます。この機能を使用するには、クライアントとプロバイダの両方でページングを実装する必要があります。

コンテンツ プロバイダの変更について詳しくは、ContentProviderContentProviderClient をご覧ください。

コンテンツ更新リクエスト

ContentProvider クラスと ContentResolver クラスにそれぞれ refresh() メソッドが含まれるようになりました。これにより、クライアントはリクエストした情報が最新かどうかを簡単に確認できるようになります。

ContentProvider を拡張することで、カスタム コンテンツの更新ロジックを追加できます。refresh() メソッドをオーバーライドして true を返し、自分でデータを更新しようとしたことをプロバイダのクライアントに示すようにしてください。

クライアント アプリは、別のメソッド(refresh() とも呼ばれます)を呼び出すことで、更新されたコンテンツを明示的にリクエストできます。このメソッドを呼び出すときは、更新するデータの URI を渡します。

注: ネットワーク経由でデータをリクエストする可能性があるため、コンテンツが古くなっていることが明らかな場合にのみ、クライアント側から refresh() を呼び出してください。このタイプのコンテンツの更新を行う最も一般的な理由は、スワイプでの更新操作、つまり最新のコンテンツを表示するように現在の UI を明示的にリクエストする場合です。

JobScheduler の改善

Android 8.0(API レベル 26)では、JobScheduler に複数の改善が行われています。これらの改善により、アプリは新しいバックグラウンド実行制限に簡単に準拠できるようになります。これは通常、スケジュール設定されたジョブを使用して、制限されたバックグラウンド サービスや暗黙的なブロードキャスト レシーバを置き換えることができます。

JobScheduler の更新内容は次のとおりです。

  • 作業キューをスケジュールされたジョブに関連付けることができるようになりました。ジョブのキューに作業アイテムを追加するには、JobScheduler.enqueue() を呼び出します。ジョブの実行時に、保留中の作業をキューから外して処理できます。この機能は、これまでバックグラウンド サービス(特に IntentService を実装するサービス)を開始するために呼び出していた多くのユースケースを処理します。
  • Android サポート ライブラリ 26.0.0 では、新しい JobIntentService クラスが導入されました。このクラスは IntentService と同じ機能を提供しますが、Android 8.0(API レベル 26)以降で実行されている場合はサービスではなくジョブを使用します。
  • これで、JobInfo.Builder.setClipData() を呼び出して ClipData をジョブに関連付けることができるようになりました。このオプションを使用すると、URI 権限の付与を Context.startService() に伝播する方法と同様に、ジョブに関連付けることができます。ワークキューのインテントで URI 権限付与を使用することもできます。
  • スケジュールされたジョブが、いくつかの新しい制約をサポートするようになりました。
    JobInfo.isRequireStorageNotLow()
    デバイスの空き容量が少ない場合、ジョブは実行されません。
    JobInfo.isRequireBatteryNotLow()
    バッテリー残量が重大なしきい値以下である場合、ジョブは実行されません。このレベルに達したら、デバイスが「バッテリー残量低下」システム ダイアログを表示します。
    NETWORK_TYPE_METERED
    ジョブには、ほとんどのモバイルデータ プランと同様に、従量制ネットワーク接続が必要です。

カスタム データストア

Android 8.0(API レベル 26)では、設定にカスタム データストアを提供できます。これは、アプリが設定をクラウドまたはローカル データベースに保存する場合や、設定がデバイス固有の場合に役立ちます。データストアの実装の詳細については、カスタム データストアをご覧ください。

メディアの機能強化

VolumeShaper

新しい VolumeShaper クラスがあります。フェードイン、フェードアウト、クロスフェードなどの短い自動音量移行を実行する場合に使用します。詳しくは、VolumeShaper で振幅を制御するをご覧ください。

音声フォーカスの機能強化

オーディオ アプリは、音声フォーカスをリクエストしたり放棄したりすることで、デバイスの音声出力を共有します。アプリは、再生を開始または停止するか、音量をダッキングすることで、フォーカスの変更を処理します。新しい AudioFocusRequest クラスがあります。このクラスを requestAudioFocus() のパラメータとして使用すると、音声フォーカスの変化を処理するときに、自動ダッキング遅延フォーカス ゲインという新しい機能がアプリで可能になります。

メディア指標

新しい getMetrics() メソッドは、属性と値のマップとして表現された、構成とパフォーマンスの情報を含む PersistableBundle オブジェクトを返します。getMetrics() メソッドは、次のメディアクラス用に定義されています。

指標はインスタンスごとに個別に収集され、インスタンスの存続期間中は保持されます。使用可能な指標がない場合、メソッドは null を返します。実際に返される指標はクラスによって異なります。

MediaPlayer

Android 8.0(API レベル 26)以降の MediaPlayer では、DRM で保護されたマテリアルと HLS サンプルレベルの暗号化されたメディアを再生できます。

Android 8.0 では、新たにオーバーロードされた seekTo() コマンドが導入され、フレームのシークをきめ細かく制御できます。シーク モードを指定する 2 つ目のパラメータがあります。

  • SEEK_PREVIOUS_SYNC は、メディア位置を、指定された時刻の直前または時点にあるデータソースに関連付けられている同期(またはキー)フレームに移動します。
  • SEEK_NEXT_SYNC は、メディア位置を、指定された時刻の直後または時点にあるデータソースに関連付けられている同期(またはキー)フレームに移動します。
  • SEEK_CLOSEST_SYNC は、メディア位置を、指定された時刻に最も近い、またはある時点のデータソースに関連付けられた同期(またはキー)フレームに移動します。
  • SEEK_CLOSEST は、メディアの位置を、指定された時間に最も近い、またはある時点で配置されているデータソースに関連付けられたフレーム(必ずしも同期フレームやキーフレームではない)に移動します。

連続してシークする場合、アプリは SEEK_CLOSEST モードではなく、SEEK_ モードのいずれかを使用する必要があります。モードは、実行速度が比較的遅くなりますが、精度が向上します。

MediaRecorder

  • MediaRecorder は、ストリーミングに役立つ MPEG2_TS 形式をサポートするようになりました。

    Kotlin

    mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_2_TS)
    

    Java

    mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_2_TS);
    

    MediaRecorder.OutputFormatを見る

  • MediaMuxer が任意の数の音声ストリームと動画ストリームを処理できるようになりました。音声トラックや動画トラックが 1 つに制限されなくなりました。addTrack() を使用して、任意の数のトラックをミキシングできます。
  • MediaMuxer は、ユーザー定義のフレームごとの情報を含む 1 つ以上のメタデータ トラックを追加することもできます。メタデータの形式はアプリケーションによって定義されます。メタデータ トラックは MP4 コンテナでのみサポートされています。

メタデータをオフライン処理に活用できます。たとえば、センサーからのジャイロ信号を使用して動画の手ぶれ補正を行うことができます。

メタデータ トラックを追加する場合、トラックの MIME 形式の先頭は「application/」にする必要があります。メタデータの書き込みは、データが MediaCodec から取得されない点を除き、動画/音声データの書き込みと同じです。代わりに、アプリは ByteBuffer と関連するタイムスタンプを writeSampleData() メソッドに渡します。タイムスタンプは、動画トラックや音声トラックと同じタイムベースである必要があります。

生成された MP4 ファイルは、ISOBMFF のセクション 12.3.3.2 で定義されている TextMetaDataSampleEntry を使用して、メタデータの MIME 形式を通知します。MediaExtractor を使用してメタデータ トラックを含むファイルを抽出する場合、メタデータの MIME 形式は MediaFormat に抽出されます。

メディア ファイルへのアクセスの改善

ストレージ アクセス フレームワーク(SAF)を使用すると、アプリはカスタム DocumentsProvider を公開できます。これにより、データソース内のファイルへのアクセスを他のアプリに提供できます。実際、ドキュメント プロバイダは、ネットワーク ストレージ上に存在するファイルや、メディア転送プロトコル(MTP)などのプロトコルを使用するファイルへのアクセスを提供することもできます。

ただし、リモート データソースから大きなメディア ファイルにアクセスするには、次のような課題があります。

  • メディア プレーヤーには、ドキュメント プロバイダのファイルへのシーク可能なアクセスが必要です。サイズの大きいメディア ファイルがリモート データソースにある場合、ドキュメント プロバイダは事前にすべてのデータを取得し、スナップショット ファイル記述子を作成する必要があります。メディア プレーヤーはファイル記述子なしでファイルを再生できないため、ドキュメント プロバイダがファイルのダウンロードを完了するまで再生を開始できません。
  • 写真アプリなどのメディア コレクション マネージャーは、一連のアクセス URI を走査して、範囲指定されたフォルダを介して外部 SD カードに保存されているメディアにアクセスする必要があります。このアクセス パターンにより、移動、コピー、削除などのメディアに対する大量オペレーションが非常に遅くなります。
  • メディア コレクション マネージャーは、指定された URI でドキュメントの場所を特定できません。そのため、この種のアプリでは、メディア ファイルの保存場所をユーザーが選択することが難しくなります。

Android 8.0 では、ストレージ アクセス フレームワークを改善することで、これらの課題に対処しています。

カスタム ドキュメント プロバイダ

Android 8.0 以降では、ストレージ アクセス フレームワークにより、カスタム ドキュメント プロバイダがリモート データソースに存在するファイルに対してシーク可能なファイル記述子を作成できるようになりました。SAF はファイルを開いて、ネイティブのシーク可能なファイル記述子を取得できます。その後、SAF は個別のバイト リクエストをドキュメント プロバイダに配信します。この機能により、ドキュメント プロバイダはファイル全体を事前にキャッシュするのではなく、メディア プレーヤー アプリがリクエストした正確な範囲のバイトを返すことができます。

この機能を使用するには、新しい StorageManager.openProxyFileDescriptor() メソッドを呼び出す必要があります。openProxyFileDescriptor() メソッドは、コールバックとして ProxyFileDescriptorCallback オブジェクトを受け取ります。ドキュメント プロバイダから返されたファイル記述子に対してクライアント アプリケーションがファイル オペレーションを実行するたびに、SAF はコールバックを呼び出します。

ドキュメントへの直接アクセス

Android 8.0(API レベル 26)以降では、getDocumentUri() メソッドを使用して、指定された mediaUri と同じドキュメントを参照する URI を取得できます。ただし、返される URI は DocumentsProvider に基づいているため、メディア コレクション マネージャーは、スコープ設定されたディレクトリのツリーを走査することなく、ドキュメントに直接アクセスできます。その結果、メディア マネージャーはドキュメントに対するファイル操作をより迅速に実行できます。

注意: getDocumentUri() メソッドはメディア ファイルを探すだけであり、メディア ファイルにアクセスする権限がアプリに付与されることはありません。メディア ファイルへのアクセス権を取得する方法について詳しくは、リファレンス ドキュメントをご覧ください。

ドキュメントへのパス

Android 8.0(API レベル 26)でストレージ アクセス フレームワークを使用する場合は、DocumentsContract クラスと DocumentsProvider クラスの両方で findDocumentPath() メソッドを使用して、ドキュメント ID に基づいてファイル システムのルートからパスを特定できます。このメソッドは、このパスを DocumentsContract.Path オブジェクトで返します。ファイル システムに同じドキュメントへのパスが複数定義されている場合、このメソッドは、指定された ID のドキュメントに到達するために最も頻繁に使用されるパスを返します。

この機能は、次のようなシナリオで特に役立ちます。

  • アプリで、特定のドキュメントの場所を表示する「名前を付けて保存」ダイアログを使用している。
  • アプリの検索結果ビューにフォルダが表示されます。ユーザーが特定のフォルダを選択した場合、そのフォルダ内の子ドキュメントを読み込む必要があります。

注: アプリがパス内の一部のドキュメントのみにアクセスする権限を持っている場合、findDocumentPath() の戻り値には、アプリがアクセスできるフォルダとドキュメントのみが含まれます。

音声再生のモニタリング

AudioManager システム サービスは、アクティブな AudioPlaybackConfiguration オブジェクトのリストを保持します。各オブジェクトには、特定の音声再生セッションに関する情報が含まれています。アプリは getActivePlaybackConfigurations() を呼び出すことで、現在アクティブな構成のセットを取得できます。

Android 8.0(API レベル 26)以降では、1 つ以上の AudioPlaybackConfiguration オブジェクトが変更されたときにアプリに通知するコールバックを登録できます。そのためには、registerAudioPlaybackCallback() を呼び出して AudioManager.AudioPlaybackCallback のインスタンスを渡します。AudioManager.AudioPlaybackCallback クラスには、音声再生の構成が変更されたときにシステムによって呼び出される onPlaybackConfigChanged() メソッドが含まれます。

接続

Wi-Fi Aware

Android 8.0(API レベル 26)では、Neighbor Awareness Networking(NAN)仕様に基づく Wi-Fi Aware のサポートが追加されています。適切な Wi-Fi Aware ハードウェアを備えたデバイスでは、インターネット アクセス ポイントがなくても、アプリと付近のデバイスが Wi-Fi 経由で検出して通信できます。Google はハードウェア パートナーと連携して、Wi-Fi Aware 技術をできるだけ早くデバイスに導入できるよう取り組んでいます。Wi-Fi Aware をアプリに統合する方法については、Wi-Fi Aware をご覧ください。

Bluetooth

Android 8.0(API レベル 26)では、以下の機能が追加され、プラットフォームの Bluetooth サポートが強化されています。

  • 曲ライブラリのブラウジングを可能にする AVRCP 1.4 標準をサポートします。
  • Bluetooth Low Energy(BLE)5.0 規格のサポート。
  • Sony LDAC コーデックの Bluetooth スタックへの統合。

コンパニオン デバイスのペア設定

Android 8.0(API レベル 26)には、Bluetooth、BLE、Wi-Fi 経由でコンパニオン デバイスとペア設定する場合に、ペア設定リクエスト ダイアログをカスタマイズできる API が用意されています。詳しくは、コンパニオン デバイスのペア設定をご覧ください。

Android での Bluetooth の使用について詳しくは、Bluetooth ガイドをご覧ください。Android 8.0(API レベル 26)に固有の Bluetooth の変更については、Android 8.0 の動作変更ページの Bluetooth セクションをご覧ください。

共有

スマート共有

Android 8.0(API レベル 26)では、ユーザーのパーソナライズされた共有設定を学習し、共有に適したアプリであるコンテンツの種類ごとに理解を深めています。たとえば、ユーザーが領収書の写真を撮った場合、Android 8.0 は経費トラッキング アプリを提案できます。ユーザーが自撮り写真を撮影すると、ソーシャル メディア アプリが画像を適切に処理できます。Android 8.0 は、ユーザーのパーソナライズされた設定に従って、これらのパターンをすべて自動的に学習します。

スマート共有は、audiovideotextURL など、image 以外のコンテンツ タイプで機能します。

スマート共有を有効にするには、コンテンツを共有するインテントに、最大 3 つの文字列のアノテーションの ArrayList を追加します。アノテーションは、コンテンツの主なコンポーネントやトピックを説明する必要があります。インテントにアノテーションを追加するサンプルコードを以下に示します。

Kotlin

val annotations: ArrayList<String> = arrayListOf(
        "topic1",
        "topic2",
        "topic3"
)

intent.putStringArrayListExtra(
        Intent.EXTRA_CONTENT_ANNOTATIONS,
        annotations
)

Java

ArrayList<String> annotations = new ArrayList<>();

annotations.add("topic1");
annotations.add("topic2");
annotations.add("topic3");

intent.putStringArrayListExtra(
    Intent.EXTRA_CONTENT_ANNOTATIONS,
    annotations
);

スマート共有アノテーションの詳細については、EXTRA_CONTENT_ANNOTATIONS をご覧ください。

Text classifier

互換性のあるデバイスでは、アプリは新しいテキスト分類を使用して、文字列が既知の分類器エンティティ タイプと一致するかどうかをチェックし、選択の代替候補を取得できます。システムが認識するエンティティには、住所、URL、電話番号、メールアドレスなどがあります。詳細については、TextClassifier をご覧ください。

ユーザー補助

Android 8.0(API レベル 26)では、独自のユーザー補助サービスを作成するデベロッパー向けに、新しいユーザー補助機能がいくつかサポートされています。

アプリのユーザー補助機能を強化する方法について詳しくは、ユーザー補助機能をご覧ください。

セキュリティとプライバシー

権限

Android 8.0(API レベル 26)では、電話に関連する新しい権限がいくつか導入されています。

  • ANSWER_PHONE_CALLS 権限により、アプリはプログラムで着信に応答できるようになります。アプリで電話の着信を処理するには、acceptRingingCall() メソッドを使用します。
  • READ_PHONE_NUMBERS 権限を付与すると、デバイスに保存されている電話番号に対する読み取りアクセス権がアプリに付与されます。

これらの権限はどちらも dangerous に分類され、PHONE 権限グループに属します。

新しいアカウント アクセスと Discovery API

Android 8.0(API レベル 26)では、アプリがユーザー アカウントにアクセスする方法がいくつか改善されています。管理対象のアカウントについて、認証システムは独自のポリシーを使用して、アプリに対してアカウントを非表示にするか、またはアプリに対してアカウントを公開するかを決定できます。Android システムは、特定のアカウントにアクセスできるアプリを追跡します。

以前のバージョンの Android では、ユーザー アカウントのリストを追跡するアプリは、無関係なタイプのアカウントを含むすべてのアカウントに関する最新情報を取得する必要がありました。Android 8.0 では、addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[]) メソッドが追加されています。これにより、アカウントの変更を受け取る必要があるアカウントの種類のリストをアプリで指定できます。

API の変更

AccountManager には、アカウントを参照できるアプリを認証システムで管理するための 6 つの新しいメソッドが用意されています。

Android 8.0(API レベル 26)では、setAccountVisibility(android.accounts.Account, java.lang.String, int) メソッドを使用して設定されなかったアプリの公開設定レベルを指定するために、2 つの特別なパッケージ名の値が導入されています。PACKAGE_NAME_KEY_LEGACY_VISIBLE の公開設定値は、GET_ACCOUNTS 権限が付与されていて、Android 8.0 より前のバージョンの Android をターゲットとするアプリ、または任意の Android バージョンをターゲットとする認証システムと署名が一致するアプリに適用されます。PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE は、以前に設定されておらず PACKAGE_NAME_KEY_LEGACY_VISIBLE が適用されないアプリに、デフォルトの公開設定値を指定します。

新しいアカウントへのアクセス API と検出 API の詳細については、AccountManagerOnAccountsUpdateListener のリファレンスをご覧ください。

テスト

インストルメンテーション テスト

Android 8.0(API レベル 26)では、アプリのインストルメンテーション テストに関して、以下のサポートが追加されています。

デフォルト以外のアプリプロセスに対して実行する

アプリのデフォルト プロセス以外のプロセスに対して特定のインストルメンテーション テストを実行するように指定できるようになりました。この構成は、異なるプロセスで実行される複数のアクティビティがアプリに含まれている場合に便利です。

デフォルト以外のプロセスのインストルメンテーションを定義するには、マニフェスト ファイルから目的の <instrumentation> 要素に移動します。android:targetProcess 属性を追加し、値を次のいずれかに設定します。

  • 特定のプロセスの名前。
  • プロセス名のカンマ区切りのリスト。
  • ワイルドカード("*")。これにより、android:targetPackage 属性で指定されたパッケージ内のコードを実行する起動済みプロセスに対してインストルメンテーションを実行できます。

インストルメンテーション テストの実行中に、getProcessName() を呼び出すことで、テスト対象のプロセスを確認できます。

テスト中に結果を報告する

addResults() を呼び出すことで、インストルメンテーション テストの実行後ではなく実行中に結果を報告できるようになりました。

テスト用のモック インテント

アプリのアクティビティの独立した独立した UI テストを簡単に作成できるように、Android 8.0(API レベル 26)では onStartActivity() メソッドが導入されています。Instrumentation.ActivityMonitor クラスのカスタム サブクラスでこのメソッドをオーバーライドして、テストクラスが呼び出す特定のインテントを処理します。

テストクラスがインテントを呼び出すと、メソッドはインテント自体を実行するのではなく、スタブ Instrumentation.ActivityResult オブジェクトを返します。テストでこのモック インテント ロジックを使用することで、別のアクティビティやまったく別のアプリに渡すインテントをアクティビティがどのように準備して処理するかに集中できます。

ランタイムとツール

プラットフォームの最適化

Android 8.0(API レベル 26)では、プラットフォームにランタイムやその他の最適化が導入され、多くのパフォーマンス改善が行われています。これらの最適化には、同時実行圧縮ガベージ コレクション、メモリの効率的な使用、コードの局所性が含まれます。

この最適化により、起動時間が短縮され、OS とアプリの両方のパフォーマンスが向上します。

Java 言語のサポートの更新

Android 8.0(API レベル 26)では、次のような OpenJDK Java API のサポートが追加されています。

新しく追加されたパッケージ内のクラスとメソッドの詳細については、API リファレンス ドキュメントをご覧ください。

Android Studio で Java 8 言語機能を使用する場合は、最新のプレビュー版をダウンロードする必要があります。

ICU4J Android フレームワーク API の更新

Android 8.0(API レベル 26)では、アプリ デベロッパーが android.icu パッケージで使用できるよう、ICU4J API のサブセットである ICU4J Android フレームワーク API が拡張されています。これらの API はデバイスに存在するローカライズ データを使用するため、APK に ICU4J ライブラリをコンパイルせずに APK のフットプリントを削減できます。

表 1. Android で使用される ICU、CLDR、Unicode のバージョン。

Android API レベル ICU バージョン CLDR のバージョン Unicode バージョン
Android 7.0(API レベル 24)、Android 7.1(API レベル 25) 56 28 8.0
Android 8.0(API レベル 26) 58.2 30.0.3 9.0

ICU4J のサポートなど、Android での国際化について詳しくは、 Android での国際化をご覧ください。

Android Enterprise

Android 8.0(API レベル 26)を搭載したデバイス向けに、新しいエンタープライズ機能と API が導入されました。次のような特徴があります。

  • 完全管理対象デバイス上の仕事用プロファイルにより、企業は仕事用と個人データを分けながら、両方のデータを管理できます。
  • API 委任を使用すると、デバイス所有者とプロファイル所有者がアプリの管理を他のアプリに割り当てられるようになります。
  • プロビジョニング フローのユーザー エクスペリエンスの改善(新しいカスタマイズ オプションを含む)により、セットアップ時間を短縮できます。
  • Bluetooth、Wi-Fi、バックアップ、セキュリティに対する新しいコントロールにより、企業はより多くのデバイスを管理できます。ネットワーク アクティビティ ロギングは、企業が問題を追跡するのに役立ちます。

これらをはじめとした Android Enterprise の新しい API や機能の詳細については、Android Enterprise in the Enterprise をご覧ください。