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

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 áp dụng cho tất cả ứng dụng khi chạy trên nền tảng Android 9, bất kể cấp độ API mà ứng dụng nhắm đến. Tất cả nhà phát triển đều nên xem xét những thay đổi này và sửa đổi ứng dụng để hỗ trợ chúng cho phù hợp (nếu ứng dụng có áp dụng).

Đối với những thay đổi chỉ ảnh hưởng đến các ứng dụng nhắm đến API cấp 28 trở lên, hãy xem phần Thay đổi về hành vi: ứng dụng nhắm đến API cấp 28 trở lên.

Quản lý nguồn

Android 9 ra mắt các tính năng mới để cải thiện khả năng quản lý nguồn điện của thiết bị. Những thay đổi này, cùng với các tính năng đã có trước Android 9, giúp đảm bảo rằng tài nguyên hệ thống được cung cấp cho những ứng dụng cần tài nguyên nhất.

Để biết thông tin chi tiết, hãy xem phần Quản lý nguồn.

Thay đổi về quyền riêng tư

Để tăng cường quyền riêng tư của người dùng, Android 9 giới thiệu một số thay đổi về hành vi, chẳng hạn như giới hạn quyền truy cập của ứng dụng ở chế độ nền vào cảm biến thiết bị, hạn chế thông tin được truy xuất từ hoạt động quét Wi-Fi, cũng như các quy tắc và nhóm quyền mới liên quan đến cuộc gọi điện thoại, trạng thái điện thoại và hoạt động quét Wi-Fi.

Những thay đổi này ảnh hưởng đến tất cả ứng dụng chạy trên Android 9, bất kể phiên bản SDK mục tiêu.

Hạn chế quyền truy cập vào cảm biến ở chế độ nền

Android 9 giới hạn khả năng ứng dụng ở chế độ nền truy cập vào dữ liệu cảm biến và hoạt động đầu vào của người dùng. Nếu ứng dụng của bạn đang chạy ở chế độ nền trên một thiết bị chạy Android 9, thì hệ thống sẽ áp dụng các hạn chế sau đây cho ứng dụng:

  • Ứng dụng của bạn không thể truy cập vào micrô hoặc máy ảnh.
  • Các cảm biến sử dụng chế độ báo cáo liên tục, chẳng hạn như gia tốc kế và con quay hồi chuyển, sẽ không nhận được sự kiện.
  • Các cảm biến sử dụng chế độ báo cáo khi thay đổi hoặc một lần sẽ không nhận được sự kiện.

Nếu ứng dụng của bạn cần phát hiện sự kiện cảm biến trên các thiết bị chạy Android 9, hãy sử dụng dịch vụ trên nền trước.

Hạn chế quyền truy cập vào nhật ký cuộc gọi

Android 9 giới thiệu nhóm quyền CALL_LOG và di chuyển các quyền READ_CALL_LOG, WRITE_CALL_LOGPROCESS_OUTGOING_CALLS vào nhóm này. Trong các phiên bản Android trước, các quyền này nằm trong nhóm quyền PHONE.

Nhóm quyền CALL_LOG này giúp người dùng kiểm soát và nắm được thông tin tốt hơn về các ứng dụng cần quyền truy cập vào thông tin nhạy cảm về cuộc gọi điện thoại, chẳng hạn như đọc bản ghi cuộc gọi điện thoại và xác định số điện thoại.

Nếu ứng dụng của bạn yêu cầu quyền truy cập vào nhật ký cuộc gọi hoặc cần xử lý cuộc gọi đi, thì bạn phải yêu cầu các quyền này một cách rõ ràng từ nhóm quyền CALL_LOG. Nếu không, SecurityException sẽ xảy ra.

Lưu ý: Do các quyền này đã thay đổi nhóm và được cấp trong thời gian chạy, nên người dùng có thể từ chối cấp cho ứng dụng của bạn quyền truy cập vào thông tin nhật ký cuộc gọi điện thoại. Trong trường hợp này, ứng dụng của bạn có thể xử lý tình trạng không truy cập được thông tin một cách linh hoạt.

Nếu ứng dụng của bạn đang tuân theo các phương pháp hay nhất về quyền khi bắt đầu chạy, thì ứng dụng có thể xử lý thay đổi trong nhóm quyền.

Hạn chế quyền truy cập vào số điện thoại

