Behavior changes: apps targeting API level 28+

Mở đầu

Như mọi người đã biết, android đã và đang đưa ra những phiên bản mới nhằm phát triển thêm và khắc phục những vấn đề còn tồn đọng của các phiên bản trước. Đứng trên góc độ của người phát triển, chúng ta cần nắm được những thay đổi ở các phiên bản để kịp thời đưa ra những action đến app của mình để thích nghi với nó. Như công ty khách hàng của mình cũng không ngoại lệ, vì gần đây mình được giao task migrate app lên target sdk 28 nên cũng có cơ hội được tìm hiểu và điều tra về chủ đề này. Do đó, nhân dịp này, mình sẽ giới thiệu đến mọi người chủ đề : “những thay đổi về hành vi được áp dụng cho các application có target API 28 hoặc cao hơn” trong phạm vi mình đã điều tra tìm hiểu . Ok, bắt đầu thôi!!!

Foreground services

Vấn đề :
Các ứng dụng có target Android 9 trở lên và đang sử dụng các foreground service thì từ giờ cần phải có quyền FOREGROUND_SERVICE. Đây là normal permission nên bạn chỉ cần đăng ký nó trong manifest là được :D, và sau đó hệ thống sẽ tự động cấp permission cho ứng dụng yêu cầu.
Nếu một ứng dụng có target Android 9 trở lên, khi không có permission FOREGROUND_SERVICE mà cố gắng tạo foreground service sẽ bị ném ra 1 ngoại lệ SecurityException.
Cách giải quyết:
Đăng ký permission trong FOREGROUND_SERVICE

Privacy changes

Vấn đề 1 : Build serial number deprecation
Ở Android 9, khi gọi Build.SERIAL sẽ luôn trả về "UNKNOWN" .Điều này được thay đổi để bảo vệ quyền riêng tư của người dùng
Cách giải quyết:
Nếu ứng dụng của bạn cần truy cập số serial phần cứng của thiết bị thì bạn nên yêu cầu quyền READ_PHONE_STATE, và sau đó gọi hàm getSerial().

Vấn đề 2:DNS privacy
Android P hỗ trợ tích hợp DNS over TLS (DNS over TLS là một giao thức bảo mật buộc tất cả các kết nối với máy chủ DNS phải được thực hiện an toàn bằng TLS). Mặc định, các thiết bị sẽ tự động nâng cấp lên DNS over TLS nếu máy chủ DNS của mạng hỗ trợ. Tuy nhiên, nếu bạn không muốn sử dụng DNS over TLS, bạn có thể tắt nó bằng cách : Đi đến Settings → Network & internet → Advanced → Private DNS. Ngoài ra, bạn cũng có thể nhập tên máy chủ DNS nếu muốn sử dụng nhà cung cấp DNS riêng. Theo đó, Android sẽ gửi tất cả các truy vấn DNS qua một kênh bảo mật đến máy chủ này hoặc bị "No internet access" nếu không thể truy cập máy chủ.
Về cơ bản, đây là 1 feature mới từ android P giúp bảo mật hơn khi thực hiện các DNS queries thay vì chỉ được tạo bằng plaintext như trước đây

Framework security changes

Android 9 bao gồm một số thay đổi hành vi nhằm cải thiện bảo mật ứng dụng của bạn. Tất nhiên, những thay đổi này chỉ có hiệu lực nếu ứng dụng của bạn có target API level 28 trở lên. Cụ thể:
Vấn đề 1: Network TLS enabled by default
Nếu ứng dụng của bạn đang target Android 9 trở lên, phương thức isCleartextTrafficPermited() trả về false theo mặc định. Điều này có nghĩa là transmit data mà chưa được mã hoá sẽ không được cho phép. Đại loại, lúc này app của bạn có thể sẽ bắn ra 1 lỗi : “java.io.IOException: Cleartext HTTP traffic to http://example.com not permitted” .Điều này được thay đổi ở android P như là kết quả của mục tiêu cải thiện bảo mật. Khi app giao tiếp với server bằng cách sử dụng cleartext (như HTTP) sẽ làm tăng nguy cơ bị rò rỉ dữ liệu, các bên thứ ba có thể thêm bớt dữ liệu trái phép hoặc trích xuất thông tin của người dùng... Cơ bản, đây là một issue nguy hiểm và bạn cần phải giải quyết nếu muốn app hoạt động bình thường.
Cách giải quyết:
Cách 1: Thêm trực tiếp 1 dòng sau vào file manifest:

Dòng code này cho phép tất cả các connect từ phía client đến bất kỳ domain nào đều có thể được truyền theo kiểu cleartext (transmit data mà không được mã hoá).
Cách 2:
Tuy nhiên, trong trường hợp bạn muốn giới hạn phạm vi của cleartext cho 1 vài domain cụ thể bạn có thể tham khảo cách 2 này:
B1: tạo file network_security_config.xml trong res/xml
Nội dung của file này sẽ giống như sau:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">sample_domain.com</domain>
    </domain-config>
</network-security-config>

Đầu tiên, bạn cần set giá trị true cho cleartextTrafficPermitted . Tiếp theo, với những domain cụ thể mà bạn muốn sử dụng cleartext, bạn có thể cấu hình nó trong thẻ includeSubdomains
B2: Cấu hình file network_security_config.xml này vào manifest

