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 (cấp độ API 37) bao gồm những thay đổi sau đây nhằm sửa đổi hoặc mở rộng nhiều khả 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 ra một môi trường ổn định và tất định hơn cho ứng dụng và người dùng Android. Các giới hạn này tập trung vào lỗi rò rỉ bộ nhớ và các điểm bất thường khác trước khi chúng gây ra tình trạng không ổn định trên toàn hệ thống, dẫn đến hiện tượng giật giao diện người dùng, hao pin nhiều hơn và ứng dụng bị tắt. Mặc dù chúng tôi dự đoán tác động tối thiểu đến phần lớn các phiên ứng dụng, nhưng bạn nên áp dụng 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 ứng dụng của mình 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 thông tin khác. Bạn cũng có thể sử dụng phân tích dựa trên điều kiện kích hoạt bằng TRIGGER_TYPE_ANOMALY để lấy tệp báo lỗi khối xếp đượ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.

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 dụng giới hạn đó. Lệnh shell am cung cấp 3 lệnh phụ để điều chỉnh giới hạn bộ nhớ. (Các lệnh này không có hiệu lực trê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 trình giới hạn bộ nhớ bỏ qua một số hoặc tất cả quy trình. Việc truyền 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 bất kỳ ứ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 quy tắc ràng buộc về bộ nhớ đối với tiến trình có mã định danh tiến trình (PID) được chỉ định. Giới hạn bộ nhớ được chỉ định dưới dạng số nguyên MB; ví dụ: truyền 30 chỉ định rằng quy trình bị giới hạn ở mức 30 MB bộ nhớ. Việc truyền max sẽ xoá tất cả giới hạn bộ nhớ đối với quy trình đó. Việc truyền none sẽ xoá mọi hạn mức thủ công được đặt cho 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 trình giới hạn bộ nhớ. Trạng thái này bao gồm 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 tin nhắn SMS chứa mật khẩu một lần (OTP).

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

Kể từ Android 17, biện pháp bảo vệ này cũng được áp dụng cho tin nhắn có đị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 quy định của quy trình xác minh miền), thì ứng dụng đó sẽ không thể truy cập 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 khả năng bảo mật cho người dùng bằng cách đảm bảo rằng chỉ những ứng dụng 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 khoảng 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 Nhà cung cấp SMS sẽ được lọc. Tin nhắn SMS sẽ được cung cấp cho các ứng dụng này sau khoảng thời gian trễ. 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 ứng dụng.

Một số ứng dụng nhất định như ứng dụng trợ lý SMS mặc định, ứng dụng đồng hành của thiết bị thông minh, v.v. được miễn áp dụng độ trễ này. Tất cả ứng dụng dựa vào việc đọc tin nhắn SMS để trích xuất OTP nên chuyển sang sử dụng API Trình truy xuất SMS hoặc Sự đồng ý của người dùng SMS để đả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ề khả năng bảo mật của 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 ngừng sử dụng phần tử usesCleartextTraffic. Các ứng dụng cần tạo kết nối không mã hoá (HTTP) nên 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 tạo 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 làm 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, thì 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 có hành động 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 mục tiêu. Kể từ Android 18, hệ thống sẽ không còn tự động cấp các quyền này nữa. Vì lý do này, bạn nên cấp rõ ràng các quyền URI có liên quan cho ứng dụng thay vì dựa vào hệ thống để cấp các 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ệ được ghi lại 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 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 rõ ràng các quyền cần thiết, hãy thêm cờ FLAG_GRANT_READ_URI_PERMISSION vào ý định ACTION_SEND và ACTION_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_PERMISSION và FLAG_GRANT_WRITE_URI_PERMISSION cho ý đị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

Ứng dụng nên tránh tạo quá nhiều khoá trong Kho khoá Android vì đây là tài nguyên dùng chung cho tất cả ứng dụng trên thiết bị. Kể từ Android 17, hệ thống sẽ thực thi giới hạn về số lượng khoá mà một ứng dụng có thể sở hữu. Giới hạn là 50.000 khoá cho các ứng dụng không thuộc hệ thống nhắm đến Android 17 (cấp độ API 37) trở lên và 200.000 khoá cho tất cả các ứng dụng khác. Ứng dụng hệ thống có giới hạn 200.000 khoá, bất kể cấp độ API mà ứng dụng đó nhắm đến.

Nếu một ứng dụng cố gắng tạo khoá vượt quá giới hạn, thì quá trình tạo sẽ không thành công và trả về lỗi KeyStoreException. Chuỗi thông báo của ngoại lệ chứa thông tin về giới hạn khoá. Nếu ứng dụng gọi getNumericErrorCode() cho trường hợp ngoại lệ, thì giá trị trả về sẽ phụ thuộc vào cấp độ API mà ứng dụng nhắm đến:

  • Ứng dụng nhắm đến Android 17 (API cấp 37) trở lên: getNumericErrorCode() trả về giá trị ERROR_TOO_MANY_KEYS mới.
  • Tất cả ứng dụng khác: getNumericErrorCode() trả về ERROR_INCORRECT_USAGE.

