Android 17 プラットフォームには、アプリに影響する可能性がある動作変更が含まれています。下記の動作変更は、targetSdkVersion に関係なく、Android 17 上で稼働するすべてのアプリに適用されます。該当する場合は、アプリをテストし、必要に応じて修正して、これらの変更に対応する必要があります。
Android 17 をターゲットとするアプリにのみ影響する動作変更のリストも必ずご確認ください。
コア機能
Android 17(API レベル 37)には、Android システムのさまざまなコア機能を変更または拡張する以下の変更が含まれています。
アプリのメモリ上限
Android 17 では、アプリと Android ユーザー向けに、より安定した決定論的な環境を構築するため、デバイスの合計 RAM に基づくアプリのメモリ上限が導入されました。これらの上限は、メモリリークやその他の外れ値がシステム全体の不安定性を引き起こし、UI のスタッタリング、バッテリー消費の増加、アプリの強制終了につながる前に、それらに焦点を当てています。ほとんどのアプリ セッションへの影響は最小限になると予想されますが、メモリのベースラインを確立するなど、メモリに関する次のベスト プラクティスをおすすめします。
アプリ セッションが影響を受けたかどうかは、ApplicationExitInfo で getDescription を呼び出すことで判断できます。アプリが影響を受けた場合、終了理由は REASON_OTHER になり、説明には "MemoryLimiter:AnonSwap" という文字列とその他の情報が含まれます。TRIGGER_TYPE_ANOMALY でトリガーベースのプロファイリングを使用すると、メモリ上限に達したときに収集されるヒープダンプを取得することもできます。
アプリのメモリを管理するのドキュメントでは、アプリのメモリの問題を診断し、リソース消費を最適化するための情報を提供しています。
メモリ制約下でのアプリの動作をテストする
Android Debug Bridge(adb)を使用すると、メモリ制限を課すデバイスでメモリ制限を調整または無効にできます。シェルコマンド am には、メモリ上限を調整するための 3 つのサブコマンドがあります。(これらのコマンドは、メモリ制限を課していないデバイスには影響しません)。
am memory-limiter ignore <uid>|none|allam memory-limiter manual <pid> <limit>|max|noneam memory-limiter status
ignoreメモリ リミッターに一部またはすべてのプロセスを無視するよう指示します。UID(Android ユーザー ID)を渡すと、メモリ制限ツールは、その UID に関連付けられているすべてのプロセスに対する強制適用を無視するよう指示されます。
all(すべてのアプリを無視)またはnone(アプリを無視しない)を渡すこともできます。noneを渡すと、am memory-limiter ignoreの以前の呼び出しがオーバーライドされます。メモリ制限ツールに UID を無視するよう指示した場合でも、
am memory-limiter manualを呼び出すことで、アプリ内のプロセスに手動でメモリ上限を適用できます。manual指定された PID(プロセス ID)のプロセスにメモリ制約を課すようシステムに指示します。メモリ制約は MB 単位の整数で指定します。たとえば、
30を渡すと、プロセスが 30 MB のメモリに制限されます。maxを渡すと、そのプロセスのメモリ上限がすべて削除されます。noneを渡すと、プロセスに設定された手動制限が削除され、システムのデフォルトの制限(設定されている場合)が復元されます。statusメモリ制限の現在のステータスをレポートします。ステータスには、表示されるプロセスと表示されないプロセスに課せられたメモリ制限が含まれます。
プライバシー
Android 17 では、ユーザーのプライバシーを強化するために、次のような変更が行われています。
SMS OTP 保護
从 Android 17 开始,Android 将扩大对包含一次性密码 (OTP) 的短信的保护范围。
在之前的 Android 版本中,此保护主要侧重于 SMS Retriever 格式。对于大多数应用,包含 SMS Retriever 哈希的消息的递送延迟了 3 小时。不过,某些应用(例如默认短信处理程序)不受此延迟的影响,拥有哈希的应用也不受此延迟的影响。
从 Android 17 开始,此保护也适用于 WebOTP 格式的消息。如果应用有权读取短信,但不是 WebOTP 消息的预期接收者(由网域验证确定),则该应用在收到消息后 3 小时内无法访问该消息。此变更旨在提高用户安全性,确保只有与消息中提及的网域关联的应用才能以编程方式读取验证码。
在这 3 小时的延迟期间,系统会保留 SMS_RECEIVED_ACTION 广播,并过滤 短信提供商 数据库查询。延迟结束后,这些应用即可使用短信。此变更适用于
所有应用,无论其目标 API 级别如何。
某些应用(例如默认短信助理应用、关联设备配套应用等)不受此延迟的影响。所有依赖于读取短信 来提取 OTP 的应用都应过渡到使用 SMS Retriever 或 SMS User Consent API,以确保功能持续可用。
セキュリティ
Android 17 では、デバイスとアプリのセキュリティが以下のように改善されています。
usesClearTraffic の非推奨プラン
今後のリリースで、usesCleartextTraffic 要素は非推奨になる予定です。暗号化されていない(HTTP)接続を行う必要があるアプリは、ネットワーク セキュリティ構成ファイルを使用するように移行する必要があります。このファイルを使用すると、アプリがクリアテキスト接続を行う必要があるドメインを指定できます。
ネットワーク セキュリティ構成ファイルは API レベル 24 以上でのみサポートされます。アプリの最小 API レベルが 24 未満の場合は、次の両方を行う必要があります。
usesCleartextTraffic属性をtrueに設定します。- ネットワーク構成ファイルを使用する
アプリの最小 API レベルが 24 以上の場合、ネットワーク構成ファイルを使用できるため、usesCleartextTraffic を設定する必要はありません。
暗黙的な URI 権限付与を制限する
目前,如果应用启动的 intent 具有 URI,且该 URI 具有操作
ACTION_SEND、ACTION_SEND_MULTIPLE或
ACTION_IMAGE_CAPTURE,则系统会自动向目标应用授予读取和
写入 URI 权限。从 Android 18 开始,系统将
不再自动授予这些权限。因此,我们建议应用明确授予相关 URI 权限,而不是依赖系统授予这些权限。
如需检测应用中这些 intent 的使用情况,请将 StrictMode 与
detectImplicitUriPermissionGrant() 结合使用,以触发违规行为:
Kotlin
val policy = StrictMode.VmPolicy.Builder() .detectImplicitUriPermissionGrant() .penaltyLog() .build() StrictMode.setVmPolicy(policy)
Java
StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder() .detectImplicitUriPermissionGrant() .penaltyLog() .build(); StrictMode.setVmPolicy(policy);
或者,您也可以监控包含消息 Please set the grant explicitly in the app 的已记录异常,该消息会在系统隐式设置授予时显示。您可以使用以下 adb 命令监控这些日志:
adb logcat | grep "Please set the grant explicitly in the app"
如需明确授予必要的权限,请将
FLAG_GRANT_READ_URI_PERMISSION标志添加到ACTION_SEND和
ACTION_SEND_MULTIPLEintent:
Kotlin
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
Java
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
对于
ACTION_IMAGE_CAPTURE intent,请同时添加FLAG_GRANT_READ_URI_PERMISSION 和
FLAG_GRANT_WRITE_URI_PERMISSION 标志:
Kotlin
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
Java
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
アプリごとのキーストアの制限
Android Keystore はデバイス上のすべてのアプリで共有されるリソースであるため、アプリは Android Keystore で過剰な数の鍵を作成しないようにする必要があります。Android 17 以降では、アプリが所有できる鍵の数に上限が設けられています。Android 17(API レベル 37)以上をターゲットとするシステムアプリ以外のアプリの場合、上限は 50,000 個の鍵です。その他のすべてのアプリの場合、上限は 200,000 個の鍵です。システムアプリのキーの上限は、対象とする API レベルに関係なく 200,000 個です。
アプリが上限を超えるキーを作成しようとすると、KeyStoreException で作成が失敗します。例外のメッセージ文字列には、キーの上限に関する情報が含まれています。アプリが例外で getNumericErrorCode() を呼び出す場合、戻り値はアプリのターゲット API レベルによって異なります。
- Android 17(API レベル 37)以上をターゲットとするアプリの場合:
getNumericErrorCode()は新しいERROR_TOO_MANY_KEYS値を返します。 - その他のすべてのアプリ:
getNumericErrorCode()はERROR_INCORRECT_USAGEを返します。
クロス プロファイル ループバック トラフィックをブロック
Android 17 以降では、デフォルトでプロファイル間のループバック トラフィックが許可されなくなりました。同じプロファイル内のループバック トラフィックは影響を受けません。 この変更は、アプリがターゲットとする API レベルに関係なく、Android 17 以降で実行されるすべてのアプリに適用されます。
ユーザー エクスペリエンスとシステム UI
Android 17 には、より一貫性のある直感的なユーザー エクスペリエンスを実現するための以下の変更が含まれています。
回転後の IME の可視性に関するデフォルトを復元
Android 17 以降では、デバイスの構成が変更されたとき(回転など)に、アプリ自体で処理されない場合、以前の IME の可視性は復元されません。
アプリが処理しない構成変更が行われ、変更後にキーボードを表示する必要がある場合は、明示的にリクエストする必要があります。このリクエストは、次のいずれかの方法で行うことができます。
android:windowSoftInputMode属性をstateAlwaysVisibleに設定します。- アクティビティの
onCreate()メソッドでソフト キーボードをプログラムでリクエストするか、onConfigurationChanged()メソッドを追加します。
手入力
Android 17 には、キーボードやタッチパッドなどのヒューマン入力デバイスとアプリがやり取りする方法に影響する次の変更が含まれています。
ポインタ キャプチャ中、タッチパッドはデフォルトで相対イベントを配信する
Android 17 以降では、アプリが View.requestPointerCapture() を使用してポインタ キャプチャをリクエストし、ユーザーがタッチパッドを使用している場合、システムはユーザーのタップによるポインタの移動とスクロール操作を認識し、キャプチャされたマウスのポインタとスクロール ホイールの移動と同じ方法でアプリに報告します。ほとんどの場合、キャプチャされたマウスをサポートするアプリで、タッチパッド用の特別な処理ロジックを追加する必要がなくなります。詳細については、View.POINTER_CAPTURE_MODE_RELATIVE のドキュメントをご覧ください。
以前は、システムはタッチパッドからのジェスチャーを認識しようとせず、代わりに、タッチスクリーンのタップと同様の形式で、指の絶対位置の生データをアプリに配信していました。アプリでこの絶対データが引き続き必要な場合は、代わりに View.POINTER_CAPTURE_MODE_ABSOLUTE を使用して新しい View.requestPointerCapture(int) メソッドを呼び出す必要があります。
メディア
Android 17 では、メディアの動作が次のように変更されています。
バックグラウンド音声の強化
Android 17 以降では、オーディオ フレームワークは、オーディオ再生、音声フォーカス リクエスト、音量変更 API などのバックグラウンド オーディオ インタラクションに対する制限を適用し、これらの変更がユーザーによって意図的に開始されるようにします。
アプリが有効なライフサイクルにないときにアプリが音声 API を呼び出そうとすると、例外をスローしたり、エラー メッセージを提供したりすることなく、音声再生 API と音量変更 API はサイレントに失敗します。音声フォーカス API が結果コード AUDIOFOCUS_REQUEST_FAILED で失敗します。
軽減策など、詳しくは、バックグラウンド音声の強化をご覧ください。
接続
Android 17 では、デバイスの接続性を強化するために次の変更が加えられています。
Bluetooth ボンドの損失に対する自律的な再ペア設定
Android 17 では、Bluetooth 接続の切断を自動的に解決するために設計されたシステムレベルの拡張機能である自律的な再ペア設定が導入されています。
以前は、バインドが失われた場合、ユーザーは [設定] に手動で移動して、周辺機器のペア設定を解除してから再度ペア設定する必要がありました。この機能は、Android 16 のセキュリティ強化を基盤として、ユーザーが手動で設定に移動して周辺機器のペア設定を解除し、再ペア設定する必要なく、システムがバックグラウンドで接続を再確立できるようにします。
ほとんどのアプリではコードの変更は必要ありませんが、デベロッパーは Bluetooth スタックの次の動作変更について認識しておく必要があります。
- 新しいペア設定コンテキスト:
ACTION_PAIRING_REQUESTにEXTRA_PAIRING_CONTEXTエクストラが含まれるようになりました。これにより、アプリは標準のペア設定リクエストと自律システムが開始した再ペア設定の試行を区別できます。 - 条件付き鍵の更新: 再ペア設定が成功し、新しい接続が以前のボンドのセキュリティ レベルを満たすか、それを超える場合にのみ、既存のセキュリティ鍵が置き換えられます。
- インテントのタイミングの変更:
ACTION_KEY_MISSINGインテントは、自律的な再ペア設定の試行が失敗した場合にのみブロードキャストされるようになりました。これにより、システムがバックグラウンドでボンドを正常に復元した場合に、アプリで不要なエラー処理を行う必要がなくなります。 - ユーザー通知: システムは、新しい UI 通知とダイアログを介して再ペア設定を管理します。ユーザーには、再ペア設定の試行を確認するよう求めるメッセージが表示され、再接続を認識できるようになっています。
周辺機器メーカーとコンパニオン アプリ デベロッパーは、ハードウェアとアプリがバインドの移行を適切に処理することを確認する必要があります。この動作をテストするには、次のいずれかの方法でリモート ボンドの損失をシミュレートします。
- 周辺機器から手動でペア設定情報を削除する
- [設定] > [接続済みのデバイス] でデバイスのペア設定を手動で解除します。