Android 12 デベロッパー プレビューへようこそ。早い段階から頻繁にフィードバックをお送りいただき、Android 12 をさらに優れたリリースにするためにご協力ください。

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

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

Android 12 をターゲットとするアプリに影響する主な変更について、次の表にまとめます。この表は、すべての変更を網羅するものではないことにご注意ください。

主な変更 影響を受けるアプリ
フォアグラウンド サービスの起動に関する制限
少数の例外ケースを除いて、アプリがバックグラウンドで動作しているときはフォアグラウンド サービスを起動できなくなりました。起動しようとすると、例外がスローされます。
バックグラウンドで動作しているときにフォアグラウンド サービスを起動するアプリ。
インテント フィルタを含むアプリ コンポーネントで exported 属性の宣言が必須に
インテント フィルタを含むアプリ コンポーネントは、android:exported 属性を明示的に設定する必要があります。この属性を設定していないアプリは、Android 12 にインストールできません。
マニフェスト ファイルで <intent-filter> 属性を宣言しているアプリ。
ネストされたインテントの安全でない起動
ネストされたインテントをアプリが安全でない方法で使用している場合、厳格モードのテストで検出されるようになりました。
内部インテントを介したコールバックを想定している、別のアプリを起動するアプリ。

Android 12 で動作するすべてのアプリに影響する動作変更のリストも必ずご確認ください。

プライバシー

WebView における最新の SameSite Cookie の動作

Android の WebView コンポーネントは、Google の Chrome ブラウザを支えるオープンソース プロジェクトである Chromium をベースにしています。昨年 Chromium は、セキュリティとプライバシーを強化してより高い透明性と管理性をユーザーに提供するため、サードパーティ Cookie の処理に関する変更を導入しました。この変更はすでに多くの Chrome ユーザーにロールアウトされており、Android 12 以降は WebView に適用されます。

Cookie の SameSite 属性は、Cookie を任意のリクエストで送信できるか、同一サイト リクエストのみで送信できるかを制御します。サードパーティ Cookie のデフォルト処理を改善し、意図しないクロスサイト共有を防止するため、Android 12 における WebView のベース バージョン(89.0.4385.0)には、次に示すプライバシー保護の変更が取り入れられています。

  • SameSite 属性が設定されていない Cookie は SameSite=Lax として扱われます。
  • SameSite=None の Cookie には、Secure 属性も指定する必要があります。つまり、そうした Cookie はセキュア コンテキストを必要とし、HTTPS で送信する必要があります。
  • サイトの HTTP バージョンと HTTPS バージョン間のリンクは、クロスサイト リクエストとして扱われるようになりました。したがって、SameSite=None; Secure として適切にマークされていない限り、Cookie は送信されません。

デベロッパー向けのガイダンスとして、重要なユーザーフローでクロスサイト Cookie の依存関係を明らかにし、必要に応じて SameSite 属性に適切な値が明示的に設定されていることを確認するようおすすめします。ウェブサイト間で、または HTTP から HTTPS に移動する同一サイト ナビゲーションで動作することを許可する Cookie を明示的に指定する必要があります。

これらの変更に関するウェブ デベロッパー向けの詳細なガイダンスについては、SameSite Cookie の説明およびスキームフル SameSite の記事をご覧ください。

アプリで SameSite 動作をテストする

アプリで WebView を使用している場合や、Cookie を使用するウェブサイトまたはサービスを管理している場合は、Android 12 の WebView でフローをテストすることをおすすめします。問題が見つかった場合は、新しい SameSite 動作に対応するために Cookie の更新が必要になる可能性があります。

ログインと埋め込みコンテンツで問題が発生しないか、また、ユーザーが安全でないページから出発して安全なページに移動するログインフロー、購入フロー、およびその他の認証フローで問題が発生しないかを確認してください。