Các ứng dụng chạy trên Android 9 không thể đọc số điện thoại hoặc trạng thái điện thoại nếu không có quyền READ_CALL_LOG, ngoài các quyền khác mà trường hợp sử dụng của ứng dụng yêu cầu.

Số điện thoại liên kết với cuộc gọi đến và đi sẽ xuất hiện trong thông báo truyền trạng thái điện thoại, chẳng hạn như đối với cuộc gọi đến và đi, đồng thời có thể truy cập được từ lớp PhoneStateListener. Tuy nhiên, nếu không có quyền READ_CALL_LOG, trường số điện thoại được cung cấp trong thông báo truyền tin PHONE_STATE_CHANGED và thông qua PhoneStateListener sẽ trống.

Để đọc số điện thoại từ trạng thái điện thoại, hãy cập nhật ứng dụng của bạn để yêu cầu các quyền cần thiết dựa trên trường hợp sử dụng:

Hạn chế quyền truy cập vào thông tin vị trí và kết nối Wi-Fi

Trong Android 9, các yêu cầu về quyền để ứng dụng quét Wi-Fi nghiêm ngặt hơn so với các phiên bản trước. Để biết thông tin chi tiết, hãy xem phần Hạn chế quét Wi-Fi.

Các quy định hạn chế tương tự cũng áp dụng cho phương thức getConnectionInfo(). Phương thức này sẽ trả về một đối tượng WifiInfo mô tả kết nối Wi-Fi hiện tại. Bạn chỉ có thể sử dụng các phương thức của đối tượng này để truy xuất giá trị SSID và BSSID nếu ứng dụng gọi có các quyền sau:

  • ACCESS_FINE_LOCATION hoặc ACCESS_COARSE_LOCATION
  • ACCESS_WIFI_STATE

Để truy xuất SSID hoặc BSSID, bạn cũng cần bật dịch vụ vị trí trên thiết bị (trong phần Cài đặt > Vị trí).

Thông tin đã bị xoá khỏi các phương thức dịch vụ Wi-Fi

Trong Android 9, các sự kiện và thông báo truyền tin sau đây không nhận được thông tin về vị trí hoặc dữ liệu nhận dạng cá nhân của người dùng:

Thông báo truyền tin hệ thống NETWORK_STATE_CHANGED_ACTION qua Wi-Fi không còn chứa SSID (trước đây là EXTRA_SSID), BSSID (trước đây là EXTRA_BSSID) hoặc thông tin kết nối (trước đây là EXTRA_NETWORK_INFO). Nếu ứng dụng của bạn cần thông tin này, hãy gọi getConnectionInfo().

Thông tin về điện thoại hiện dựa vào chế độ cài đặt vị trí của thiết bị

Nếu người dùng đã tắt vị trí thiết bị trên một thiết bị chạy Android 9, thì các phương thức sau đây sẽ không cung cấp kết quả:

Các hạn chế về việc sử dụng giao diện không phải SDK

Để giúp đảm bảo tính ổn định và khả năng tương thích của ứng dụng, nền tảng này hạn chế việc sử dụng một số phương thức và trường không phải SDK; các hạn chế này áp dụng cho dù bạn cố gắng truy cập trực tiếp vào các phương thức và trường này, thông qua phản chiếu hay sử dụng JNI. Trong Android 9, ứng dụng của bạn có thể tiếp tục truy cập vào các giao diện bị hạn chế này; nền tảng sẽ sử dụng thông báo ngắn và mục nhập nhật ký để bạn chú ý. Nếu ứng dụng của bạn hiển thị thông báo ngắn như vậy, điều quan trọng là bạn phải theo đuổi một chiến lược triển khai khác với giao diện bị hạn chế. Nếu cảm thấy không có chiến lược thay thế nào khả thi, bạn có thể gửi báo cáo lỗi để yêu cầu xem xét lại quy định hạn chế.

Bài viết Các hạn chế đối với giao diện không phải SDK cung cấp thêm thông tin quan trọng. Bạn nên xem lại để đảm bảo ứng dụng của mình tiếp tục hoạt động đúng cách.

Thay đổi về hành vi bảo mật

Thay đổi về bảo mật thiết bị

Android 9 bổ sung một số tính năng giúp cải thiện tính bảo mật của ứng dụng, bất kể ứng dụng của bạn nhắm đến phiên bản nào.

Thay đổi về việc triển khai TLS

