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

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

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

コア機能

Android 17 には、Android システムのさまざまなコア機能を変更または拡張する以下の変更が含まれています。

MessageQueue の新しいロックフリー実装

Beginning with Android 17, apps targeting Android 17 (API level 37) or higher receive a new lock-free implementation of android.os.MessageQueue. The new implementation improves performance and reduces missed frames, but may break clients that reflect on MessageQueue private fields and methods.

For more information, including mitigation strategies, see MessageQueue behavior change guidance.

static final フィールドが変更不可になった

Apps running on Android 17 or higher that target Android 17 (API level 37) or higher cannot change static final fields. If an app attempts to change a static final field by using reflection, it will cause an IllegalAccessException. Attempting to modify one of these fields through JNI APIs (such as SetStaticLongField()) will cause the app to crash.

ユーザー補助

Android 17 では、ユーザー補助を改善するために以下の変更が行われています。

複雑な IME 物理キーボード入力のユーザー補助サポート

この機能では、CJKV 言語入力のスクリーン リーダーの音声フィードバックを強化するために、新しい AccessibilityEventTextAttribute API が導入されています。CJKV IME アプリは、テキストの作成中にテキスト変換候補が選択されたかどうかを通知できるようになりました。編集フィールドのあるアプリは、テキスト変更のユーザー補助イベントを送信するときに、テキスト変更タイプ を指定できます。 たとえば、テキストの作成中にテキストが変更されたことや、確定によってテキストが変更されたことを指定できます。 これにより、スクリーン リーダーなどのユーザー補助サービスは、テキストの変更の性質に基づいて、より正確なフィードバックを提供できます。

導入アプリ数

  • 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 では、TLS handshake で Server Name Indication(SNI)を暗号化することでユーザーのプライバシーを強化する TLS 拡張機能である Encrypted Client Hello(ECH)のプラットフォーム サポートが導入されています。この暗号化により、ネットワーク監視者がアプリの接続先の特定のドメインを簡単に特定することを防ぐことができます。

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 ユーザー同意 API を使用するように移行する必要があります。

セキュリティ

Android 17 では、デバイスとアプリのセキュリティが次のように改善されています。

アクティビティのセキュリティ

In Android 17, the platform continues its shift toward a "secure-by-default" architecture, introducing a suite of enhancements designed to mitigate high-severity exploits such as phishing, interaction hijacking, and confused deputy attacks. This update requires developers to explicitly opt in to new security standards to maintain app compatibility and user protection.

Key impacts for developers include:

  • BAL hardening & improved opt-in: We are refining Background Activity Launch (BAL) restrictions by extending protections to IntentSender. Developers must migrate away from the legacy MODE_BACKGROUND_ACTIVITY_START_ALLOWED constant. Instead, you should adopt granular controls like MODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLE, which restricts activity starts to scenarios where the calling app is visible, significantly reducing the attack surface.
  • Adoption tools: Developers should utilize strict mode and updated lint checks to identify legacy patterns and ensure readiness for future target SDK requirements.

CT をデフォルトで有効にする

If an app targets Android 17 (API level 37) or higher, certificate transparency (CT) is enabled by default. (On Android 16, CT is available but apps had to opt in.)

より安全なネイティブ DCL - C

アプリが Android 17(API レベル 37)以降をターゲットとしている場合、Android 14 で導入された DEX ファイルと JAR ファイルの動的コードのより安全な読み込み(DCL)保護がネイティブ ライブラリにも適用されるようになりました。

System.load() を使用して読み込まれるネイティブ ファイルはすべて読み取り専用としてマークする必要があります。そうしないと、システムは UnsatisfiedLinkError をスローします。

アプリでは可能な限り、コードを動的に読み込まないようにすることをおすすめします。コードを動的に読み込むと、コード インジェクションやコードの改ざんによってアプリが不正使用されるリスクが大幅に高まります。

CP2 データビューで機密データのフィールドを制限する

Android 17(API レベル 37)以上を対象とするアプリの場合、連絡先プロバイダ 2(CP2)は、個人を特定できる情報(PII)を含む特定の列をデータビューから制限します。この変更を有効にすると、ユーザーのプライバシーを強化するために、これらの列がデータビューから削除されます。制限付き列には次のものがあります。

ContactsContract.Data のこれらの列を使用しているアプリは、RAW_CONTACT_ID と結合することで、代わりに ContactsContract.RawContacts から抽出できます。

CP2 で厳格な SQL チェックを適用する

Android 17(API レベル 37)以上をターゲットとするアプリの場合、READ_CONTACTS 権限なしで ContactsContract.Data テーブルにアクセスすると、連絡先プロバイダ 2(CP2)は厳格な SQL クエリ検証を適用します。

この変更により、アプリに READ_CONTACTS 権限がない場合、ContactsContract.Data テーブルをクエリするときに StrictColumns オプションと StrictGrammar オプションが設定されます。クエリでこれらのパターンと互換性のないパターンが使用されている場合、クエリは拒否され、例外がスローされます。

メディア

Android 17 には、メディアの動作に関する以下の変更が含まれています。

バックグラウンド オーディオの強化

Android 17 以降では、オーディオ フレームワークは、オーディオ再生、音声フォーカス リクエスト、音量変更 API などのバックグラウンド オーディオ インタラクションに対する制限を適用し、これらの変更がユーザーによって意図的に開始されるようにします。

一部の音声制限はすべてのアプリに適用されます。ただし、アプリが Android 17(API レベル 37)をターゲットとしている場合、制限はより厳しくなります。これらのアプリのいずれかがバックグラウンドでオーディオを操作する場合は、フォアグラウンド サービスが実行されている必要があります。また、アプリは次の要件のいずれかまたは両方を満たす必要があります。

  • フォアグラウンド サービスには「使用中のみ許可」の機能が必要です。
  • アプリに正確なアラームの権限が付与されており、USAGE_ALARM 音声ストリームとやり取りしている必要があります。

軽減策など、詳しくは、バックグラウンド音声の強化をご覧ください。

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

Android 17 には、さまざまなデバイスサイズとフォーム ファクタでユーザー エクスペリエンスを向上させるための以下の変更が含まれています。

大画面(画面幅 600 dp 以上)での画面の向き、サイズ変更、アスペクト比の制約を無視するためのプラットフォーム API の変更

Android 16 では、API レベル 36 以上をターゲットとするアプリで大画面(sw >= 600dp)の画面の向き、アスペクト比、サイズ変更の制限を無視するためのプラットフォーム API の変更を導入しました。デベロッパーは SDK 36 でこれらの変更をオプトアウトできますが、Android 17(API レベル 37)以上をターゲットとするアプリでは、このオプトアウトは利用できなくなります。

詳しくは、向きとサイズ変更の制限が無視されるをご覧ください。

接続

Android 17 では、一貫性を高め、Bluetooth RFCOMM ソケットの標準 Java InputStream 動作に合わせるために、以下の変更が導入されています。

RFCOMM の BluetoothSocket read() 動作の一貫性

For apps targeting Android 17 (API level 37), the read() method of the InputStream obtained from an RFCOMM-based BluetoothSocket now returns -1 when the socket is closed or the connection is dropped.

This change makes RFCOMM socket behavior consistent with LE CoC sockets and aligns with the standard InputStream.read() documentation, which states that -1 is returned when the end of the stream is reached.

Apps that rely solely on catching an IOException to break out of a read loop may be impacted by this change and should update the BluetoothSocket read loops to explicitly check for a return value of -1. This ensures the loop terminates correctly when the remote device disconnects or the socket is closed. For an example of the recommended implementation, see the code snippet in the Transfer Bluetooth data guide.