動作の変更点: Android 16 以上をターゲットとするアプリ

これまでのリリースと同様、Android 16 には、アプリに影響する可能性がある動作変更が含まれています。下記の動作変更は、Android 16 以上をターゲットとするアプリにのみ適用されます。アプリが Android 16 以上をターゲットとする場合は、必要に応じてアプリを変更し、下記の動作に対応できるようにしてください。

アプリの targetSdkVersion に関係なく、Android 16 で実行されるすべてのアプリに影響する動作変更のリストも必ずご確認ください。

ユーザー エクスペリエンスとシステム UI

Android 16(API レベル 36)には、より一貫性のある直感的なユーザー エクスペリエンスを実現するための以下の変更が含まれています。

エッジ ツー エッジのオプトアウトの廃止

Android 15 では、Android 15(API レベル 35)をターゲットとするアプリに対してエッジ ツー エッジが強制適用されましたが、R.attr#windowOptOutEdgeToEdgeEnforcementtrue に設定することで、アプリはエッジ ツー エッジを無効にできます。Android 16(API レベル 36)をターゲットとするアプリの場合、R.attr#windowOptOutEdgeToEdgeEnforcement は非推奨となり無効化されます。アプリでエッジ ツー エッジ モードを無効にすることはできません。

  • アプリが Android 16(API レベル 36)をターゲットとしており、Android 15 デバイスで実行されている場合、R.attr#windowOptOutEdgeToEdgeEnforcement は引き続き動作します。
  • アプリが Android 16(API レベル 36)をターゲットとしており、Android 16 デバイスで実行されている場合、R.attr#windowOptOutEdgeToEdgeEnforcement は無効になります。

Android 16 でテストする場合は、アプリがエッジ ツー エッジに対応していることを確認し、R.attr#windowOptOutEdgeToEdgeEnforcement の使用をすべて削除して、Android 15 デバイスでもエッジ ツー エッジに対応するようにします。エッジ ツー エッジをサポートするには、ComposeViews のガイダンスをご覧ください。

予測型「戻る」には移行またはオプトアウトが必要

Android 16(API レベル 36)以上をターゲットとし、Android 16 以上のデバイスで実行されるアプリの場合、予測型「戻る」のシステム アニメーション(ホームに戻る、タスク間、アクティビティ間)はデフォルトで有効になっています。また、onBackPressed は呼び出されず、KeyEvent.KEYCODE_BACK はディスパッチされなくなります。

アプリが「戻る」イベントをインターセプトしていて、予測型「戻る」にまだ移行していない場合は、サポートされている「戻る」ナビゲーション API を使用するようにアプリを更新するか、アプリの AndroidManifest.xml ファイルの <application> または <activity> タグで android:enableOnBackInvokedCallback 属性を false に設定して、一時的にオプトアウトします。

ホームに戻る予測型「戻る」アニメーション。
予測型クロス アクティビティ アニメーション。
予測型クロス タスク アニメーション。

Elegant font API のサポート終了と無効化

Android 15(API レベル 35)をターゲットとするアプリでは、elegantTextHeight TextView 属性がデフォルトで true に設定され、コンパクトなフォントが可読性の高いフォントに置き換えられます。elegantTextHeight 属性を false に設定することで、この動作をオーバーライドできます。

Android 16 では elegantTextHeight 属性が非推奨となり、アプリのターゲットが Android 16 になると、この属性は無視されます。これらの API で制御される「UI フォント」は廃止されるため、アラビア語、ラオス語、ミャンマー語、タミル語、グジャラート語、カンナダ語、マラヤーラム語、オディア語、テルグ語、タイ語でテキストが常に正しくレンダリングされるように、レイアウトを調整する必要があります。

Android 14(API レベル 34)以下をターゲットとするアプリ、または elegantTextHeight 属性を false に設定してデフォルトをオーバーライドした Android 15(API レベル 35)をターゲットとするアプリの
elegantTextHeight の動作。
Android 16(API レベル 36)をターゲットとするアプリ、または elegantTextHeight 属性を false に設定してデフォルトをオーバーライドしていない Android 15(API レベル 35)をターゲットとするアプリの
elegantTextHeight の動作。