Việc triển khai TLS của hệ thống đã trải qua một số thay đổi trong Android 9:

  • Nếu một thực thể của SSLSocket không kết nối được trong khi đang được tạo, thì hệ thống sẽ gửi một IOException thay vì NullPointerException.
  • Lớp SSLEngine xử lý gọn gàng mọi cảnh báo close_notify xảy ra.

Để tìm hiểu thêm về cách tạo các yêu cầu web bảo mật trong ứng dụng Android, hãy xem Ví dụ về HTTPS.

Bộ lọc SECCOMP nghiêm ngặt hơn

Android 9 hạn chế thêm các lệnh gọi hệ thống mà ứng dụng có thể sử dụng. Hành vi này là một phần mở rộng của bộ lọc SECCOMP có trong Android 8.0 (API cấp 26).

Thay đổi về mật mã

Android 9 giới thiệu một số thay đổi đối với việc triển khai và xử lý các thuật toán mật mã.

Các phương thức triển khai thông số và thuật toán của Conscrypt

Android 9 cung cấp các phương thức triển khai bổ sung của các tham số thuật toán trong Conscrypt. Các tham số này bao gồm: AES, DESEDE, OAEP và EC. Các phiên bản Bouncy Castle của các tham số này và nhiều thuật toán đã ngừng hoạt động kể từ Android 9.

Nếu ứng dụng của bạn nhắm đến Android 8.1 (API cấp 27) trở xuống, bạn sẽ nhận được cảnh báo khi yêu cầu triển khai Bouncy Castle của một trong những thuật toán không dùng nữa này. Tuy nhiên, nếu bạn nhắm đến Android 9, thì mỗi yêu cầu này sẽ gửi một NoSuchAlgorithmException.

Các thay đổi khác

Android 9 giới thiệu một số thay đổi khác liên quan đến mật mã:

  • Khi sử dụng khoá PBE, nếu Bouncy Castle đang chờ một vectơ khởi chạy (IV) và ứng dụng của bạn không cung cấp vectơ đó, bạn sẽ nhận được cảnh báo.
  • Việc triển khai thuật toán mã hoá ARC4 của Conscrypt cho phép bạn chỉ định ARC4/ECB/NoPadding hoặc ARC4/NONE/NoPadding.
  • Nhà cung cấp Kiến trúc mã hoá Java (JCA) đã bị xoá. Do đó, nếu ứng dụng của bạn gọi SecureRandom.getInstance("SHA1PRNG", "Crypto"), thì NoSuchProviderException sẽ xảy ra.
  • Nếu ứng dụng của bạn phân tích cú pháp các khoá RSA từ các vùng đệm lớn hơn cấu trúc khoá, thì ngoại lệ sẽ không còn xảy ra.

Để tìm hiểu thêm về cách sử dụng các tính năng mã hoá của Android, hãy xem phần Mã hoá.

Không còn hỗ trợ tệp đã mã hoá bảo mật của Android

Android 9 xoá hoàn toàn tính năng hỗ trợ cho các tệp được mã hoá bảo mật của Android (ASEC).

Trong Android 2.2 (API cấp 8), Android đã giới thiệu ASEC để hỗ trợ chức năng ứng dụng trên thẻ SD. Trên Android 6.0 (API cấp 23), nền tảng này đã ra mắt công nghệ thiết bị lưu trữ có thể sử dụng mà nhà phát triển có thể sử dụng thay cho ASEC.

Nội dung cập nhật cho thư viện ICU

Android 9 sử dụng phiên bản 60 của thư viện ICU. Android 8.0 (API cấp 26) và Android 8.1 (API cấp 27) sử dụng ICU 58.

ICU được dùng để cung cấp các API công khai bên dưới android.icu package và được dùng nội bộ trong nền tảng Android để hỗ trợ quốc tế hoá. Ví dụ: lớp này được dùng để triển khai các lớp Android trong java.util, java.textandroid.text.format.

Bản cập nhật ICU 60 có nhiều thay đổi nhỏ nhưng hữu ích, bao gồm cả tính năng hỗ trợ dữ liệu Emoji 5.0 và cải thiện định dạng ngày/giờ, như được ghi nhận trong ghi chú phát hành ICU 59 và ICU 60.

