動作の変更点: すべてのアプリ

Android 17 プラットフォームには、アプリに影響する可能性がある動作変更が含まれています。下記の動作変更は、targetSdkVersion に関係なく、Android 17 上で稼働するすべてのアプリに適用されます。該当する場合は、アプリをテストし、必要に応じて修正して、これらの変更に対応する必要があります。

Android 17 をターゲットとするアプリにのみ影響する動作変更のリストも必ずご確認ください。

コア機能

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

アプリのメモリ上限

Android 17 引入了基于设备总 RAM 的应用内存限制,旨在为您的应用和 Android 用户打造更稳定、更具确定性的环境。这些限制侧重于在内存泄漏和其他异常值触发系统范围的不稳定性(导致界面卡顿、电池耗电量增加和应用被终止)之前,对其进行限制。虽然我们预计对绝大多数应用会话的影响很小,但我们建议您遵循以下内存最佳实践,包括建立内存基准。

您可以在 ApplicationExitInfo 中调用 getDescription,以确定您的应用会话是否受到影响;如果您的应用受到 影响,退出原因将为 REASON_OTHER,并且 说明将包含字符串 "MemoryLimiter:AnonSwap" 以及 其他信息。您还可以使用基于触发器的分析(使用 TRIGGER_TYPE_ANOMALY)来获取在达到 内存限制时收集的堆转储。

管理应用内存”文档提供了相关信息 可帮助您诊断应用的内存问题并优化其资源 消耗。

在内存限制下测试应用的行为

您可以使用 Android 调试桥 (adb) 调整或停用对任何设备施加的 内存限制。Shell 命令 am 提供了三个子命令来调整内存限制。(这些命令对未施加内存限制的设备没有影响。)

  • am memory-limiter ignore <uid>|none|all
  • am memory-limiter manual <pid> <limit>|max|none
  • am 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 RetrieverSMS User Consent API,以确保功能持续可用。

セキュリティ

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

usesClearTraffic の非推奨プラン

今後のリリースで、usesCleartextTraffic 要素は非推奨になる予定です。暗号化されていない(HTTP)接続を行う必要があるアプリは、ネットワーク セキュリティ構成ファイルを使用するように移行する必要があります。このファイルを使用すると、アプリがクリアテキスト接続を行う必要があるドメインを指定できます。

ネットワーク セキュリティ構成ファイルは API レベル 24 以上でのみサポートされます。アプリの最小 API レベルが 24 未満の場合は、次の両方を行う必要があります。

  • usesCleartextTraffic 属性を true に設定します。
  • ネットワーク構成ファイルを使用する

アプリの最小 API レベルが 24 以上の場合、ネットワーク構成ファイルを使用できるため、usesCleartextTraffic を設定する必要はありません。

暗黙的な URI 権限付与を制限する

現在、アプリがアクション ACTION_SENDACTION_SEND_MULTIPLE、または ACTION_IMAGE_CAPTUREを含む URI でインテントを起動すると、システムはターゲットアプリに読み取りと 書き込みの URI 権限を自動的に付与します。Android 18 以降では、システムは これらの権限を自動的に付与しなくなります。そのため、アプリはシステムに権限を付与させるのではなく、関連する URI 権限を明示的に付与することをおすすめします。

アプリでこれらのインテントが使用されていることを検出するには、StrictModedetectImplicitUriPermissionGrant() を使用して違反をトリガーします。

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 密钥库中创建过多的密钥,因为它是设备上所有应用的共享资源。从 Android 17 开始,系统会强制限制应用可拥有的密钥数量。对于以 Android 17(API 级别 37)或更高版本为目标平台的非系统应用,密钥数量上限为 50,000 个;对于所有其他应用,密钥数量上限为 200,000 个。无论系统应用以哪个 API 级别为目标,其密钥数量上限均为 20 万。

如果应用尝试创建超出限制的密钥,则创建会失败并显示 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_CONTEXT extra,允许应用区分 标准配对请求和自主系统发起的重新配对尝试。
  • 有条件的密钥更新:只有在重新配对成功且新连接达到或超过之前配对信息的安全级别时,才会替换现有安全密钥。
  • 修改后的 intent 时间:现在,只有在自主重新配对尝试失败时,才会广播 ACTION_KEY_MISSING intent。如果系统在后台成功恢复配对信息,则可以减少应用中不必要的错误处理。
  • 用户通知:系统通过新的界面通知和对话框管理重新配对。系统会提示用户确认重新配对尝试,以确保用户了解重新连接。

外围设备制造商和配套应用开发者应验证硬件和应用是否能妥善处理配对信息转换。如需测试此行为,请使用以下任一方法模拟远程配对信息丢失:

  • 从外围设备中手动移除配对信息
  • 在“设置”>“已连接的设备”中手动取消配对设备