Vấn đề 2: Web-based data directories separated by process
Ở Android 9, các ứng dụng sẽ không thể chia sẻ một WebView data directory giữa nhiều process.
Cách giải quyết
Thông thường, các dữ liệu này bao gồm cookie, HTTP caches và nhiều dữ liệu khác liên quan đến trình duyệt web. Theo như khuyến khích, bạn nên di chuyển tất cả các Activity mà sử dụng cùng 1 WebView vào cùng một process. Bạn có thể thực thi rule "only process only" bằng cách gọi hàm disableWebView () ở các quy trình khác trong ứng dụng. Điều này giúp ngăn không cho WebView khởi tạo trong các process khác, ngay cả khi nó được gọi từ trong library.
Tuy nhiên, Nếu ứng dụng của bạn buộc phải sử dụng một WebView trong nhiều process, bạn có thể tham khảo tại đây

Vấn đề 3: Per-app SELinux domains
Các ứng dụng có target Android 9 trở lên sẽ không thể chia sẻ dữ liệu với các ứng dụng khác bằng world-accessible Unix permissions. Thay đổi này nhằm cải thiện tính toàn vẹn của Android Application Sandbox. Dữ liệu private của ứng dụng thì chỉ có thể được truy cập được bởi ứng dụng đó.
Cách giải quyết
Sử dụng content provider để chia sẻ file với các ứng dụng khác

Connectivity changes

Vấn đề Apache HTTP client deprecation
Từ Android 6.0, Android đã xóa Apache HTTP client và bắt đầu với Android 9, thư viện này sẽ bị xóa khỏi boot classpath và mặc định sẽ không có sẵn cho các application
Cách giải quyết:
Để tiếp tục sử dụng Apache HTTP client, các ứng dụng có target Android 9 trở lên cần thêm các mục sau vào AndroidManifest.xml:

<used-library android: name = "org.apache.http.legacy" android: required = "false" />

Lưu ý: Thuộc tính android: required = "false" là bắt buộc đối với các ứng dụng có SDK tối thiểu 23 hoặc thấp hơn, bởi vì trên các thiết bị có mức API thấp hơn 24, thư viện org.apache.http.legacy không khả dụng. (Trên các thiết bị đó, các lớp Apache HTTP có sẵn trên bootgrouppath.)

UI changes

Vấn đề 1: View focus
Với những view mà có chiều rộng hay chiều dài bằng 0 sẽ không còn có thể focus được nữa. Thêm vào đó, các activities không còn có thể ngầm gán focus ban đầu trong touch-mode. Thay vào đó, bạn cần phải request khởi tạo focus ban đầu 1 cách rõ ràng nếu muốn.
Cách giải quyết
nếu với requirement là cần thiết, bạn cần request khởi tạo focus ban đầu 1 cách rõ ràng nếu muốn

Vấn đề 2: CSS RGBA hex value handling
Với những màu có 4 hay 8 chữ số hex, việc hiển thị có thể bị sai khác so với nguyên mẫu. Ví dụ: màu # 80ff8080 được hiển thị trong WebView dưới dạng màu đỏ nhạt (# ff8080) cho các ứng dụng có target API 27 hoặc thấp hơn( 2 số đầu sẽ được Android hiểu là thành phần alpha) .Tuy nhiên, với một ứng dụng target API level 28 trở lên, # 80ff8080 được hiểu là màu xanh nhạt trong suốt (# 80ff80) với thành phần alpha là 2 số cuối 80.
Cách giải quyết:
Các ứng dụng có target Android 9 trở lên phải kích hoạt draft CSS Color Module Level 4 behaviour để xử lý những màu có 4 và 8 chữ số hex. CSS Color Module Level 4 behaviour
đã được Chrome hỗ trợ kể từ khi bản release 52, nhưng WebView hiện vô hiệu hóa tính năng này.

Vấn đề 3: MIME type sniffing for file: URIs
Các phiên bản Android nhỏ hơn Android 9 có thể suy ra MIME type từ nội dung tệp. Tuy nhiên, bắt đầu với các ứng dụng Android 9 (API level 28) , để xác định được MIME type, ta phải sử dụng phần extension của tệp chính xác khi tải tệp. Lý do được đưa ra là bởi sử dụng nội dung tệp để suy ra các MIME type có thể là nguyên nhân gây ra lỗi bảo mật. Ở android api 28, Khi sử dụng webview để hiển thị 1 file, nếu file đó có phần extension được nhận dạng, chẳng hạn như .html, .txt, .js hoặc .css thì MIME type sẽ được xác định bởi extension. Trong khi đó, nếu một tệp không có phần extension hoặc không được nhận dạng, MIME type của file sẽ được hiểu là sẽ là plain text
Cách giải quyết:
cung cấp extension chính xác cho file

Vấn đề 4: Document scrolling element
Trên các phiên bản trước, vị trí scroll được set ở body element và root element có giá trị scroll bằng không. Còn ở Android 9 thì scrolling element là root element.
Về cơ bản đây là feature ở android 9 và không có ảnh hưởng gì lớn đến application

Vấn đề 5: Notifications from suspended apps
Trước Android 9, các thông báo từ những ứng dụng bị treo sẽ bị hủy. Nhưng với Android 9, các thông báo từ các ứng dụng bị treo sẽ bị ẩn đi cho đến khi ứng dụng được mở lại.
Và cũng như vấn đề trên, đây là 1 feature mới của Android 9, và không gây ảnh hưởng gì đến app. Bạn có thể tự test thử feature này bằng cách vào setting của app và chọn force close 😀

Trên đây là tất cả những gì minh đã tìm hiểu được trong quá trình migrate app sang target sdk 28 cho dự án của công ty khách hàng. Hẹn gặp lại mọi người ở những bài viết tiếp theo.

Tài liệu tham khảo :

https://developer.android.com/about/versions/pie/android-9.0-changes-28

Leave a Reply

Your email address will not be published. Required fields are marked *