Những thay đổi đáng chú ý trong bản cập nhật này:

  • Cách nền tảng xử lý múi giờ đã thay đổi.
    • Nền tảng này xử lý GMT và UTC tốt hơn; UTC không còn đồng nghĩa với GMT.

      ICU hiện cung cấp tên múi giờ đã dịch cho GMT và UTC. Thay đổi này ảnh hưởng đến hành vi định dạng và phân tích cú pháp android.icu cho các múi giờ như "GMT", "Etc/GMT", "UTC", "Etc/UTC" và "Zulu".

    • java.text.SimpleDateFormat hiện sử dụng ICU để cung cấp tên hiển thị cho UTC /GMT, nghĩa là:
      • Việc định dạng zzzz sẽ tạo ra một chuỗi dài được bản địa hoá cho nhiều ngôn ngữ. Trước đây, hàm này tạo ra "UTC" cho UTC và các chuỗi như "GMT+00:00" cho GMT.
      • Việc phân tích cú pháp zzzz sẽ nhận ra các chuỗi như "Giờ phối hợp quốc tế" và "Giờ chuẩn Greenwich".
      • Ứng dụng có thể gặp vấn đề về khả năng tương thích nếu giả định rằng "UTC" hoặc "GMT+00:00" là đầu ra cho zzzz ở tất cả ngôn ngữ.
    • Hành vi của java.text.DateFormatSymbols.getZoneStrings() đã thay đổi:
      • Cũng như SimpleDateFormat, giờ UTC và GMT hiện có tên dài. Các biến thể DST của tên múi giờ cho múi giờ UTC, chẳng hạn như "UTC", "Etc/UTC" và "Zulu", sẽ trở thành GMT+00:00, đây là phương án dự phòng chuẩn khi không có tên nào, thay vì chuỗi UTC được mã hoá cứng.
      • Một số mã vùng được nhận dạng chính xác là từ đồng nghĩa cho các vùng khác, nhờ đó Android tìm thấy các chuỗi cho các mã vùng cũ, chẳng hạn như Eire, trước đây không thể phân giải được.
    • Vùng Asia/Hanoi không còn được công nhận nữa. Vì lý do này, java.util.TimeZones.getAvailableIds() không trả về giá trị này và java.util.TimeZone.getTimeZone() không nhận dạng được giá trị này. Hành vi này nhất quán với hành vi android.icu hiện có.
  • Phương thức android.icu.text.NumberFormat.getInstance(ULocale, PLURALCURRENCYSTYLE).parse(String) có thể gửi một ParseException ngay cả khi phân tích cú pháp văn bản tiền tệ hợp lệ. Hãy tránh vấn đề này bằng cách sử dụng NumberFormat.parseCurrency (có sẵn từ Android 7.0 (API cấp 24)) cho văn bản đơn vị tiền tệ kiểu PLURALCURRENCYSTYLE.

Các thay đổi về Kiểm thử Android

Android 9 giới thiệu một số thay đổi đối với thư viện và cấu trúc lớp của khung Kiểm thử Android. Những thay đổi này giúp nhà phát triển sử dụng các API công khai, được hỗ trợ khung, nhưng các thay đổi này cũng cho phép linh hoạt hơn trong việc xây dựng và chạy kiểm thử bằng cách sử dụng thư viện của bên thứ ba hoặc logic tuỳ chỉnh.

Xoá thư viện khỏi khung

Android 9 sắp xếp lại các lớp dựa trên JUnit thành ba thư viện: android.test.base, android.test.runnerandroid.test.mock. Thay đổi này cho phép bạn chạy kiểm thử dựa trên phiên bản JUnit hoạt động tốt nhất với các phần phụ thuộc của dự án. Phiên bản JUnit này có thể khác với phiên bản mà android.jar cung cấp.

Để tìm hiểu thêm về cách các lớp dựa trên JUnit được sắp xếp vào các thư viện này, cũng như cách chuẩn bị dự án của ứng dụng để viết và chạy kiểm thử, hãy xem phần Thiết lập dự án cho Kiểm thử Android.

Thay đổi bản dựng bộ kiểm thử

Phương thức addRequirements() trong lớp TestSuiteBuilder đã bị xoá và chính lớp TestSuiteBuilder cũng không còn được dùng nữa. Phương thức addRequirements() yêu cầu nhà phát triển cung cấp các đối số có loại là API ẩn, khiến API không hợp lệ.

Bộ giải mã UTF Java

