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 格式。对于大多数应用,包含短信检索器哈希的消息延迟了 3 小时才送达。不过,某些应用(例如默认短信处理程序)不受延迟影响,拥有哈希的应用也不受延迟影响。
从 Android 17 开始,此保护措施也适用于 WebOTP 格式的消息。如果应用有权读取短信,但不是 WebOTP 消息的预期接收者(由网域验证确定),则应用在收到消息 3 小时后才能访问该消息。此项变更旨在提高用户安全性,确保只有与消息中提及的网域相关联的应用才能以编程方式读取验证码。
在这 3 小时的延迟期间,SMS_RECEIVED_ACTION 广播会被扣留,短信提供程序数据库查询会被过滤。延迟后,这些应用便可收到短信。此项变更适用于所有应用,无论其目标 API 级别如何。
某些应用(例如默认短信助理应用、已连接设备的配套应用等)不受此延迟的影响。所有依赖读取短信来提取动态密码的应用都应改用 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 的 intent,系统会自动向目标应用授予读取和写入 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_MULTIPLE intent:
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。 - 在 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 引入了自主重新配对功能,这是一项系统级增强功能,旨在自动解决蓝牙绑定丢失问题。
以前,如果连接丢失,用户必须手动前往“设置”取消配对外围设备,然后重新配对。此功能以 Android 16 的安全改进为基础,使系统能够在获得用户同意后重新建立绑定。这样一来,用户就无需手动前往“设置”来取消配对和重新配对外围设备。
虽然大多数应用不需要更改代码,但开发者应注意蓝牙堆栈中的以下行为变更:
- 新的配对上下文:
ACTION_PAIRING_REQUEST现在包含EXTRA_PAIRING_CONTEXTextra,使应用能够区分标准配对请求和系统发起的自主重新配对尝试。 - 有条件的密钥更新:只有在重新配对成功且新连接的安全级别达到或超过之前绑定的安全级别时,系统才会替换现有安全密钥。
- 修改了 intent 时间:现在,仅当自主重新配对尝试失败时,系统才会广播
ACTION_KEY_MISSINGintent。如果系统在后台成功恢复绑定,这会减少应用中不必要的错误处理。 - 用户通知:系统通过新的界面通知和对话框管理重新配对。系统会提示用户确认重新配对尝试,以确保他们知道重新连接。
外围设备制造商和配套应用开发者应验证硬件和应用是否能妥善处理绑定转换。如需测试此行为,请使用以下任一方法模拟远程绑定丢失:
- 手动从外围设备中移除绑定信息
- 在“设置”>“已连接的设备”中手动取消配对设备