コア機能

Android 16(API レベル 36)には、Android システムのさまざまなコア機能を変更または拡張する以下の変更が含まれています。

固定レートの作業スケジュールの最適化

Android 16 をターゲットとする前は、scheduleAtFixedRate が有効なプロセス ライフサイクルの外部にあるためにタスクの実行を逃した場合、アプリが有効なライフサイクルに戻ると、逃した実行がすべて直ちに実行されました。

Android 16 をターゲットとしている場合、アプリが有効なライフサイクルに戻ると、scheduleAtFixedRate の実行が最大 1 回スキップされた場合、その実行が直ちに実行されます。この動作変更により、アプリのパフォーマンスが向上することが期待されます。アプリでこの動作をテストして、アプリが影響を受けているかどうかを確認します。アプリ互換性フレームワークを使用して STPE_SKIP_MULTIPLE_MISSED_PERIODIC_TASKS 互換性フラグを有効にしてテストすることもできます。

デバイスのフォーム ファクタ

Android 16(API レベル 36)では、大画面デバイスに表示されるアプリに対して次の変更が加えられています。

アダプティブ レイアウト

Android アプリは、スマートフォン、タブレット、折りたたみ式デバイス、デスクトップ、自動車、テレビなど、さまざまなデバイスで動作するようになり、大画面のウィンドウ モード(分割画面やデスクトップ ウィンドウなど)も利用できるようになりました。そのため、デベロッパーは、デバイスの向きにかかわらず、あらゆる画面サイズやウィンドウ サイズに対応できる Android アプリを構築する必要があります。画面の向きやサイズ変更を制限するなどのパラダイムは、今日のマルチデバイスの世界では制限が厳しすぎます。

向き、サイズ変更の可能性、アスペクト比の制限を無視する

Android 16(API レベル 36)をターゲットとするアプリの場合、Android 16 には、システムが画面の向き、サイズ変更、アスペクト比の制限を管理する方法の変更が含まれています。最小幅が 600dp 以上のディスプレイでは、制限は適用されなくなります。アプリは、アスペクト比やユーザーの優先する向きに関係なく、表示ウィンドウ全体に表示され、ピラーボックス表示は使用されません。

この変更により、新しい標準プラットフォームの動作が導入されます。Android は、アプリがさまざまな向き、表示サイズ、アスペクト比に対応することを想定したモデルに移行しています。固定された向きやサイズ変更の制限などの制約はアプリの適応性を妨げるため、アプリをアダプティブにすることで、可能な限り最高のユーザー エクスペリエンスを提供することをおすすめします。

アプリ互換性フレームワークを使用して UNIVERSAL_RESIZABLE_BY_DEFAULT 互換性フラグを有効にすることで、この動作をテストすることもできます。

一般的な互換性を破る変更

向き、サイズ変更、アスペクト比の制限を無視すると、一部のデバイスでアプリの UI に影響する可能性があります。特に、縦向きに固定された小さなレイアウト用に設計された要素では、レイアウトの引き伸ばしや画面外のアニメーションやコンポーネントなどの問題が発生する可能性があります。アスペクト比や向きに関する想定は、アプリの視覚的な問題を引き起こす可能性があります。詳細

デバイスの回転を許可すると、アクティビティの再作成が増え、適切に保存されていない場合はユーザーの状態が失われる可能性があります。UI の状態を正しく保存する方法については、UI の状態を保存するをご覧ください。

実装の詳細

次のマニフェスト属性とランタイム API は、大画面デバイスの全画面モードとマルチウィンドウ モードでは無視されます。

screenOrientationsetRequestedOrientation()getRequestedOrientation() の次の値は無視されます。

  • portrait
  • reversePortrait
  • sensorPortrait
  • userPortrait
  • landscape
  • reverseLandscape
  • sensorLandscape
  • userLandscape

ディスプレイのサイズ変更については、android:resizeableActivity="false"android:minAspectRatioandroid:maxAspectRatio は影響しません。