UTF-8 là bộ ký tự mặc định trong Android. Một trình tự byte UTF-8 có thể được giải mã bằng hàm khởi tạo String, chẳng hạn như String(byte[] bytes).

Bộ giải mã UTF-8 trong Android 9 tuân thủ các tiêu chuẩn Unicode nghiêm ngặt hơn so với các phiên bản trước. Những thay đổi bao gồm:

  • Biểu thức UTF-8 không ngắn nhất, chẳng hạn như <C0, AF>, được coi là không đúng định dạng.
  • Biểu mẫu thay thế của UTF-8, chẳng hạn như U+D800..U+DFFF, được coi là không đúng định dạng.
  • Phần phụ tối đa được thay thế bằng một U+FFFD duy nhất. Ví dụ: trong trình tự byte "41 C0 AF 41 F4 80 80 41", các phần phụ tối đa là "C0", "AF" và "F4 80 80". "F4 80 80" có thể là trình tự con ban đầu của "F4 80 80 80", nhưng "C0" không thể là trình tự con ban đầu của bất kỳ trình tự đơn vị mã nào được định dạng đúng cách. Do đó, kết quả sẽ là "A\ufffd\ufffdA\ufffdA".
  • Để giải mã một trình tự UTF-8 / CESU-8 đã sửa đổi trong Android 9 trở lên, hãy sử dụng phương thức DataInputStream.readUTF() hoặc phương thức JNI NewStringUTF().

Xác minh tên máy chủ bằng chứng chỉ

RFC 2818 mô tả hai phương thức để so khớp tên miền với chứng chỉ – sử dụng các tên có sẵn trong tiện ích subjectAltName (SAN) hoặc trong trường hợp không có tiện ích SAN, hãy quay lại commonName (CN).

Tuy nhiên, tính năng dự phòng cho CN đã ngừng hoạt động trong RFC 2818. Vì lý do này, Android không còn sử dụng lại CN nữa. Để xác minh tên máy chủ, máy chủ phải cung cấp một chứng chỉ có SAN khớp. Các chứng chỉ không chứa SAN khớp với tên máy chủ sẽ không còn được tin cậy.

Việc tra cứu địa chỉ mạng có thể gây ra lỗi vi phạm mạng

Các thao tác tra cứu địa chỉ mạng yêu cầu phân giải tên có thể liên quan đến I/O mạng và do đó được coi là các thao tác chặn. Việc chặn các thao tác trên luồng chính có thể gây ra tình trạng tạm dừng hoặc giật.

Lớp StrictMode là một công cụ phát triển giúp nhà phát triển phát hiện vấn đề trong mã của họ.

Trong Android 9 trở lên, StrictMode phát hiện các lỗi vi phạm mạng do các lượt tra cứu địa chỉ mạng yêu cầu phân giải tên.

Bạn không nên phân phối ứng dụng khi bật StrictMode. Nếu bạn làm như vậy, ứng dụng của bạn có thể gặp phải các trường hợp ngoại lệ, chẳng hạn như NetworkOnMainThreadException khi sử dụng phương thức detectNetwork() hoặc detectAll() để nhận chính sách phát hiện lỗi vi phạm mạng.

Việc phân giải địa chỉ IP dạng số không được coi là thao tác chặn. Độ phân giải địa chỉ IP số hoạt động giống như trong các phiên bản trước Android 9.

Gắn thẻ ổ cắm

Trong các phiên bản nền tảng thấp hơn Android 9, nếu một ổ cắm được gắn thẻ bằng phương thức setThreadStatsTag(), thì ổ cắm đó sẽ bị bỏ gắn thẻ khi được gửi đến một quy trình khác bằng binder IPC với vùng chứa ParcelFileDescriptor.

Trong Android 9 trở lên, thẻ ổ cắm được giữ lại khi được gửi đến một quy trình khác bằng cách sử dụng liên kết IPC. Thay đổi này có thể ảnh hưởng đến số liệu thống kê về lưu lượng truy cập mạng, ví dụ: khi sử dụng phương thức queryDetailsForUidTag().

Nếu muốn giữ lại hành vi của các phiên bản trước (gỡ thẻ một ổ cắm được gửi đến một quy trình khác), bạn có thể gọi untagSocket() trước khi gửi ổ cắm.

Số byte có sẵn được báo cáo trong ổ cắm

