Android 9 (API cấp 28) giới thiệu một số thay đổi đối với hệ thống Android.
Những thay đổi về hành vi sau đây chỉ áp dụng cho ứng dụng nhắm đến API cấp 28 trở lên. Những ứng dụng đặt targetSdkVersion thành API cấp 28 trở lên phải sửa đổi ứng dụng để hỗ trợ những hành vi này cho phù hợp (nếu cần).
Đối với những thay đổi ảnh hưởng đến tất cả ứng dụng chạy trên Android 9, bất kể ứng dụng đó nhắm đến cấp độ API nào, hãy xem Các thay đổi về hành vi: tất cả ứng dụng.
Dịch vụ trên nền trước
Những ứng dụng nhắm đến Android 9 trở lên và sử dụng dịch vụ trên nền trước phải yêu cầu quyền FOREGROUND_SERVICE. Đây là quyền thông thường, vì vậy hệ thống sẽ tự động cấp quyền này cho ứng dụng yêu cầu.
Nếu một ứng dụng nhắm đến Android 9 trở lên cố gắng tạo một dịch vụ trên nền trước mà không yêu cầu FOREGROUND_SERVICE, thì hệ thống sẽ gửi một SecurityException.
Những thay đổi về quyền riêng tư
Nếu ứng dụng của bạn nhắm đến Android 9, bạn nên lưu ý những thay đổi sau đây về hành vi. Những nội dung cập nhật này đối với thông tin DNS và số sê-ri thiết bị sẽ giúp tăng cường quyền riêng tư của người dùng.
Ngừng sử dụng số sê-ri bản dựng
Trong Android 9, Build.SERIAL luôn được đặt thành "UNKNOWN" để bảo vệ quyền riêng tư của người dùng.
Nếu ứng dụng của bạn cần truy cập vào số sê-ri phần cứng của thiết bị, thì thay vào đó, bạn nên yêu cầu quyền READ_PHONE_STATE, sau đó gọi getSerial().
Quyền riêng tư của DNS
Các ứng dụng nhắm đến Android 9 phải tuân thủ các API DNS riêng tư. Cụ thể, các ứng dụng phải đảm bảo rằng nếu trình phân giải hệ thống đang thực hiện DNS qua TLS, thì mọi ứng dụng DNS tích hợp sẵn đều sử dụng DNS được mã hoá cho cùng tên máy chủ như hệ thống hoặc bị vô hiệu hoá để ưu tiên trình phân giải hệ thống.
Thay đổi về bảo mật trong khung
Android 9 có một số thay đổi về hành vi giúp cải thiện tính bảo mật của ứng dụng, nhưng những thay đổi này chỉ có hiệu lực nếu ứng dụng của bạn nhắm đến API cấp 28 trở lên.
TLS mạng được bật theo mặc định
Nếu ứng dụng của bạn nhắm đến Android 9 trở lên, thì phương thức isCleartextTrafficPermitted() sẽ trả về false theo mặc định. Nếu ứng dụng của bạn cần bật văn bản thuần tuý cho các miền cụ thể, bạn phải đặt cleartextTrafficPermitted thành true một cách rõ ràng cho những miền đó trong Cấu hình bảo mật mạng của ứng dụng.
Các thư mục dữ liệu dựa trên web được phân tách theo quy trình
Để cải thiện độ ổn định của ứng dụng và tính toàn vẹn của dữ liệu trong Android 9, các ứng dụng không thể chia sẻ một thư mục dữ liệu WebView duy nhất giữa nhiều quy trình. Thông thường, các thư mục dữ liệu như vậy lưu trữ cookie, bộ nhớ đệm HTTP và bộ nhớ tạm thời cũng như bộ nhớ liên tục khác liên quan đến hoạt động duyệt web.
Trong hầu hết các trường hợp, ứng dụng của bạn chỉ nên sử dụng các lớp từ gói android.webkit, chẳng hạn như WebView và CookieManager, trong một quy trình. Ví dụ: bạn nên di chuyển tất cả các đối tượng Activity sử dụng WebView vào cùng một quy trình. Bạn có thể thực thi nghiêm ngặt hơn quy tắc "chỉ một quy trình" bằng cách gọi disableWebView() trong các quy trình khác của ứng dụng. Lệnh gọi này ngăn WebView được khởi chạy nhầm trong các quy trình khác đó, ngay cả khi lệnh gọi này được gọi từ một thư viện phụ thuộc.
Nếu ứng dụng của bạn phải sử dụng các thực thể của WebView trong nhiều quy trình, thì bạn phải chỉ định một hậu tố thư mục dữ liệu duy nhất cho mỗi quy trình bằng phương thức WebView.setDataDirectorySuffix() trước khi sử dụng một thực thể nhất định của WebView trong quy trình đó. Phương thức này đặt dữ liệu web từ mỗi quy trình vào thư mục riêng trong thư mục dữ liệu của ứng dụng.
Miền SELinux cho từng ứng dụng
Các ứng dụng nhắm đến Android 9 trở lên không thể chia sẻ dữ liệu với các ứng dụng khác bằng quyền Unix mà mọi người đều có thể truy cập. Thay đổi này giúp cải thiện tính toàn vẹn của Hộp cát ứng dụng Android, đặc biệt là yêu cầu về việc chỉ ứng dụng đó mới có thể truy cập vào dữ liệu riêng tư của ứng dụng.
Để chia sẻ tệp với các ứng dụng khác, hãy dùng một trình cung cấp nội dung.
Thay đổi về khả năng kết nối
Đếm dữ liệu kết nối và nhiều đường dẫn
Trong các ứng dụng nhắm đến Android 9 trở lên, hệ thống sẽ tính lưu lượng truy cập mạng trên những mạng không phải là mạng mặc định hiện tại (chẳng hạn như lưu lượng truy cập di động trong khi thiết bị đang dùng Wi-Fi) và cung cấp các phương thức trong lớp NetworkStatsManager để truy vấn lưu lượng truy cập đó.
Cụ thể, getMultipathPreference() hiện trả về một giá trị dựa trên lưu lượng truy cập mạng nêu trên. Bắt đầu từ Android 9, phương thức này sẽ trả về true cho dữ liệu di động, nhưng khi lưu lượng truy cập tích luỹ trong một ngày vượt quá một mức nhất định, phương thức này sẽ bắt đầu trả về false. Các ứng dụng chạy trên Android 9 phải gọi phương thức này và tuân thủ gợi ý này.
Lớp ConnectivityManager.NetworkCallback
hiện gửi thông tin về VPN đến các ứng dụng. Thay đổi này giúp các ứng dụng dễ dàng theo dõi các sự kiện kết nối mà không cần kết hợp các lệnh gọi đồng bộ và không đồng bộ, đồng thời sử dụng các API có giới hạn. Ngoài ra, điều này có nghĩa là việc truyền thông tin sẽ diễn ra như mong đợi khi một thiết bị kết nối đồng thời với nhiều mạng Wi-Fi hoặc nhiều mạng di động.
Ngừng sử dụng ứng dụng HTTP Apache
Với Android 6.0, chúng tôi đã ngừng hỗ trợ ứng dụng HTTP Apache. Kể từ Android 9, thư viện đó sẽ bị xoá khỏi bootclasspath và không có sẵn cho các ứng dụng theo mặc định.
Để tiếp tục sử dụng ứng dụng Apache HTTP, những ứng dụng nhắm đến Android 9 trở lên có thể thêm nội dung sau vào AndroidManifest.xml:
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
Thay vì sử dụng thư viện Apache thời gian chạy, các ứng dụng có thể gói phiên bản org.apache.http của riêng mình trong APK. Nếu làm như vậy, bạn phải đóng gói lại thư viện (bằng một tiện ích như Jar Jar) để tránh các vấn đề về khả năng tương thích của lớp với các lớp được cung cấp trong thời gian chạy.
Thay đổi về giao diện người dùng
Chế độ xem tập trung
Các khung hiển thị có diện tích bằng 0 (chiều rộng hoặc chiều cao bằng 0) sẽ không còn lấy được tiêu điểm nữa.
Ngoài ra, các hoạt động không còn ngầm gán tiêu điểm ban đầu ở chế độ cảm ứng nữa. Thay vào đó, bạn phải yêu cầu rõ tiêu điểm ban đầu nếu muốn.
Xử lý giá trị mã hex RGBA của CSS
Những ứng dụng nhắm đến Android 9 trở lên phải bật hành vi CSS Color Module Level 4 (Mô-đun màu CSS cấp 4) bản nháp để xử lý màu CSS gồm 4 và 8 chữ số thập lục phân.
Chrome đã hỗ trợ CSS Color Module Level 4 kể từ phiên bản 52, nhưng WebView hiện vô hiệu hoá tính năng này vì các ứng dụng Android hiện có được phát hiện có chứa màu thập lục phân 32 bit theo thứ tự Android (ARGB), điều này sẽ gây ra lỗi kết xuất.
Ví dụ: màu #80ff8080 hiện được kết xuất trong WebView dưới dạng màu đỏ nhạt đục (#ff8080) cho các ứng dụng nhắm đến API cấp 27 trở xuống. Thành phần hàng đầu (sẽ được Android diễn giải là thành phần alpha) hiện bị bỏ qua. Nếu một ứng dụng nhắm đến API cấp 28 trở lên, #80ff8080 sẽ được diễn giải là màu xanh lục nhạt trong suốt 50% (#80ff80).
Tính năng phát hiện loại MIME cho tệp: URI
Các phiên bản Android cũ hơn Android 9 có thể suy luận các loại MIME từ nội dung tệp. Kể từ Android 9 (API cấp 28), các ứng dụng phải sử dụng đuôi tệp chính xác khi tải URI file: trong WebView.
Việc sử dụng nội dung tệp để suy luận các loại MIME có thể là nguồn gốc của các lỗi bảo mật và các trình duyệt hiện đại thường không cho phép điều này.
Nếu một tệp có đuôi tệp được nhận dạng, chẳng hạn như .html, .txt, .js hoặc .css, thì loại MIME sẽ được xác định theo đuôi tệp.
Nếu một tệp không có đuôi hoặc có đuôi không xác định, thì loại MIME sẽ là văn bản thuần tuý.
Ví dụ: một URI như file:///sdcard/test.html sẽ được hiển thị dưới dạng HTML, nhưng một URI như file:///sdcard/test sẽ hiển thị dưới dạng văn bản thuần tuý, ngay cả khi tệp chứa dữ liệu HTML.
Phần tử cuộn tài liệu
Android 9 xử lý đúng trường hợp trong đó phần tử gốc của tài liệu là phần tử cuộn. Trên các phiên bản trước, vị trí di chuyển được đặt trên phần tử nội dung và phần tử gốc có giá trị di chuyển bằng 0. Android 9 cho phép hành vi tuân thủ tiêu chuẩn, trong đó phần tử cuộn là phần tử gốc.
Ngoài ra, việc truy cập trực tiếp vào document.body.scrollTop, document.body.scrollLeft, document.documentElement.scrollTop hoặc document.documentElement.scrollLeft sẽ có hành vi khác nhau tuỳ thuộc vào SDK mục tiêu. Để truy cập vào các giá trị cuộn khung nhìn, hãy dùng document.scrollingElement (nếu có).
Thông báo của các ứng dụng bị tạm ngưng
Trước Android 9, thông báo của các ứng dụng bị tạm ngưng sẽ bị huỷ. Kể từ Android 9, thông báo của các ứng dụng bị tạm ngưng sẽ bị ẩn cho đến khi ứng dụng được tiếp tục chạy.