Thay đổi về hành vi: tất cả ứng dụng

Nền tảng Android 17 có các thay đổi về hành vi có thể ảnh hưởng đến ứng dụng của bạn. Những thay đổi về hành vi sau đây áp dụng cho tất cả ứng dụng chạy trên Android 17, bất kể targetSdkVersion. Bạn nên kiểm thử ứng dụng rồi sửa đổi để hỗ trợ những thay đổi này cho phù hợp (nếu cần).

Ngoài ra, hãy nhớ tham khảo danh sách thay đổi về hành vi chỉ ảnh hưởng đến những ứng dụng nhắm đến Android 17.

Chức năng cốt lõi

Android 17 (API cấp 37) có những thay đổi sau đây giúp sửa đổi hoặc mở rộng nhiều chức năng cốt lõi của hệ thống Android.

Giới hạn bộ nhớ ứng dụng

Android 17 mang đến tính năng giới hạn bộ nhớ ứng dụng dựa trên tổng dung lượng RAM của thiết bị để tạo một môi trường ổn định và có thể xác định hơn cho các ứng dụng và người dùng Android. Các giới hạn này tập trung vào tình trạng rò rỉ bộ nhớ và các điểm ngoại lệ khác trước khi chúng kích hoạt tình trạng không ổn định trên toàn hệ thống, dẫn đến hiện tượng kết xuất gián đoạn giao diện người dùng, mức tiêu hao pin cao hơn và ứng dụng bị tắt. Mặc dù dự kiến sẽ có tác động không đáng kể đến phần lớn các phiên hoạt động của ứng dụng, nhưng bạn nên làm theo các phương pháp hay nhất sau đây về bộ nhớ, bao gồm cả việc thiết lập một đường cơ sở cho bộ nhớ.

Bạn có thể xác định xem phiên hoạt động của ứng dụng có bị ảnh hưởng hay không bằng cách gọi getDescription trong ApplicationExitInfo; nếu ứng dụng của bạn bị ảnh hưởng, lý do thoát sẽ là REASON_OTHER và nội dung mô tả sẽ chứa chuỗi "MemoryLimiter:AnonSwap" cùng với các thông tin khác. Bạn cũng có thể sử dụng hồ sơ dựa trên trình kích hoạt với TRIGGER_TYPE_ANOMALY để nhận các kết xuất heap được thu thập khi đạt đến giới hạn bộ nhớ.

Tài liệu Quản lý bộ nhớ của ứng dụng cung cấp thông tin giúp bạn chẩn đoán các vấn đề về bộ nhớ của ứng dụng và tối ưu hoá mức tiêu thụ tài nguyên của ứng dụng.

Kiểm thử hành vi của ứng dụng trong điều kiện hạn chế về bộ nhớ

Bạn có thể dùng Cầu gỡ lỗi Android (adb) để điều chỉnh hoặc tắt giới hạn bộ nhớ trên mọi thiết bị áp đặt giới hạn này. Lệnh shell am cung cấp 3 lệnh con để điều chỉnh hạn mức bộ nhớ. (Các lệnh này không ảnh hưởng đến thiết bị không áp đặt giới hạn bộ nhớ.)

  • am memory-limiter ignore <uid>|none|all
  • am memory-limiter manual <pid> <limit>|max|none
  • am memory-limiter status
ignore

Hướng dẫn bộ giới hạn bộ nhớ bỏ qua một số hoặc tất cả các quy trình. Việc truyền một UID (Mã nhận dạng người dùng Android) sẽ hướng dẫn trình giới hạn bộ nhớ bỏ qua việc thực thi trên tất cả các quy trình liên kết với UID đó. Bạn cũng có thể truyền all (bỏ qua tất cả ứng dụng) hoặc none (không bỏ qua ứng dụng nào). Việc truyền none sẽ ghi đè mọi lệnh gọi trước đó đến am memory-limiter ignore.

Nếu hướng dẫn trình giới hạn bộ nhớ bỏ qua một UID, bạn vẫn có thể áp dụng giới hạn bộ nhớ theo cách thủ công cho một quy trình trong ứng dụng bằng cách gọi am memory-limiter manual.

manual

Hướng dẫn hệ thống áp đặt một hạn chế về bộ nhớ đối với quy trình có PID (Mã nhận dạng quy trình) được chỉ định. Hạn chế về bộ nhớ được chỉ định dưới dạng số nguyên (số MB); ví dụ: truyền 30 chỉ định rằng quy trình bị giới hạn ở 30 MB bộ nhớ. Truyền max sẽ xoá tất cả các giới hạn bộ nhớ trên quy trình đó. Việc truyền none sẽ xoá mọi hạn mức thủ công được đặt trên quy trình, khôi phục hạn mức mặc định của hệ thống (nếu có).

status

Báo cáo trạng thái hiện tại của bộ giới hạn bộ nhớ. Trạng thái này bao gồm cả giới hạn bộ nhớ áp dụng cho các quy trình hiển thị và không hiển thị.