Phương thức available() trả về 0 khi được gọi sau khi gọi phương thức shutdownInput().

Báo cáo chi tiết hơn về các chức năng mạng cho VPN

Trên Android 8.1 (API cấp 27) trở xuống, lớp NetworkCapabilities chỉ báo cáo một tập hợp thông tin hạn chế cho VPN, chẳng hạn như TRANSPORT_VPN, nhưng bỏ qua NET_CAPABILITY_NOT_VPN. Thông tin hạn chế này khiến chúng tôi khó xác định liệu việc sử dụng VPN có khiến người dùng ứng dụng phải trả phí hay không. Ví dụ: việc kiểm tra NET_CAPABILITY_NOT_METERED sẽ không xác định được liệu các mạng cơ bản có được đo lượng dữ liệu hay không.

Trong Android 9 trở lên, khi VPN gọi phương thức setUnderlyingNetworks(), hệ thống Android sẽ hợp nhất các phương thức truyền tải và chức năng của mọi mạng cơ bản và trả về kết quả dưới dạng chức năng mạng hiệu quả của mạng VPN.

Trên Android 9 trở lên, các ứng dụng đã kiểm tra NET_CAPABILITY_NOT_METERED sẽ nhận được các chức năng mạng của VPN và các mạng cơ bản.

Các tệp trong thư mục xt_qtaguid không còn được cung cấp cho ứng dụng nữa

Kể từ Android 9, các ứng dụng không được phép có quyền đọc trực tiếp vào các tệp trong thư mục /proc/net/xt_qtaguid. Lý do là để đảm bảo tính nhất quán với một số thiết bị hoàn toàn không có các tệp này.

Các API công khai dựa vào các tệp này, TrafficStatsNetworkStatsManager, sẽ tiếp tục hoạt động như dự kiến. Tuy nhiên, các hàm cutils không được hỗ trợ, chẳng hạn như qtaguid_tagSocket(), có thể không hoạt động như mong đợi hoặc không hoạt động trên các thiết bị khác nhau.

Hiện đã thực thi yêu cầu FLAG_ACTIVITY_NEW_TASK

Với Android 9, bạn không thể bắt đầu một hoạt động từ bối cảnh không phải hoạt động trừ phi bạn truyền cờ ý định FLAG_ACTIVITY_NEW_TASK. Nếu bạn cố gắng bắt đầu một hoạt động mà không truyền cờ này, thì hoạt động sẽ không bắt đầu và hệ thống sẽ in một thông báo vào nhật ký.

Thay đổi về chế độ xoay màn hình

Kể từ Android 9, chế độ xoay dọc có những thay đổi đáng kể. Trong Android 8.0 (API cấp 26), người dùng có thể bật/tắt giữa chế độ xoay tự độngdọc bằng cách sử dụng thẻ cài đặt Quicksettings hoặc Display (Cài đặt màn hình). Chế độ dọc đã được đổi tên thành khoá xoay và chế độ này sẽ hoạt động khi bạn tắt tính năng tự động xoay. Không có thay đổi nào đối với chế độ tự động xoay.

Khi thiết bị ở chế độ khoá xoay, người dùng có thể khoá màn hình theo bất kỳ chế độ xoay nào được Hoạt động hiển thị ở trên cùng hỗ trợ. Hoạt động không được giả định rằng hoạt động đó sẽ luôn được kết xuất theo hướng dọc. Nếu Hoạt động trên cùng có thể hiển thị ở nhiều chế độ xoay trong chế độ tự động xoay, thì các tuỳ chọn tương tự cũng sẽ có trong chế độ khoá xoay, ngoại trừ một số trường hợp ngoại lệ dựa trên chế độ cài đặt screenOrientation của Hoạt động (xem bảng bên dưới).

Các hoạt động yêu cầu hướng cụ thể (ví dụ: screenOrientation=landscape) sẽ bỏ qua lựa chọn ưu tiên về khoá của người dùng và hoạt động giống như trong Android 8.0.

Bạn có thể đặt tuỳ chọn hướng màn hình ở cấp Hoạt động trong Tệp kê khai Android hoặc theo phương thức lập trình bằng setRequestedOrientation().