Android 16(API レベル 36)をターゲットとするアプリの場合、大画面ではアプリの向き、サイズ変更、アスペクト比の制約はデフォルトで無視されますが、完全に準備が整っていないアプリは、オプトアウトすることでこの動作を一時的にオーバーライドできます(これにより、互換モードで配置されるという以前の動作になります)。

例外

Android 16 の画面の向き、サイズ変更、アスペクト比の制限は、次の場合には適用されません。

  • ゲーム(android:appCategory フラグに基づく)
  • デバイスのアスペクト比設定でアプリのデフォルトの動作を明示的に選択しているユーザー
  • sw600dp より小さい画面

一時的にオプトアウトする

特定のアクティビティをオプトアウトするには、PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY マニフェスト プロパティを宣言します。

<activity ...>
  <property android:name="android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY" android:value="true" />
  ...
</activity>

アプリの多くの部分が Android 16 に対応していない場合は、アプリケーション レベルで同じプロパティを適用することで、完全にオプトアウトできます。

<application ...>
  <property android:name="android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY" android:value="true" />
</application>

健康&フィットネス

Android 16(API レベル 36)では、健康とフィットネスに関するデータについて以下の変更が加えられています。

健康とフィットネスの権限

Android 16(API レベル 36)以上をターゲットとするアプリの場合、BODY_SENSORS 権限は android.permissions.health の下にあるより細かい権限を使用します。これは ヘルスコネクトでも使用されます。Android 16 以降、これまで BODY_SENSORS または BODY_SENSORS_BACKGROUND を必要としていた API はすべて、対応する android.permissions.health 権限が必要となります。この変更は、次のデータ型、API、フォアグラウンド サービスタイプに影響します。

アプリがこれらの API を使用している場合は、それぞれの粒度の細かい権限をリクエストする必要があります。

これらの権限は、健康、フィットネス、ウェルネスのデータ用の Android データストアである ヘルスコネクトからのデータ読み取りへのアクセスを保護する権限と同じです。

モバイルアプリ

READ_HEART_RATE やその他のきめ細かい権限を使用するように移行するモバイルアプリは、アプリのプライバシー ポリシーを表示するためにアクティビティを宣言する必要もあります。これはヘルスコネクトと同じ要件です。

接続

Android 16(API レベル 36)では、周辺機器との接続性を改善するために、Bluetooth スタックに次の変更が加えられています。

ボンドの損失と暗号化の変更を処理する新しいインテント

ボンドの損失処理の改善の一環として、Android 16 では、ボンドの損失と暗号化の変更をアプリがより認識できるように、2 つの新しいインテントを導入しています。

Android 16 をターゲットとするアプリは、次のことができます。

  • リモート ボンドの損失が検出されたときに ACTION_KEY_MISSING インテントを受け取り、より有益なユーザー フィードバックを提供するとともに、適切なアクションを実行できます。
  • リンクの暗号化ステータスが変更されるたびに ACTION_ENCRYPTION_CHANGE インテントを受け取ります。これには、暗号化ステータスの変更、暗号化アルゴリズムの変更、暗号鍵サイズの変更が含まれます。後で ACTION_ENCRYPTION_CHANGE インテントを受け取った際にリンクが正常に暗号化された場合、アプリはボンディングが復元されたと見なす必要があります。

さまざまな OEM 実装への適応

Android 16 ではこれらの新しいインテントを導入していますが、その実装とブロードキャスト方法はデバイス メーカー(OEM)によって異なる場合があります。すべてのデバイスでアプリが一貫した信頼性の高いエクスペリエンスを提供できるようにするには、デベロッパーは、このような潜在的な変化に適切に対応するように、ボンディングの損失処理を設計する必要があります。