WebView を使用するアプリをテストするには、次のいずれかの手順を実施して、テスト対象のアプリで新しい SameSite 動作を有効にする必要があります。

  • WebView DevToolsUI フラグ webview-enable-modern-cookie-same-site を切り替えることにより、テストデバイス上の SameSite 動作を手動で有効にします。

    このアプローチでは、Android 5.0(API レベル 21)以上(Android 12 を含む)と WebView バージョン 89.0.4385.0 以上を実行しているデバイスで、テストを実施できます。

  • targetSdkVersion により、Android 12 をターゲットとしてアプリをコンパイルします。

    このアプローチでは、Android 12 と WebView バージョン 89.0.4385.0 以上を実行しているデバイスを使用する必要があります。

Android での WebView のリモート デバッグについては、Android デバイスでリモート デバッグを開始するをご覧ください。

その他のリソース

最新の SameSite 動作と Chrome および WebView へのロールアウトについて詳しくは、Chromium の SameSite アップデートのページをご覧ください。WebView または Chromium でバグが見つかった場合は、一般公開されている Chromium Issue Tracker での報告をお願いします。

ADB バックアップの制限

限定公開アプリのデータを保護するため、Android 12 では adb backup コマンドのデフォルト動作が変更されました。Android 12 をターゲットとするアプリでは、ユーザーが adb backup コマンドを実行したとき、デバイスからエクスポートされる他のシステムデータからアプリデータが除外されます。

テストまたは開発ワークフローが adb backup を使用して取得するアプリデータに依存している場合は、アプリのマニフェスト ファイルで android:debuggabletrue に設定することにより、アプリデータのエクスポートを有効にすることができるようになりました。

セキュリティ

コンポーネントのより安全なエクスポート

「フィードバック送信」アイコン コンポーネントのエクスポートに関する新しい要件について、フィードバックをお寄せください。簡単なアンケートにご協力いただき、ご意見をお聞かせください。特に、この変更がアプリに影響するユースケースをお知らせください。

Android 12 をターゲットとするアプリに、インテント フィルタを使用するアクティビティサービス、またはブロードキャスト レシーバが含まれている場合は、それらのアプリ コンポーネントで android:exported 属性を明示的に宣言する必要があります。

警告: インテント フィルタを使用するアクティビティ、サービス、またはブロードキャスト レシーバが android:exported の値を明示的に宣言していない場合、Android 12 を実行しているデバイスにアプリをインストールできません。

Android Studio を使用してそのようなアプリをインストールしようとすると、logcat に次のエラー メッセージが表示されます。

Installation did not succeed.
The application could not be installed: INSTALL_FAILED_VERIFICATION_FAILURE
List of apks:
[0] '.../build/outputs/apk/debug/app-debug.apk'
Installation failed due to: 'null'

アプリが android:exported の値を宣言する必要がある場合に宣言していないと、logcat に次のエラー メッセージが表示されます。

Targeting S+ (version 10000 and above) requires that an explicit value for \
android:exported be defined when intent filters are present

次のコード スニペットは、インテント フィルタを含むサービスが Android 12 用に正しく構成されている例を示しています。

<service android:name="com.example.app.backgroundService"
         android:exported="false">
    <intent-filter>
        <action android:name="com.example.app.START_BACKGROUND" />
    </intent-filter>
</service>

ペンディング インテントで可変性の宣言が必須に

「フィードバック送信」アイコン ペンディング インテントに関するこの新しい要件について、フィードバックをお寄せください。簡単なアンケートにご協力いただき、ご意見をお聞かせください。特に、この変更がアプリに影響するユースケースをお知らせください。

Android 12 をターゲットとするアプリでは、アプリが作成する個々の PendingIntent オブジェクトの可変性を指定する必要があります。この追加要件により、アプリのセキュリティが強化されます。

特定の PendingIntent オブジェクトが可変または不変であることを宣言するには、PendingIntent.FLAG_MUTABLE フラグまたは PendingIntent.FLAG_IMMUTABLE フラグをそれぞれ使用します。アプリがどちらの可変性フラグも設定せずに PendingIntent オブジェクトを作成しようとすると、IllegalArgumentException がスローされ、logcat に次のメッセージが表示されます。