Chế độ khoá xoay hoạt động bằng cách đặt lựa chọn ưu tiên xoay của người dùng mà WindowManager sử dụng khi xử lý hoạt động xoay. Lựa chọn ưu tiên xoay của người dùng có thể thay đổi trong các trường hợp sau. Xin lưu ý rằng có một độ lệch để quay lại chế độ xoay tự nhiên của thiết bị, thường là hướng dọc đối với các thiết bị có kiểu dáng điện thoại:

  • Khi người dùng chấp nhận một đề xuất xoay, lựa chọn ưu tiên về chế độ xoay sẽ thay đổi thành đề xuất đó.
  • Khi người dùng chuyển sang một ứng dụng buộc phải ở chế độ dọc (bao gồm cả màn hình khoá hoặc trình chạy), lựa chọn ưu tiên về chế độ xoay sẽ thay đổi thành dọc.

Bảng sau đây tóm tắt hành vi xoay cho các hướng màn hình phổ biến:

Hướng màn hình Hành vi
chưa chỉ định, người dùng Trong chế độ tự động xoay và khoá xoay, Hoạt động có thể được kết xuất theo hướng dọc hoặc ngang (và ngược lại). Dự kiến sẽ hỗ trợ cả bố cục dọc và ngang.
userLandscape Trong chế độ tự động xoay và khoá xoay, Hoạt động có thể được kết xuất theo hướng ngang hoặc ngược hướng ngang. Dự kiến sẽ chỉ hỗ trợ bố cục ngang.
userPortrait Trong chế độ tự động xoay và khoá xoay, Hoạt động có thể được kết xuất theo hướng dọc hoặc ngược chiều dọc. Dự kiến sẽ chỉ hỗ trợ bố cục dọc.
fullUser Trong chế độ tự động xoay và khoá xoay, Hoạt động có thể được kết xuất theo hướng dọc hoặc ngang (và ngược lại). Dự kiến sẽ hỗ trợ cả bố cục dọc và ngang.

Người dùng chế độ khoá xoay sẽ có lựa chọn khoá thành chế độ dọc đảo ngược, thường là 180º.
cảm biến, cảm biến toàn cảnh, cảm biến dọc, cảm biến ngang Lựa chọn ưu tiên về chế độ khoá xoay bị bỏ qua và được coi như chế độ tự động xoay đang hoạt động. Chỉ sử dụng tính năng này trong các trường hợp ngoại lệ và cân nhắc kỹ lưỡng về trải nghiệm người dùng.

Việc ngừng sử dụng ứng dụng khách Apache HTTP ảnh hưởng đến các ứng dụng có ClassLoader không chuẩn

Với Android 6.0, chúng tôi đã ngừng hỗ trợ ứng dụng khách HTTP Apache. Thay đổi này không ảnh hưởng đến phần lớn ứng dụng không nhắm đến Android 9 trở lên. Tuy nhiên, thay đổi này có thể ảnh hưởng đến một số ứng dụng sử dụng cấu trúc ClassLoader không chuẩn, ngay cả khi các ứng dụng đó không nhắm đến Android 9 trở lên.

Ứng dụng có thể bị ảnh hưởng nếu sử dụng ClassLoader không chuẩn, uỷ quyền rõ ràng cho ClassLoader hệ thống. Thay vào đó, các ứng dụng này cần uỷ quyền cho ứng dụng ClassLoader khi tìm kiếm các lớp trong org.apache.http.*. Nếu các lớp này uỷ quyền cho ClassLoader của hệ thống, thì các ứng dụng sẽ không hoạt động trên Android 9 trở lên với NoClassDefFoundError, vì ClassLoader của hệ thống không còn biết các lớp đó nữa. Để ngăn chặn các vấn đề tương tự trong tương lai, nói chung, các ứng dụng nên tải các lớp thông qua ClassLoader của ứng dụng thay vì truy cập trực tiếp vào ClassLoader của hệ thống.

Liệt kê máy ảnh

Các ứng dụng chạy trên thiết bị Android 9 có thể khám phá mọi máy ảnh có sẵn bằng cách gọi getCameraIdList(). Ứng dụng không được giả định rằng thiết bị chỉ có một camera sau hoặc chỉ có một camera trước.

Ví dụ: nếu ứng dụng của bạn có nút để chuyển đổi giữa camera trước và sau, thì có thể có nhiều camera trước hoặc sau để bạn chọn. Bạn nên duyệt qua danh sách máy ảnh, kiểm tra đặc điểm của từng máy ảnh và quyết định máy ảnh nào sẽ hiển thị cho người dùng.