Quyền riêng tư

Android 17 có những thay đổi sau đây để cải thiện quyền riêng tư của người dùng.

Bảo vệ mã OTP qua tin nhắn SMS

Kể từ Android 17, Android sẽ mở rộng phạm vi bảo vệ cho các tin nhắn SMS chứa mật khẩu dùng một lần (OTP).

Trong các phiên bản Android trước, tính năng bảo vệ này chủ yếu tập trung vào định dạng SMS Retriever. Việc gửi tin nhắn chứa hàm băm SMS Retriever bị trì hoãn trong 3 giờ đối với hầu hết các ứng dụng. Tuy nhiên, một số ứng dụng (như trình xử lý SMS mặc định) được miễn trì hoãn và ứng dụng sở hữu hàm băm cũng được miễn.

Kể từ Android 17, tính năng bảo vệ này cũng được áp dụng cho các tin nhắn ở định dạng WebOTP. Nếu một ứng dụng có quyền đọc tin nhắn SMS nhưng không phải là người nhận dự kiến của tin nhắn WebOTP (theo kết quả xác minh miền), thì ứng dụng đó sẽ không truy cập được vào tin nhắn cho đến 3 giờ sau khi nhận được tin nhắn. Thay đổi này nhằm cải thiện tính bảo mật cho người dùng bằng cách đảm bảo rằng chỉ những ứng dụng được liên kết với miền được đề cập trong tin nhắn mới có thể đọc mã xác minh theo phương thức lập trình.

Trong thời gian trì hoãn 3 giờ này, thông báo truyền tin SMS_RECEIVED_ACTION sẽ bị giữ lại và các truy vấn cơ sở dữ liệu của nhà cung cấp SMS sẽ được lọc. Tin nhắn SMS sẽ có sẵn cho các ứng dụng này sau khi hết thời gian trì hoãn. Thay đổi này áp dụng cho tất cả ứng dụng, bất kể cấp độ API mục tiêu của chúng.

Một số ứng dụng như ứng dụng trợ lý SMS mặc định, ứng dụng đồng hành cho thiết bị thông minh, v.v. được miễn trì hoãn. Tất cả ứng dụng dựa vào việc đọc tin nhắn SMS để trích xuất OTP đều phải chuyển sang sử dụng API SMS Retriever hoặc API SMS User Consent để đảm bảo chức năng tiếp tục hoạt động.

Bảo mật

Android 17 có những điểm cải tiến sau đây về bảo mật thiết bị và ứng dụng.

Kế hoạch ngừng sử dụng usesClearTraffic

Trong một bản phát hành trong tương lai, chúng tôi dự định sẽ ngừng sử dụng phần tử usesCleartextTraffic. Những ứng dụng cần thực hiện kết nối không được mã hoá (HTTP) nên di chuyển sang sử dụng tệp cấu hình bảo mật mạng. Tệp này cho phép bạn chỉ định những miền mà ứng dụng cần kết nối văn bản thô.

Xin lưu ý rằng tệp cấu hình bảo mật mạng chỉ được hỗ trợ trên API cấp 24 trở lên. Nếu ứng dụng của bạn có cấp độ API tối thiểu thấp hơn 24, bạn nên thực hiện cả hai việc sau:

  • Đặt thuộc tính usesCleartextTraffic thành true
  • Sử dụng tệp cấu hình mạng

Nếu cấp độ API tối thiểu của ứng dụng là 24 trở lên, bạn có thể sử dụng tệp cấu hình mạng và không cần đặt usesCleartextTraffic.

Hạn chế cấp quyền URI ngầm ẩn

Hiện tại, nếu một ứng dụng khởi chạy một ý định có URI với thao tác ACTION_SEND, ACTION_SEND_MULTIPLE hoặc ACTION_IMAGE_CAPTURE, thì hệ thống sẽ tự động cấp quyền đọc và ghi URI cho ứng dụng đích. Kể từ Android 18, hệ thống sẽ không tự động cấp các quyền này nữa. Vì lý do này, bạn nên cấp quyền URI có liên quan một cách rõ ràng cho các ứng dụng thay vì dựa vào hệ thống để cấp quyền.

Để phát hiện việc sử dụng các ý định này trong ứng dụng, hãy dùng StrictMode với detectImplicitUriPermissionGrant() để kích hoạt lỗi vi phạm:

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);

Ngoài ra, bạn có thể theo dõi các ngoại lệ đã ghi nhật ký có chứa thông báo Please set the grant explicitly in the app xuất hiện khi hệ thống ngầm đặt quyền truy cập. Bạn có thể theo dõi các nhật ký này bằng lệnh adb sau:

adb logcat | grep "Please set the grant explicitly in the app"

Để cấp các quyền cần thiết một cách rõ ràng, hãy thêm cờ FLAG_GRANT_READ_URI_PERMISSION vào ý định ACTION_SENDACTION_SEND_MULTIPLE:

Kotlin

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)

Java

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

Thêm cả cờ FLAG_GRANT_READ_URI_PERMISSIONFLAG_GRANT_WRITE_URI_PERMISSION cho các ý định ACTION_IMAGE_CAPTURE:

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);

Giới hạn kho khoá cho mỗi ứng dụng

应用应避免在 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

Chặn lưu lượng truy cập vòng lặp trên nhiều hồ sơ

从 Android 17 开始,默认情况下不再允许跨个人资料环回流量。同一个人资料内的环回流量不受影响。 此项变更适用于在 Android 17 或更高版本上运行的所有应用,无论应用以哪个 API 级别为目标平台。

Trải nghiệm người dùng và giao diện người dùng hệ thống

Android 17 có những thay đổi sau đây nhằm tạo ra trải nghiệm người dùng nhất quán và trực quan hơn.

Khôi phục chế độ hiển thị IME mặc định sau khi xoay

Kể từ Android 17, khi cấu hình của thiết bị thay đổi (ví dụ: thông qua thao tác xoay) và ứng dụng không tự xử lý việc này, thì chế độ hiển thị IME trước đó sẽ không được khôi phục.

Nếu ứng dụng của bạn trải qua một thay đổi về cấu hình mà ứng dụng không xử lý và ứng dụng cần bàn phím hiển thị sau khi thay đổi, thì bạn phải yêu cầu rõ ràng điều này. Bạn có thể gửi yêu cầu này theo một trong những cách sau:

  • Đặt thuộc tính android:windowSoftInputMode thành stateAlwaysVisible.
  • Yêu cầu bàn phím mềm theo phương thức lập trình trong phương thức onCreate() của hoạt động hoặc thêm phương thức onConfigurationChanged().

Dữ liệu đầu vào của con người

Android 17 có những thay đổi sau đây ảnh hưởng đến cách ứng dụng tương tác với các thiết bị đầu vào của con người như bàn phím và bàn di chuột.

Bàn di chuột cung cấp các sự kiện tương đối theo mặc định trong quá trình ghi lại con trỏ

Kể từ Android 17, nếu một ứng dụng yêu cầu tính năng ghi lại con trỏ bằng View.requestPointerCapture() và người dùng sử dụng bàn di chuột, thì hệ thống sẽ nhận ra chuyển động của con trỏ và cử chỉ cuộn từ thao tác chạm của người dùng, đồng thời báo cáo các cử chỉ đó cho ứng dụng theo cách tương tự như chuyển động của con trỏ và bánh xe cuộn từ chuột đã ghi lại. Trong hầu hết các trường hợp, điều này giúp các ứng dụng hỗ trợ chuột đã ghi lại không cần thêm logic xử lý đặc biệt cho bàn di chuột. Để biết thêm thông tin chi tiết, hãy xem tài liệu về View.POINTER_CAPTURE_MODE_RELATIVE.

Trước đây, hệ thống không cố gắng nhận ra cử chỉ từ bàn di chuột mà thay vào đó, cung cấp vị trí ngón tay tuyệt đối, thô cho ứng dụng ở định dạng tương tự như thao tác chạm trên màn hình cảm ứng. Nếu một ứng dụng vẫn yêu cầu dữ liệu tuyệt đối này, thì ứng dụng đó nên gọi phương thức mới bằng thay vì.View.requestPointerCapture(int)View.POINTER_CAPTURE_MODE_ABSOLUTE

Nội dung nghe nhìn

Android 17 có những thay đổi sau đây về hành vi của nội dung nghe nhìn.

Tăng cường bảo mật âm thanh ở chế độ nền

从 Android 17 开始,音频框架会对后台音频互动(包括音频播放、音频焦点请求和音量更改 API)强制执行限制,以确保这些更改是由用户有意发起的。

如果应用尝试在应用未处于有效生命周期时调用音频 API,则音频播放和音量更改 API 会以静默方式失败,而不会抛出异常或提供失败消息。音频焦点 API 会失败,并返回结果代码 AUDIOFOCUS_REQUEST_FAILED

如需了解详情(包括缓解措施),请参阅后台音频安全加固

Khả năng kết nối

Android 17 có những thay đổi sau đây để tăng cường khả năng kết nối của thiết bị.

Tự động ghép nối lại khi mất liên kết Bluetooth

Android 17 引入了自主重新配对功能,这是一项系统级增强功能,旨在自动解决蓝牙配对信息丢失问题。

以前,如果配对信息丢失,用户必须手动前往“设置”取消配对,然后重新配对外围设备。此功能以 Android 16 的安全改进为基础,允许系统在后台重新建立配对信息,而无需用户手动前往“设置”取消配对并重新配对外围设备。

虽然大多数应用不需要更改代码,但开发者应注意蓝牙堆栈中的以下行为变更:

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

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

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