PACKAGE_NAME: Targeting S+ (version 10000 and above) requires that one of \
FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.

Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if \
some functionality depends on the PendingIntent being mutable, e.g. if \
it needs to be used with inline replies or bubbles.

可能な限り不変のペンディング インテントを作成する

ほとんどの場合において、アプリでは不変の PendingIntent オブジェクトを作成するようにしてください(次のコード スニペットを参照)。PendingIntent オブジェクトが不変の場合、アプリはそのインテントを変更して、インテント呼び出しの結果を調整することはできません。

Kotlin

val pendingIntent = PendingIntent.getActivity(applicationContext,
        REQUEST_CODE, intent,
        /* flags */ PendingIntent.FLAG_IMMUTABLE)

Java

PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),
        REQUEST_CODE, intent,
        /* flags */ PendingIntent.FLAG_IMMUTABLE);

ただし、次の場合には可変の PendingIntent オブジェクトを作成する必要があります。

  • 通知内のダイレクト返信アクションが、返信に関連付けられた PendingIntent オブジェクト内のクリップデータの変更を必要とする場合。通常は、fillIn() メソッドに FILL_IN_CLIP_DATA をフラグとして渡すことにより、この変更をリクエストします。
  • アプリが PendingIntent を使用して会話をバブルに配置する場合は、システムが FLAG_ACTIVITY_MULTIPLE_TASKFLAG_ACTIVITY_NEW_DOCUMENT などの正しいフラグを適用できるように、インテントを可変にする必要があります。

アプリで可変の PendingIntent オブジェクトを作成する場合は、明示的インテントを使用して ComponentName の値をフィルインすることを強くおすすめします。そうすれば、別のアプリが PendingIntent を呼び出してアプリに制御を戻すたびに、常にアプリ内の同じコンポーネントが開始されます。

ペンディング インテントの可変性の変更をテストする

アプリに可変性の宣言が欠けているかどうかを確認するには、Android Studio で次の lint 警告を検索します。

Warning: Missing PendingIntent mutability flag [UnspecifiedImmutableFlag]

デベロッパー プレビューを使用している場合に、テスト目的でこのシステム動作を無効にするには、PENDING_INTENT_EXPLICIT_MUTABILITY_REQUIRED アプリ互換性フラグをオフにします。

ネストされたインテントの安全でない起動

Android 12 では、プラットフォームのセキュリティを強化するため、ネストされたインテントの安全でない起動をアプリが実行したときに警告するデバッグ機能が導入されました。「ネストされたインテント」とは、別のインテント内でエクストラとして渡されるインテントです。アプリが次のアクションの両方を実行すると、StrictMode 違反が発生します。

  1. 配信されたインテントのエクストラから、ネストされたインテントを取り出した。
  2. そのネストされたインテントを使用して(たとえば startActivity()startService()、または bindService() にインテントを渡して)、アプリ コンポーネントを直ちに開始した。

ネストされたインテントの安全でない起動が検出されるようにアプリを構成する

アプリ内のネストされたインテントの安全でない起動をチェックするには、次のコード スニペットに示すように、VmPolicy を構成する際に detectUnsafeIntentLaunch() を呼び出します。アプリで StrictMode 違反が検出された場合は、機密に該当する可能性がある情報を保護するために、アプリの実行を停止することをおすすめします。

Kotlin

fun onCreate() {
    StrictMode.setVmPolicy(VmPolicy.Builder()
        // Other StrictMode checks that you've previously added.
        // ...
        .detectUnsafeIntentLaunch()
        .penaltyLog()
        // Consider also adding penaltyDeath()
        .build())
}

Java

protected void onCreate() {
    StrictMode.setVmPolicy(new VmPolicy.Builder()
        // Other StrictMode checks that you've previously added.
        // ...
        .detectUnsafeIntentLaunch()
        .penaltyLog()
        // Consider also adding penaltyDeath()
        .build());
}

より厳格なインテントの使い方

