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 権限付与を制限する
現在、アプリがアクション
ACTION_SEND、ACTION_SEND_MULTIPLE、または
ACTION_IMAGE_CAPTUREを含む URI でインテントを起動すると、システムはターゲットアプリに読み取りと
書き込みの URI 権限を自動的に付与します。Android 18 以降では、システムは
これらの権限を自動的に付与しなくなります。そのため、アプリはシステムに権限を付与させるのではなく、関連する URI
権限を明示的に付与することをおすすめします。
アプリでこれらのインテントが使用されていることを検出するには、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_MULTIPLE インテントに追加します。
Kotlin
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
Java
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
ACTION_IMAGE_CAPTURE インテントには、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。 - 在 activity 的
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 会失败,并返回结果代码 AUDIOFOCUS_REQUEST_FAILED。
如需了解详情(包括缓解措施),请参阅后台音频安全加固。
接続
Android 17 では、デバイスの接続性を強化するために次の変更が加えられています。
Bluetooth ボンドの損失に対する自律的な再ペア設定
Android 17 では、Bluetooth 接続の切断を自動的に解決するために設計されたシステムレベルの拡張機能である自律的な再ペア設定が導入されています。
以前は、バインドが失われた場合、ユーザーは [設定] に手動で移動して、周辺機器のペア設定を解除してから再度ペア設定する必要がありました。この機能は、Android 16 のセキュリティ強化を基盤として、ユーザーが手動で設定に移動して周辺機器のペア設定を解除し、再ペア設定する必要なく、システムがバックグラウンドで接続を再確立できるようにします。
ほとんどのアプリではコードの変更は必要ありませんが、デベロッパーは Bluetooth スタックの次の動作変更について認識しておく必要があります。
- 新しいペア設定コンテキスト:
ACTION_PAIRING_REQUESTにEXTRA_PAIRING_CONTEXTエクストラが含まれるようになりました。これにより、アプリは標準のペア設定リクエストと自律システムが開始した再ペア設定の試行を区別できます。 - 条件付き鍵の更新: 再ペア設定が成功し、新しい接続が以前のボンドのセキュリティ レベルを満たすか、それを超える場合にのみ、既存のセキュリティ鍵が置き換えられます。
- インテントのタイミングの変更:
ACTION_KEY_MISSINGインテントは、自律的な再ペア設定の試行が失敗した場合にのみブロードキャストされるようになりました。これにより、システムがバックグラウンドでボンドを正常に復元した場合に、アプリで不要なエラー処理を行う必要がなくなります。 - ユーザー通知: システムは、新しい UI 通知とダイアログを介して再ペア設定を管理します。ユーザーには、再ペア設定の試行を確認するよう求めるメッセージが表示され、再接続を認識できるようになっています。
周辺機器メーカーとコンパニオン アプリ デベロッパーは、ハードウェアとアプリがバインドの移行を適切に処理することを確認する必要があります。この動作をテストするには、次のいずれかの方法でリモート ボンドの損失をシミュレートします。
- 周辺機器から手動でペア設定情報を削除する
- [設定] > [接続済みのデバイス] でデバイスのペア設定を手動で解除します。