これまでのリリースと同様、Android 17 には、アプリに影響する可能性がある動作変更が含まれています。下記の動作変更は、Android 17 以上をターゲットとするアプリにのみ適用されます。アプリが Android 17 以上をターゲットとする場合は、必要に応じてアプリを変更し、下記の動作に対応できるようにしてください。
アプリの targetSdkVersion に関係なく、Android 17 で実行されるすべてのアプリに影響する動作変更のリストも必ずご確認ください。
ユーザー エクスペリエンスとシステム UI
Android 17 には、より一貫性のある直感的なユーザー エクスペリエンスを実現するための、以下の変更が含まれています。
メモリ上限ウィジェット
Android 17 以降、Android 17(API レベル 37)以降をターゲットとするアプリの場合、RemoteViews パーセルに存在するビットマップとアイコンの合計メモリ使用量に対して、厳格なメモリ上限(1.5 * 画面幅 * 画面高さ * 4)が適用されます。これらの上限を超えると、致命的な IllegalArgumentException がスローされ、アプリのプロセスがクラッシュします。
詳細については、UpdateAppWidget をご覧ください。
コア機能
Android 17 には、Android システムのさまざまなコア機能を変更または拡張する、以下の変更が含まれています。
MessageQueue の新しいロックフリー実装
Android 17 以降、Android 17(API レベル 37)以降をターゲットとするアプリは、android.os.MessageQueue の新しいロックフリー実装を受け取ります。新しい実装では、パフォーマンスが向上し、フレームの欠落が減少しますが、MessageQueue のプライベート フィールドとメソッドを反映するクライアントが破損する可能性があります。
緩和戦略などの詳細については、MessageQueue の動作変更に関するガイダンスをご覧ください。
静的 final フィールドが変更不可に
Android 17(API レベル 37)以降をターゲットとする Android 17 以降で動作するアプリは、static final フィールドを変更できません。アプリがリフレクションを使用して static final フィールドを変更しようとすると、IllegalAccessException が発生します。JNI API(SetStaticLongField() など)を介してこれらのフィールドのいずれかを変更しようとすると、アプリがクラッシュします。
ユーザー補助
Android 17 では、ユーザー補助機能を改善するために次の変更が加えられています。
複雑な IME 物理キーボード入力のユーザー補助サポート
この機能では、新しい AccessibilityEvent API と TextAttribute API が導入され、CJKV 言語入力のスクリーン リーダーの音声フィードバックが強化されています。CJKV IME アプリは、テキスト作成中にテキスト変換候補が選択されたかどうかを通知できるようになりました。編集フィールドを持つアプリは、テキスト変更のユーザー補助イベントを送信するときに、テキスト変更タイプを指定できます。たとえば、アプリは、テキストの作成中にテキストの変更が発生したことや、commit の結果としてテキストの変更が発生したことを指定できます。これにより、スクリーン リーダーなどのユーザー補助サービスは、テキスト変更の性質に基づいて、より正確なフィードバックを提供できます。
導入アプリ数
IME アプリ: 編集フィールドで作成中のテキストを設定する際、IME は
TextAttribute.Builder.setTextSuggestionSelected()を使用して、特定の変換候補が選択されたかどうかを示すことができます。編集フィールドを含むアプリ: カスタム
InputConnectionを保持するアプリは、TextAttribute.isTextSuggestionSelected()を呼び出すことで候補選択データを取得できます。これらのアプリは、TYPE_VIEW_TEXT_CHANGEDイベントをディスパッチするときにAccessibilityEvent.setTextChangeTypes()を呼び出す必要があります。標準のTextViewを使用する Android 17(API レベル 37)をターゲットとするアプリでは、この機能がデフォルトで有効になります。(つまり、TextViewは、ユーザー補助サービスにイベントを送信するときに、IME からのデータの取得とテキスト変更タイプの設定を処理します)。ユーザー補助サービス:
TYPE_VIEW_TEXT_CHANGEDイベントを処理するユーザー補助サービスは、AccessibilityEvent.getTextChangeTypes()を呼び出して変更の性質を特定し、それに応じてフィードバック戦略を調整できます。
プライバシー
Android 17 では、ユーザーのプライバシーを強化するために、次の変更が加えられています。
ECH(Encrypted Client Hello)が有効
Android 17 では、Encrypted Client Hello(ECH)のプラットフォーム サポートが導入されています。ECH は、TLS handshake で Server Name Indication(SNI)を暗号化することで、ユーザーのプライバシーを強化する TLS 拡張機能です。この暗号化により、ネットワーク監視者がアプリの接続先である特定のドメインを簡単に特定できなくなります。
Android 17(API レベル 37)以降をターゲットとするアプリの場合、TLS 接続に ECH が使用されます。ECH は、アプリで使用されるネットワーキング ライブラリ(HttpEngine、WebView、OkHttp など)に ECH サポートが統合されており、リモート サーバーも ECH プロトコルをサポートしている場合にのみ有効になります。ECH をネゴシエートできない場合、クライアントはランダム化されたコンテンツを含む ECH 拡張機能を送信します(ECH GREASE と呼ばれるメカニズム)。ECH GREASE の仕組みについて詳しくは、RFC 9849 をご覧ください。
アプリでこの動作をカスタマイズできるように、Android 17 ではネットワーク セキュリティ構成ファイルに新しい <domainEncryption> 要素が追加されています。デベロッパーは、<base-config> タグまたは <domain-config> タグ内で <domainEncryption> を使用して、グローバルまたはドメインごとに ECH モード("enabled" や "disabled" など)を選択できます。
詳細については、Encrypted Client Hello のドキュメントをご覧ください。
Android 17 をターゲットとするアプリに必要なローカル ネットワーク権限
Android 17 では、不正なローカル ネットワーク アクセスからユーザーを保護するために、ACCESS_LOCAL_NETWORK 実行時の権限が導入されています。これは既存の NEARBY_DEVICES 権限グループに該当するため、他の NEARBY_DEVICES 権限をすでに付与しているユーザーには、再度プロンプトが表示されることはありません。この新しい要件により、悪意のあるアプリが制限のないローカル ネットワーク アクセスを悪用して、ユーザーの追跡やフィンガープリントを密かに行うことを防ぎます。この権限を宣言してリクエストすることで、アプリはスマートホーム デバイスやキャスト レシーバーなどのローカル エリア ネットワーク(LAN)上のデバイスを検出して接続できるようになります。
Android 17(API レベル 37)以降をターゲットとするアプリには、LAN デバイスとの通信を維持するための 2 つのパスがあります。システムを介したプライバシー保護デバイス選択ツールを採用して権限プロンプトをスキップするか、実行時にこの新しい権限を明示的にリクエストしてローカル ネットワーク通信を維持します。
詳細については、ローカル ネットワークの権限に関するドキュメントをご覧ください。
実機でパスワードを非表示にする
アプリが Android 17(API レベル 37)以降をターゲットとしており、ユーザーが物理入力デバイス(外部キーボードなど)を使用している場合、Android オペレーティング システムは、パスワード フィールドのすべての文字に新しい show_passwords_physical 設定を適用します。デフォルトでは、この設定によりパスワードのすべての文字が非表示になります。
Android システムは、ユーザーがパスワードを誤入力したかどうかを確認できるように、最後に入力されたパスワード文字を表示します。ただし、大型の外付けキーボードでは、この必要性ははるかに低くなります。また、外付けキーボードを備えたデバイスはディスプレイが大きいことが多く、入力したパスワードが誰かに見られる危険性が高くなります。
ユーザーがデバイスのタッチスクリーンを使用している場合、システムは新しい show_passwords_touch 設定を適用します。
標準の SMS メッセージの OTP 保護
Android 17 以降、Android は SMS OTP 保護を拡張し、標準の SMS メッセージ(WebOTP 形式または SMS Retriever 形式を使用しない OTP を含む SMS メッセージ)に適用します。Android 17(API レベル 37)以降をターゲットとするほとんどのアプリでは、これらの SMS メッセージは受信から 3 時間経過するまで利用できません。この遅延は、OTP のハイジャックを防ぐことを目的としています。この 3 時間の遅延の間、SMS_RECEIVED_ACTION ブロードキャストは保留され、SMS プロバイダのデータベース クエリはフィルタされます。SMS メッセージは、遅延後にこれらのアプリで利用できるようになります。
デフォルトの SMS アシスタント アプリ、接続済みデバイスのコンパニオン アプリなど、特定のアプリはこの遅延の対象外となります。OTP 抽出のために SMS メッセージの読み取りに依存しているすべてのアプリは、SMS Retriever API または SMS User Consent API を使用するように移行して、機能が継続されるようにする必要があります。
セキュリティ
Android 17 では、デバイスとアプリのセキュリティが次のように改善されています。
アクティビティのセキュリティ
Android 17 では、プラットフォームが「デフォルトで保護」アーキテクチャに移行し、フィッシング、インタラクション ハイジャック、混乱した代理攻撃などの重大度の高いエクスプロイトを軽減するように設計された一連の機能強化が導入されています。このアップデートでは、アプリの互換性とユーザー保護を維持するために、デベロッパーが新しいセキュリティ標準を明示的に有効にする必要があります。
デベロッパーへの主な影響は次のとおりです。
- BAL の強化とオプトインの改善: バックグラウンド アクティビティの起動(BAL)の制限を改良し、
IntentSenderに保護を拡張しています。デベロッパーは、以前のMODE_BACKGROUND_ACTIVITY_START_ALLOWED定数から移行する必要があります。代わりに、MODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLEなどのきめ細かい制御を採用する必要があります。これにより、アクティビティの開始を呼び出し元アプリが表示されているシナリオに制限し、攻撃対象領域を大幅に縮小できます。 - 導入ツール: デベロッパーは、厳格モードと更新された lint チェックを利用して、以前のパターンを特定し、将来のターゲット SDK 要件に備える必要があります。
CT をデフォルトで有効にする
Android 17(API レベル 37)以降をターゲットとするアプリの場合、Certificate Transparency(CT)がデフォルトで有効になります。(Android 16 では、CT は利用可能ですが、アプリはオプトインする必要がありました)。
より安全なネイティブ DCL - C
アプリが Android 17(API レベル 37)以降をターゲットとしている場合、Android 14 で DEX ファイルと JAR ファイルに導入された、より安全な動的コード読み込み(DCL)保護がネイティブ ライブラリにも適用されるようになりました。
System.load() を使用して読み込まれるすべてのネイティブ ファイルは、読み取り専用としてマークする必要があります。そうしないと、システムは UnsatisfiedLinkError をスローします。
アプリでは可能な限り、コードを動的に読み込まないようにすることをおすすめします。コードを動的に読み込むと、コード インジェクションやコードの改ざんによってアプリが不正使用されるリスクが大幅に高まります。
CP2 データビューで PII フィールドを制限する
Android 17(API レベル 37)以降をターゲットとするアプリの場合、連絡先プロバイダ 2(CP2)は、個人を特定できる情報(PII)を含む特定の列をデータビューから制限します。この変更が有効になると、ユーザーのプライバシーを強化するために、これらの列がデータビューから削除されます。制限付きの列は次のとおりです。
ContactsContract.Data のこれらの列を使用しているアプリは、RAW_CONTACT_ID と結合することで、代わりに ContactsContract.RawContacts から抽出できます。
CP2 で厳格な SQL チェックを適用する
Android 17(API レベル 37)以降をターゲットとするアプリの場合、READ_CONTACTS 権限なしで ContactsContract.Data テーブルにアクセスすると、Contacts Provider 2(CP2)によって厳格な SQL クエリ検証が適用されます。
この変更により、アプリに READ_CONTACTS 権限がない場合、ContactsContract.Data テーブルをクエリするときに StrictColumns オプションと StrictGrammar オプションが設定されます。クエリでこれらと互換性のないパターンが使用されている場合、クエリは拒否され、例外がスローされます。
インテリジェンス
Android 17 では、システム インテリジェンスに次の変更が加えられています。
setContentCaptureEnabled のサポート終了
コンテンツ キャプチャは、特定のデバイスでデフォルトで有効になっており、オンデバイス AI 機能が画面コンテンツを分析してインテリジェントなエクスペリエンスを提供できるようにします。
Android 17 以降、ContentCaptureManager.setContentCaptureEnabled(boolean) API メソッドは非推奨になりました。Android 17(API レベル 37)以降をターゲットとするアプリの場合、setContentCaptureEnabled(false) を呼び出してもコンテンツ キャプチャが無効にならなくなりました。
アプリで引き続きコンテンツ キャプチャを無効にする必要がある場合や、画面コンテンツがシステムによってキャプチャされないように制限する必要がある場合は、FLAG_SECURE ウィンドウ レイアウト パラメータを使用するように移行する必要があります。
コンテンツ キャプチャを無効にするには、次の例に示すように、ウィンドウに FLAG_SECURE フラグを設定します。
Kotlin
window.setFlags(
WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE
)
Java
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE
);
詳細については、WindowManager.LayoutParams.FLAG_SECURE リファレンス ドキュメントをご覧ください。
メディア
Android 17 では、メディアの動作に次の変更が加えられています。
バックグラウンド音声の強化
Android 17 以降、オーディオ フレームワークは、オーディオ再生、オーディオ フォーカス リクエスト、音量変更 API などのバックグラウンド オーディオ インタラクションに制限を適用し、これらの変更がユーザーによって意図的に開始されるようにします。
一部のオーディオ制限はすべてのアプリに適用されます。ただし、アプリが Android 17(API レベル 37)をターゲットとしている場合は、制限がより厳しくなります。これらのアプリのいずれかがバックグラウンドでオーディオを操作する場合は、フォアグラウンド サービスを実行する必要があります。さらに、アプリは次の要件のいずれかまたは両方を満たす必要があります。
- フォアグラウンド サービスには、使用中(WIU)機能が必要です。
- アプリに正確なアラームの権限があり、
USAGE_ALARM音声ストリームを操作している。
緩和戦略などの詳細については、バックグラウンド オーディオの強化をご覧ください。
デバイスのフォーム ファクタ
Android 17 には、さまざまなデバイスサイズとフォーム ファクタでユーザー エクスペリエンスを向上させるための、以下の変更が含まれています。
大画面(sw>=600dp)で画面の向き、サイズ変更、アスペクト比の制約を無視するようにプラットフォーム API を変更
Android 16 では、対象 API レベル 36 以降をターゲットとするアプリに対して、大画面(sw >= 600dp)での画面の向き、サイズ変更、アスペクト比の制限を無視するようにプラットフォーム API が変更されました。デベロッパーは SDK 36 でこれらの変更をオプトアウトできますが、Android 17(API レベル 37)以降をターゲットとするアプリでは、このオプトアウトは利用できなくなります。
詳細については、向きとサイズ変更の制限が無視されるをご覧ください。
接続
Android 17 では、Bluetooth RFCOMM ソケットの標準的な Java InputStream 動作との整合性を高めるため、以下の変更が導入されています。
RFCOMM の一貫した BluetoothSocket read() 動作
Android 17(API レベル 37)をターゲットとするアプリでは、RFCOMM ベースの BluetoothSocket から取得した InputStream の read() メソッドは、ソケットが閉じられたとき、または接続が切断されたときに -1 を返すようになりました。
この変更により、RFCOMM ソケットの動作が LE CoC ソケットと整合し、ストリームの終わりに達すると -1 が返されるという標準の InputStream.read() ドキュメントに沿った動作になります。
IOException をキャッチして読み取りループを抜けることにのみ依存しているアプリは、この変更の影響を受ける可能性があります。BluetoothSocket の読み取りループを更新して、戻り値が -1 であることを明示的に確認する必要があります。これにより、リモート デバイスが切断されたとき、またはソケットが閉じられたときに、ループが正しく終了します。推奨される実装の例については、Bluetooth データを転送するガイドのコード スニペットをご覧ください。