アプリは、アプリ内のコンポーネント間を移動するため、または別のアプリに代わってアクションを実行するため、ネストされたインテントを起動することがあります。いずれの場合も StrictMode 違反が発生する可能性を最小限に抑えるために、以下を実施してください。

  • ネストされたインテントの内部起動: 該当コンポーネントがエクスポートされないようにします。
  • ネストされたインテントのクロスアプリ起動: ネストされたインテントの代わりに PendingIntent を使用します。この方法では、Intent からその内部の PendingIntent が取り出されたとき、アプリ コンポーネントが呼び出しプロセスの識別子を使用して PendingIntent を起動できます。このように構成すると、プロバイダ アプリは、任意のコンポーネント(呼び出し元アプリのエクスポートされないコンポーネントを含む)にコールバックを送信できます。

    この状況を識別してアプリに変更を加える方法について詳しくは、Medium の Android のネスト インテント に関するブログ記事をご覧ください。

パフォーマンス

フォアグラウンド サービスの起動に関する制限

Android 12 をターゲットとするアプリは、バックグラウンドで動作しているとき、少数の特殊なケースを除いて、フォアグラウンド サービスを起動できなくなりました。アプリがバックグラウンドで動作しているときにフォアグラウンド サービスを起動しようとすると、(少数の特殊なケースを除いて)例外が発生します。アプリがバックグラウンドで動作しているときに作業のスケジュールを設定して開始するには、WorkManager の使用を検討してください。

アプリが受ける影響と、この変更に基づいてアプリを更新する方法について詳しくは、フォアグラウンド サービスの起動に関する制限のガイドをご覧ください。また、GitHub の WorkManagerSample を確認することもできます。

サービスまたはブロードキャスト レシーバからの通知トランポリン作成が不可に

「フィードバック送信」アイコン 通知トランポリンの動作の変更について、フィードバックをお寄せください。簡単なアンケートにご協力いただき、ご意見をお聞かせください。特に、この変更がアプリに影響するユースケースをお知らせください。

ユーザーが通知を操作したとき、一部のアプリは通知のタップに反応してアプリ コンポーネントを起動し、このアプリ コンポーネントにより、ユーザーが最終的に確認して操作するアクティビティが開始されます。このようなアプリ コンポーネントを「通知トランポリン」と呼びます。

アプリのパフォーマンスと UX を改善するため、Android 12 をターゲットとするアプリは、通知トランポリンとして使用されるサービスまたはブロードキャスト レシーバからアクティビティを開始できなくなりました。つまり、ユーザーが通知または通知内のアクション ボタンをタップした後、アプリはサービスまたはブロードキャスト レシーバ内で startActivity() を呼び出すことができません。

通知トランポリンとして機能するサービスまたはブロードキャスト レシーバからアプリがアクティビティを開始しようとすると、システムによってアクティビティの開始が阻止され、logcat に以下のメッセージが表示されます。

Indirect notification activity start (trampoline) from PACKAGE_NAME, \
this should be avoided for performance reasons.

アプリの更新

通知トランポリンとして機能するサービスまたはブロードキャスト レシーバからアクティビティを開始するアプリがある場合は、次の移行手順を実施します。

  1. 次のいずれかのアクティビティに関連付けられた PendingIntent オブジェクトを作成します。

    • ユーザーが通知をタップした後で表示されるアクティビティ(推奨)。
    • トランポリン アクティビティ(つまり、ユーザーが通知をタップした後で表示されるアクティビティを開始するアクティビティ)。
  2. 通知を作成する際に、前の手順で作成した PendingIntent オブジェクトを使用します。

動作の切り替え

デベロッパー プレビューでアプリをテストする場合は、NOTIFICATION_TRAMPOLINE_BLOCK アプリ互換性フラグを使用して、この制限を有効または無効にできます。

非 SDK インターフェースの制限

Android 12 では、Android デベロッパーの協力と直近の内部テストに基づいて、制限を受ける非 SDK インターフェースのリストが更新されています。Google は、非 SDK インターフェースを制限する前に、可能な限り、その代わりとなる公開インターフェースを利用可能にしています。