アプリの動作は次のとおりにすることをおすすめします。

  • ACTION_KEY_MISSING インテントがブロードキャストされた場合:

    ACL(非同期接続レス)リンクはシステムによって切断されますが、デバイスのボンディング情報は保持されます(こちらを参照)。

    アプリでは、このインテントを結合喪失の検出の主要なシグナルとして使用し、デバイスの消去や再ペア設定を開始する前に、リモート デバイスが範囲内にあることを確認するようユーザーに案内する必要があります。

    ACTION_KEY_MISSING の受信後にデバイスが切断された場合、デバイスがシステムとボンディングされていない可能性があるため、アプリは再接続に注意する必要があります。

  • ACTION_KEY_MISSING インテントがブロードキャストされていない場合:

    ACL リンクは接続されたままになり、デバイスのボンディング情報は Android 15 の場合と同じようにシステムによって削除されます。

    このシナリオでは、アプリは以前の Android リリースと同様に既存のボンディング損失処理メカニズムを継続して、ボンディング損失イベントを検出して管理する必要があります。

Bluetooth のペア設定を削除する新しい方法

Android 16 をターゲットとするすべてのアプリで、CompanionDeviceManager の公開 API を使用して Bluetooth デバイスのペア設定を解除できるようになりました。コンパニオン デバイスが CDM の関連付けとして管理されている場合、アプリは、関連付けられたデバイスで新しい removeBond(int) API を使用して、Bluetooth の接続解除をトリガーできます。アプリは、Bluetooth デバイスのブロードキャスト イベント ACTION_BOND_STATE_CHANGED をリッスンすることで、ボンディング状態の変化をモニタリングできます。

セキュリティ

Android 16(API レベル 36)では、セキュリティが次のように変更されています。

MediaStore バージョンのロックダウン

Android 16 以降をターゲットとするアプリの場合、MediaStore#getVersion() はアプリごとに一意になります。これにより、バージョン文字列から識別プロパティが削除され、フィンガープリント手法の不正使用と使用が防止されます。アプリでは、このバージョンの形式について前提条件を設定しないでください。アプリは、この API を使用する際にバージョンの変更をすでに処理している必要があります。ほとんどの場合、デベロッパーがこの API の対象範囲を超える追加情報を推測しようとしない限り、現在の動作を変更する必要はありません。

Safer Intents

Safer Intents 機能は、Android のインテント解決メカニズムのセキュリティを強化するために設計された多段階のセキュリティ イニシアチブです。この目標は、インテント処理中にチェックを追加し、特定の条件を満たさないインテントをフィルタすることで、アプリを悪意のあるアクションから保護することです。

Android 15 では、この機能は送信側アプリに重点が置かれていましたが、Android 16 では受信側アプリに制御が移り、デベロッパーはアプリ マニフェストを使用して厳格なインテント解決をオプトインできるようになります。

次の 2 つの主な変更が実施されます。

  1. 明示的インテントはターゲット コンポーネントのインテント フィルタと一致する必要がある: インテントがコンポーネントを明示的にターゲットにしている場合、そのコンポーネントのインテント フィルタと一致する必要があります。

  2. アクションのないインテントはインテント フィルタに一致しない: アクションが指定されていないインテントは、インテント フィルタに解決されるべきではありません。

これらの変更は、複数のアプリが関与している場合にのみ適用され、単一のアプリ内のインテント処理には影響しません。

影響

オプトイン方式であるため、デベロッパーはアプリ マニフェストで明示的に有効にしなければなりません。そのため、この機能の影響は、デベロッパーが次の条件を満たすアプリに限定されます。

  • Safer Intents 機能とそのメリットを理解している。
  • より厳格なインテント処理方法をアプリに組み込むことを積極的に選択する。

このオプトイン アプローチにより、現在の安全性の低いインテント解決動作に依存している可能性のある既存のアプリが破損するリスクを最小限に抑えることができます。

Android 16 での初期の影響は限定的かもしれませんが、Safer Intents イニシアチブには、今後の Android リリースでより広範な影響を与えるためのロードマップがあります。最終的には、厳密なインテント解決をデフォルトの動作にする予定です。

Safer Intents 機能は、悪意のあるアプリがインテント解決メカニズムの脆弱性を悪用することを困難にすることで、Android エコシステムのセキュリティを大幅に強化する可能性があります。

ただし、既存のアプリとの互換性の問題に対処するため、オプトアウトへの移行と強制適用は慎重に管理する必要があります。

実装