Chặn lưu lượng truy cập lặp lại trong hồ sơ

Kể từ Android 17, lưu lượng truy cập lặp lại giữa các hồ sơ không còn được cho phép theo mặc định. Lưu lượng truy cập lặp lại trong cùng một hồ sơ sẽ không bị ảnh hưởng. Thay đổi này áp dụng cho tất cả ứng dụng chạy trên Android 17 trở lên, bất kể cấp độ API mà ứng dụng nhắm đến.

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

Android 17 bao gồm những thay đổi sau đây nhằm mang đến 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 chế độ xoay) và ứng dụng không xử lý được, 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ể đưa ra 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 chụp con trỏ

Kể từ Android 17, nếu một ứng dụng yêu cầu chụp 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 dạng cử chỉ di chuyển 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ư cử chỉ di chuyển con trỏ và con lăn chuột từ chuột được chụp. Trong hầu hết các trường hợp, việc này giúp các ứng dụng hỗ trợ chuột được thu nạp 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, 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 dạng cử chỉ từ bàn di chuột, mà thay vào đó, hệ thống sẽ cung cấp vị trí ngón tay thô, tuyệt đối 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 vẫn cần dữ liệu tuyệt đối này, ứng dụng nên gọi phương thức View.requestPointerCapture(int) mới bằng View.POINTER_CAPTURE_MODE_ABSOLUTE.

Nội dung nghe nhìn

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

Tăng cường bảo mật âm thanh nền

Kể từ Android 17, khung âm thanh sẽ thực thi các quy định hạn chế đối với các hoạt động tương tác âm thanh trong nền, bao gồm cả việc phát âm thanh, yêu cầu lấy tiêu điểm âm thanh và các API thay đổi âm lượng để đảm bảo rằng những thay đổi này được bắt đầu một cách có chủ đích bởi người dùng.

Nếu ứng dụng cố gắng gọi API âm thanh khi ứng dụng không ở trong một vòng đời hợp lệ, thì API phát âm thanh và thay đổi âm lượng sẽ không hoạt động mà không gửi ngoại lệ hoặc cung cấp thông báo lỗi. API tâm điểm âm thanh không thành công với mã kết quả AUDIOFOCUS_REQUEST_FAILED.

Để biết thêm thông tin, bao gồm cả các chiến lược giảm thiểu, hãy xem phần Tăng cường bảo mật âm thanh nền.

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 kết nối Bluetooth

Android 17 ra mắt tính năng tự động ghép nối lại, một tính năng nâng cao ở cấp hệ thống được thiết kế để tự động giải quyết tình trạng mất kết nối Bluetooth.

Trước đây, nếu mất liên kết, người dùng phải chuyển đến phần Cài đặt theo cách thủ công để hủy ghép nối rồi ghép nối lại thiết bị ngoại vi. Tính năng này dựa trên điểm cải tiến về bảo mật của Android 16 bằng cách cho phép hệ thống thiết lập lại mối liên kết ở chế độ nền mà không yêu cầu người dùng phải chuyển đến phần Cài đặt theo cách thủ công để hủy ghép nối và ghép nối lại thiết bị ngoại vi.

Mặc dù hầu hết các ứng dụng sẽ không cần thay đổi mã, nhưng nhà phát triển nên lưu ý những thay đổi sau đây về hành vi trong ngăn xếp Bluetooth:

  • Bối cảnh ghép nối mới: ACTION_PAIRING_REQUEST hiện bao gồm cả EXTRA_PAIRING_CONTEXT, cho phép các ứng dụng phân biệt giữa yêu cầu ghép nối tiêu chuẩn và nỗ lực ghép nối lại do hệ thống tự động khởi tạo.
  • Cập nhật khoá có điều kiện: Khoá bảo mật hiện có sẽ chỉ được thay thế nếu quá trình ghép nối lại thành công và kết nối mới đáp ứng hoặc vượt quá mức bảo mật của mối liên kết trước đó.
  • Thời gian sửa đổi ý định: Ý định ACTION_KEY_MISSING hiện chỉ được truyền phát nếu nỗ lực ghép nối lại tự động không thành công. Điều này giúp giảm việc xử lý lỗi không cần thiết trong ứng dụng nếu hệ thống khôi phục thành công liên kết trong nền.
  • Thông báo cho người dùng: Hệ thống quản lý việc ghép nối lại thông qua các thông báo và hộp thoại mới trên giao diện người dùng. Người dùng sẽ được nhắc xác nhận việc ghép nối lại để đảm bảo họ biết về việc kết nối lại.

Nhà sản xuất thiết bị ngoại vi và nhà phát triển ứng dụng đồng hành nên xác minh rằng phần cứng và ứng dụng xử lý quá trình chuyển đổi liên kết một cách linh hoạt. Để kiểm thử hành vi này, hãy mô phỏng việc mất liên kết từ xa bằng một trong hai phương thức sau:

  • Xoá thông tin liên kết khỏi thiết bị ngoại vi theo cách thủ công
  • Huỷ ghép nối thiết bị theo cách thủ công trong phần: Cài đặt > Thiết bị đã kết nối