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() を使用して通知の作成時にタイムアウトを設定できます。このメソッドを使用すると、通知をキャンセルするまでの時間を指定できます。必要に応じて、指定したタイムアウト時間が経過する前に通知をキャンセルできます。
  • 通知設定: Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES インテントを使用して、通知からアプリの通知設定へのリンクを作成するときに表示されるテキストを設定するには、setSettingsText() を呼び出します。システムは、アプリがユーザーに表示する設定をフィルタリングするインテントを持つエクストラ 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
  • 終了ハンドル 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 TV エミュレータと Android 8.0 用の Nexus Player デバイス イメージで利用できます。新しいホーム画面では、動画コンテンツがチャンネルに対応する行に整理され、各チャンネルにはシステム上のアプリによって番組が入力されます。アプリは複数のチャンネルを公開でき、ユーザーはホーム画面に表示するチャンネルを構成できます。Android TV のホーム画面には Watch Next 行もあり、ユーザーの視聴習慣に基づいてアプリの番組が表示されます。アプリで動画プレビューを提供することもできます。動画プレビューは、ユーザーがプログラムにフォーカスすると自動的に再生されます。チャンネルとプログラムにデータを入力する API は、TvProvider API の一部です。TvProvider API は、Android 8.0 で Android サポート ライブラリ モジュールとして配布されます。

AnimatorSet

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

入力とナビゲーション

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

アプリ内のアクティビティで、図 2 のような複雑なビュー階層を使用する場合は、UI 要素のグループをクラスタ化して、キーボード操作を容易にすることを検討してください。ユーザーは、Meta+Tab キーまたは Chromebook デバイスでは検索+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 権限付与をジョブに関連付けることができます。ワークキューのインテントで URI 権限付与を使用することもできます。
  • スケジュール設定されたジョブで、次の新しい制約がサポートされるようになりました。
    JobInfo.isRequireStorageNotLow()
    デバイスの空き容量が少ない場合、ジョブは実行されません。
    JobInfo.isRequireBatteryNotLow()
    バッテリー残量が重大なしきい値以下の場合、ジョブは実行されません。このレベルに達したときに、デバイスがバッテリー残量低下のシステム ダイアログを表示します。
    NETWORK_TYPE_METERED
    ジョブに、ほとんどのモバイルデータ プランと同様に、従量制のネットワーク接続が必要です。

カスタム データストア

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

メディアの機能強化

VolumeShaper

新しい VolumeShaper クラスがあります。フェードイン、フェードアウト、クロスフェードなどの短時間の音量の自動切り替えに使用します。 詳しくは、VolumeShaper で Amplitude を制御するをご覧ください。

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

オーディオ アプリは、音声フォーカスのリクエストと放棄により、デバイスの音声出力を共有します。アプリは、再生を開始または停止するか、音量を下げることで、フォーカスの変更を処理します。新しい 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 から取得されない点を除き、動画/音声データの書き込みと同じです。代わりに、アプリは、関連付けられたタイムスタンプを含む ByteBufferwriteSampleData() メソッドに渡します。タイムスタンプは、動画トラックや音声トラックと同じタイムベースにする必要があります。

生成された 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 規格のサポート。
  • Bluetooth スタックに Sony LDAC コーデックを統合。

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

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 が Android 8.0 より前のアプリ、または Android バージョンをターゲットとする認証システムと署名が一致するアプリに適用されます。 PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE は、以前に設定されておらず、PACKAGE_NAME_KEY_LEGACY_VISIBLE が適用されないアプリに対して、デフォルトの公開設定値を指定します。

新しいアカウント アクセスと Discovery 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 Android フレームワーク API(ICU4J 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 をご覧ください。