Android 12 をターゲットとしないアプリでは、この変更の一部はすぐには影響しない可能性があります。ただし、現時点で(アプリのターゲット API レベルに応じて)一部の非 SDK インターフェースを利用できていても、非 SDK のメソッドまたはフィールドをそのまま使用し続けると、将来的にアプリが機能しなくなるリスクが高くなります。

アプリが非 SDK インターフェースを使用しているかどうか不明な場合は、アプリをテストして確認できます。アプリが非 SDK インターフェースに依存している場合は、SDK の代替インターフェースへの移行を計画してください。ただし Google も、一部のアプリには非 SDK インターフェースを使用する正当なユースケースがあると承知しています。アプリの機能で使用している非 SDK インターフェースの代替インターフェースが見つからない場合は、新しい公開 API をリクエストしてください。

Android の今回のリリースの変更について詳しくは、非 SDK インターフェースの制限に関する Android 12 での変更点をご覧ください。非 SDK インターフェース全般について詳しくは、非 SDK インターフェースの制限をご覧ください。

カスタム通知の変更

Android 12 では、フルカスタム通知の外観が変更されました。以前のカスタム通知では、通知領域全体を使用して、独自のレイアウトとスタイルを指定することが可能でした。その結果、アンチパターンが発生して、ユーザーが混乱したり異なるデバイス間でレイアウト互換性の問題が生じたりすることがありました。

Android 12 をターゲットとするアプリでは、カスタム コンテンツ ビューを使用する通知は通知領域全体を使用せず、代わりにシステムが標準テンプレートを適用するようになります。このテンプレートにより、カスタム通知がすべての状態において他の通知と同じ装飾を持つことが保証されます。たとえば、通知のアイコンと展開のアフォーダンス(折りたたまれた状態の場合)や、通知のアイコン、アプリ名、および折りたたみのアフォーダンス(展開された状態の場合)などです。この動作は、Notification.DecoratedCustomViewStyle の動作とほぼ同じです。

これにより、Android 12 では、すべての通知の視覚的な一貫性が確保されます。また、ユーザーにとって見つけやすく親しみやすい外観で通知が展開されるため、スキャンが容易になります。

次の図は、標準テンプレートによるカスタム通知を示しています。

次の例は、折りたたまれた状態と展開された状態でカスタム通知がどのようにレンダリングされるかを示しています。

Android 12 における変更は、Notification.Style のカスタム サブクラスを定義しているアプリや、Notification.Builder のメソッド setCustomContentView(RemoteViews)setCustomBigContentView(RemoteViews)setCustomHeadsUpContentView(RemoteViews) を使用しているアプリに影響します。

フルカスタム通知を使用しているアプリがある場合は、できるだけ早く新しいテンプレートでテストして、必要な調整を行うことをおすすめします。

  1. カスタム通知の変更を有効にするには:

    1. アプリの targetSdkVersionS に変更して、新しい動作を有効にします。
    2. 再コンパイルします。
    3. Android 12 を実行しているデバイスまたはエミュレータにアプリをインストールします。
  2. カスタムビューを使用する通知をすべてテストし、シェード内で想定どおりに表示されることを確認します。

  3. カスタムビューのサイズに注意してください。一般的に、カスタム通知に提供される高さは以前より低くなります。折りたたまれた状態では、カスタム コンテンツの最大の高さは 106 dp から 48 dp に減少します。また、水平方向のスペースが縮小されます。

  4. 「ヘッドアップ」の状態が想定どおりに表示されるようにするには、通知チャネルの重要度を必ず「高」(画面上のポップアップ表示)に上げてください。

接続

Android 12 以上をターゲットとするデバイスがハードウェア サポート対象のデバイス上で実行されている場合、ピアツーピア接続を使用しても、ピアデバイスへの接続を作成する際に既存の Wi-Fi 接続は切断されません。この機能のサポートを確認するには、WifiManager.isMultiStaConcurrencySupported() を使用します。