デベロッパーは、アプリのマニフェストで intentMatchingFlags 属性を使用して、より厳格なインテント マッチングを明示的に有効にする必要があります。アプリ全体で機能をオプトインし、レシーバで無効化/オプトアウトする例を次に示します。

<application android:intentMatchingFlags="enforceIntentFilter">
    <receiver android:name=".MyBroadcastReceiver" android:exported="true" android:intentMatchingFlags="none">
        <intent-filter>
            <action android:name="com.example.MY_CUSTOM_ACTION" />
        </intent-filter>
        <intent-filter>
            <action android:name="com.example.MY_ANOTHER_CUSTOM_ACTION" />
        </intent-filter>
    </receiver>
</application>

サポートされているフラグの詳細:

フラグ名 説明
enforceIntentFilter 受信インテントに対してより厳密なマッチングを適用します
なし 受信インテントの特別な照合ルールをすべて無効にします。複数のフラグを指定した場合、競合する値は「なし」フラグが優先されることで解決されます。
allowNullAction 一致ルールを緩和して、アクションのないインテントを一致させます。特定の動作を実現するために「enforceIntentFilter」と組み合わせて使用されるフラグ

テストとデバッグ

適用が有効になっている場合、インテント呼び出し元がインテントを適切に設定していれば、アプリは正しく機能します。ただし、ブロックされたインテントは、タグ "PackageManager." を含む "Intent does not match component's intent filter:""Access blocked:" などの警告ログメッセージをトリガーします。これは、アプリに影響する可能性のある問題を示しており、注意が必要です。

Logcat フィルタ:

tag=:PackageManager & (message:"Intent does not match component's intent filter:" | message: "Access blocked:")

プライバシー

Android 16(API レベル 36)では、プライバシーが次のように変更されています。

ローカル ネットワークへのアクセス権

LAN 上のデバイスには、INTERNET 権限を持つアプリからアクセスできます。これにより、アプリがローカル デバイスに簡単に接続できるようになりますが、ユーザーのフィンガープリントの作成や位置情報のプロキシなど、プライバシーに関する影響もあります。

ローカル ネットワーク保護プロジェクトは、新しい実行時の権限の背後にローカル ネットワークへのアクセスを制限することで、ユーザーのプライバシーを保護することを目的としています。

リリース計画

この変更は、2 つのリリース(25Q2 と TBD)の間にデプロイされます。デベロッパーは 25Q2 でこのガイダンスに沿って、フィードバックを共有することが不可欠です。これらの保護は今後の Android リリースで適用される予定です。また、暗黙的なローカル ネットワーク アクセスに依存するシナリオを、以下のガイダンスに沿って更新し、ユーザーによる新しい権限の拒否や取り消しに備える必要があります。

影響

現段階では、LNP はオプトイン機能であるため、オプトインしたアプリのみが影響を受けます。オプトイン フェーズの目的は、アプリのどの部分が暗黙的なローカル ネットワーク アクセスに依存しているかをアプリ デベロッパーが把握し、次のリリースでそれらの部分の権限を保護する準備をすることです。

アプリが次の方法でユーザーのローカル ネットワークにアクセスする場合、アプリは影響を受けます。

  • ローカル ネットワーク アドレスでのロー ソケットの直接使用またはライブラリ使用(mDNS や SSDP サービス ディスカバリ プロトコルなど)
  • ローカル ネットワークにアクセスするフレームワーク レベルのクラス(NsdManager など)の使用

ローカル ネットワーク アドレスとの間のトラフィックには、ローカル ネットワーク アクセス権限が必要です。次の表に、一般的なケースを示します。

アプリの低レベル ネットワーク オペレーション ローカル ネットワークへのアクセス権が必要です
アウトバウンド TCP 接続を行う はい
受信 TCP 接続を受け入れる はい
UDP ユニキャスト、マルチキャスト、ブロードキャストの送信 はい
受信 UDP ユニキャスト、マルチキャスト、ブロードキャスト はい

