動作の変更点: 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 デバイスで実行されている場合、 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 を使用するようにアプリを更新するか、または アプリの <application> タグまたは <activity> タグで android:enableOnBackInvokedCallback 属性を false に設定して、一時的にオプトアウトします。AndroidManifest.xml ファイル。

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

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)をターゲットとするアプリでは、最小幅が 600 dp 以上のディスプレイで、画面の向き、サイズ変更、アスペクト比の制限が適用されなくなります。アスペクト比やユーザーが指定した画面の向きにかかわらず、アプリはディスプレイ ウィンドウ全体に表示され、ピラーボックス表示は使用されません。

この変更により、新しい標準プラットフォームの動作が導入されます。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」と組み合わせて使用して、特定の動作を実現します。

テストとデバッグ

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

logcat フィルタ:

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

GPU システムコール フィルタリング

Mali GPU サーフェスを強化するため、非推奨となった Mali GPU IOCTL や GPU 開発専用の Mali GPU IOCTL は、本番環境ビルドでブロックされています。また、GPU プロファイリングに使用される IOCTL がシェル プロセスまたはデバッグ可能なアプリに制限されました。プラットフォーム レベルのポリシーについて詳しくは、SAC の更新を参照してください。

この変更は、Mali GPU を搭載した Google Pixel デバイス(Google Pixel 6 ~ 9)で実施されます。Arm は、r54p2 リリースDocumentation/ioctl-categories.rst で IOCTL の公式な分類を提供しています。このリストは、今後のドライバ リリースでも引き続き維持されます。

この変更は、サポートされているグラフィック API(Vulkan や OpenGL など)には影響しません。また、デベロッパーや既存のアプリケーションにも影響しないと見込まれます。Streamline Performance Analyzer や Android GPU Inspector などの GPU プロファイリング ツールは影響を受けません。

テスト

次のような SELinux の拒否が表示された場合は、アプリがこの変更の影響を受けている可能性があります。

06-30 10:47:18.617 20360 20360 W roidJUnitRunner: type=1400 audit(0.0:85): avc:  denied  { ioctl }
for  path="/dev/mali0" dev="tmpfs" ino=1188 ioctlcmd=0x8023
scontext=u:r:untrusted_app_25:s0:c512,c768 tcontext=u:object_r:gpu_device:s0 tclass=chr_file
permissive=0 app=com.google.android.selinux.pts

アプリケーションでブロックされた IOCTL を使用する必要がある場合は、バグを報告して android-partner-security@google.com に割り当ててください。

よくある質問

  1. このポリシーの変更はすべての OEM に適用されますか? この変更はオプトインですが、この強化方法を使用したい OEM は誰でも利用できます。変更を実装する手順については、実装に関するドキュメントをご覧ください。

  2. これを実装するには OEM コードベースを変更する必要がありますか?それとも、新しい AOSP リリースにデフォルトで含まれていますか?プラットフォーム レベルの変更は、デフォルトで新しい AOSP リリースに含まれます。ベンダーは、この変更を適用したい場合は、コードベースでこの変更を有効にできます。

  3. SoC は IOCTL リストを最新の状態に保つ責任がありますか?たとえば、デバイスが ARM Mali GPU を使用している場合、変更について ARM に問い合わせる必要はありますか?個々の SoC は、ドライバのリリース時にデバイスごとに IOCTL リストを更新する必要があります。たとえば、ARM はドライバの更新時に公開済みの IOCTL リストを更新します。ただし、OEM は、SEPolicy に更新を組み込み、必要に応じて選択したカスタム IOCTL をリストに追加する必要があります。

  4. この変更は、販売中のすべての Google Pixel に自動的に適用されますか?それとも、この変更を適用するためにユーザーが何かを切り替える必要がありますか?この変更は、Mali GPU(Google Pixel 6 ~ 9)を使用するすべての Google Pixel 販売中デバイスに適用されます。この変更を適用するためにユーザー側で必要な操作はありません。

  5. このポリシーを使用すると、カーネル ドライバのパフォーマンスに影響しますか?このポリシーは GFXBench を使用して Mali GPU でテストされましたが、GPU パフォーマンスに測定可能な変化は見られませんでした。

  6. IOCTL リストを現在のユーザースペースとカーネル ドライバのバージョンに合わせる必要がありますか?はい。許可される IOCTL のリストは、ユーザー空間とカーネル ドライバの両方でサポートされる IOCTL と同期する必要があります。ユーザー空間またはカーネル ドライバの IOCTL が更新された場合は、SEPolicy IOCTL リストも一致するように更新する必要があります。

  7. ARM は IOCTL を「制限付き」 / 「計測」に分類していますが、一部を本番環境のユースケースで使用したり、一部を拒否したりしたいと考えています。個々の OEM/SoC は、ユーザー空間 Mali ライブラリの構成に基づいて、使用する IOCTL を分類する方法を決定する責任があります。ARM のリストは、これらの決定に役立ちますが、OEM/SoC のユースケースはそれぞれ異なる場合があります。

プライバシー

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

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

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

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

リリース計画

この変更は、25Q2 と 26Q2 の 2 つのリリースに分けてデプロイされます。 デベロッパーは、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 リクエスト
許可 機能する 機能する 機能する
未許可 失敗する 機能する 失敗する

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

adb shell am compat disable RESTRICT_LOCAL_NETWORK <package_name>

エラー

これらの制限によって発生したエラーは、呼び出し元のソケットがローカル ネットワーク アドレスに送信または送信バリアントを呼び出すたびに返されます。

エラーの例:

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