これらの制限はネットワーク スタックの奥深くに実装されているため、すべてのネットワーク API に適用されます。これには、ネイティブ コードまたはマネージド コードで作成されたソケット、Cronet や OkHttp などのネットワーキング ライブラリ、それらの上に実装された API が含まれます。ローカル ネットワーク上のサービス(.local サフィックスが付いているものなど)を解決しようとするには、ローカル ネットワークの権限が必要です。

上記のルールの例外:

  • デバイスの DNS サーバーがローカル ネットワーク上にある場合、そのサーバーとの間のトラフィック(ポート 53)にはローカル ネットワーク アクセス権限は必要ありません。
  • アプリ内ピッカーとして出力スイッチャーを使用するアプリは、ローカル ネットワークの権限を必要としません(2025 年第 4 四半期に詳細なガイダンスが提供される予定です)。

デベロッパー ガイド(オプトイン)

ローカル ネットワークの制限を有効にする手順は次のとおりです。

  1. デバイスを 25Q2 ベータ版 3 以降のビルドに書き込みます。
  2. テストするアプリをインストールします。
  3. adb で Appcompat フラグを切り替えます。

    adb shell am compat enable RESTRICT_LOCAL_NETWORK <package_name>
    
  4. デバイスを再起動する

これで、アプリのローカル ネットワークへのアクセスが制限され、ローカル ネットワークにアクセスしようとするとソケット エラーが発生します。アプリのプロセス外でローカル ネットワーク オペレーションを実行する API(NsdManager など)を使用している場合、オプトイン フェーズでは影響を受けません。

アクセス権を復元するには、アプリに NEARBY_WIFI_DEVICES 権限を付与する必要があります。

  1. アプリがマニフェストで NEARBY_WIFI_DEVICES 権限を宣言していることを確認します。
  2. [設定] > [アプリ] > [アプリ名] > [権限] > [付近のデバイス] > [許可] に移動します。

これで、アプリのローカル ネットワークへのアクセスが復元され、アプリを有効にする前と同じようにすべてのシナリオが動作するはずです。

ローカル ネットワーク保護の適用が開始されると、アプリのネットワーク トラフィックは次のように影響を受けます。

権限 アウトバウンド LAN リクエスト アウトバウンド/インバウンドのインターネット リクエスト インバウンド LAN リクエスト
許可 Works Works Works
Not Granted(未許可) ハプニング集 Works ハプニング集

次のコマンドを使用して、App-Compat フラグをオフにします。

adb shell am compat disable RESTRICT_LOCAL_NETWORK <package_name>

エラー

これらの制限に起因するエラーは、呼び出し元ソケットがローカル ネットワーク アドレスに対して send または send バリアントを呼び出すたびに返されます。

エラーの例:

sendto failed: EPERM (Operation not permitted)

sendto failed: ECONNABORTED (Operation not permitted)

ローカル ネットワークの定義

このプロジェクトのローカル ネットワークとは、Wi-Fi やイーサネットなどのブロードキャスト対応のネットワーク インターフェースを利用する IP ネットワークを指します。ただし、携帯通信(WWAN)や VPN 接続は除きます。

次のネットワークはローカル ネットワークとみなされます。

IPv4:

  • 169.254.0.0/16 // リンクローカル
  • 100.64.0.0/10 // CGNAT
  • 10.0.0.0/8 // RFC1918
  • 172.16.0.0/12 // RFC1918
  • 192.168.0.0/16 // RFC1918

IPv6:

  • リンクローカル
  • 直接接続されたルート
  • Thread などのスタブ ネットワーク
  • 複数サブネット(未定)

また、マルチキャスト アドレス(224.0.0.0/4、ff00::/8)と IPv4 ブロードキャスト アドレス(255.255.255.255)の両方がローカル ネットワーク アドレスとして分類されます。

アプリ所有の写真

Android 16 以降を搭載したデバイスで、SDK 36 以降をターゲットとするアプリから写真と動画の権限を求めるメッセージが表示された場合、選択したメディアへのアクセスを制限することを選択したユーザーには、アプリが所有する写真が写真選択ツールで事前選択された状態で表示されます。ユーザーは、これらの事前選択された項目の選択を解除できます。これにより、それらの写真と動画へのアプリのアクセス権が取り消されます。