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 sau đây về hành vi sẽ áp dụng cho tất cả ứng dụng khi chúng chạy trên nền tảng Android 9, bất kể cấp độ API mà các ứng dụng đó đang nhắm đến. Tất cả các nhà phát triển nên xem xét những thay đổi này và sửa đổi ứng dụng của họ để hỗ trợ chúng cho phù hợp (nếu phù hợp).
Đối với các thay đổi chỉ ảnh hưởng đến những ứ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 giới thiệu các tính năng mới để cải thiện việc 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 nhất.
Để biết thông tin chi tiết, hãy xem phần Quản lý nguồn.
Các thay đổi về quyền riêng tư
Để tăng cường bảo vệ quyền riêng tư của người dùng, Android 9 ra mắt một số thay đổi về hành vi, chẳng hạn như hạn chế 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 truy xuất từ tính năng quét tìm Wi-Fi, cũng như các quy tắc mới về quyền và nhóm quyền liên quan đến cuộc gọi điện thoại, trạng thái điện thoại và quét tìm Wi-Fi.
Những thay đổi này ảnh hưởng đến tất cả các ứng dụng chạy trên Android 9, bất kể phiên bản SDK mục tiêu.
Quyền truy cập hạn chế vào cảm biến ở chế độ nền
Android 9 giới hạn khả năng các ứ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 cho ứng dụng đó:
- Ứng dụng của bạn không thể truy cập vào micrô hoặc camera.
- 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, không nhận được sự kiện.
- Các cảm biến sử dụng chế độ báo cáo on-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 các sự kiện cảm biến trên thiết bị chạy Android 9, hãy sử dụng một 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
, đồng thời di chuyển các quyền READ_CALL_LOG
, WRITE_CALL_LOG
và PROCESS_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 cho phép người dùng kiểm soát và theo dõi tốt hơn đối với những ứ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à nhận dạng số điện thoại.
Nếu ứng dụng của bạn cần quyền truy cập vào nhật ký cuộc gọi hoặc cần xử lý các lệnh gọi đi, thì bạn phải yêu cầu rõ ràng các quyền này từ nhóm quyền CALL_LOG
. Nếu không, SecurityException
sẽ xảy ra.
Lưu ý: Vì những quyền này đã thay đổi các nhóm và được cấp trong thời gian chạy, nên có thể người dùng sẽ 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 phải có thể xử lý vấn đề thiếu quyền truy cập thông tin một cách linh hoạt.
Nếu đã làm theo các phương pháp hay nhất về quyền khi bắt đầu chạy, thì ứng dụng của bạn 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 sẽ không thể đọc số điện thoại hoặc trạng thái điện thoại nếu trước đó chưa có được quyền READ_CALL_LOG
, ngoài những quyền khác mà các 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 các cuộc gọi đến và đi sẽ hiển thị trong thông báo trạng thái điện thoại, chẳng hạn như các 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 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 để yêu cầu các quyền cần thiết dựa trên trường hợp sử dụng của bạn:
- Để đọc các số từ hành động theo ý định
PHONE_STATE
, bạn cần có cả quyềnREAD_CALL_LOG
và quyềnREAD_PHONE_STATE
. - Để đọc số từ
onCallStateChanged()
, bạn chỉ cần có quyềnREAD_CALL_LOG
. Bạn không cần quyềnREAD_PHONE_STATE
.
Hạn chế quyền truy cập vào thông tin vị trí và kết nối Wi-Fi
Trên Android 9, các yêu cầu về quyền để một ứng dụng quét tìm Wi-Fi sẽ 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 tìm Wi-Fi.
Các hạn chế tương tự cũng áp dụng cho phương thức getConnectionInfo()
. Phương thức này trả về đố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
Việc truy xuất SSID hoặc BSSID cũng yêu cầu bật dịch vụ vị trí trên thiết bị (trong phần Cài đặt > Vị trí).
Đã xoá thông tin 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 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:
- Các phương thức
getScanResults()
vàgetConnectionInfo()
từWifiManager
. - Phương thức
discoverServices()
vàaddServiceRequest()
từWifiP2pManager
. - Thông báo truyền tin
NETWORK_STATE_CHANGED_ACTION
.
Hệ thống NETWORK_STATE_CHANGED_ACTION
truyền tin từ 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 điện thoại hiện dựa trên 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 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 độ ổn định và khả năng tương thích của ứng dụng, nền tảng sẽ hạn chế việc sử dụng một số trường và phương thức không phải SDK. Các quy định hạn chế này sẽ áp dụng cho dù bạn tìm cách truy cập trực tiếp vào các phương thức và trường này thông qua cơ chế 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. Nếu ứng dụng của bạn hiển thị một thông báo ngắn như vậy, thì bạn cần theo dõi một chiến lược triển khai khác ngoài giao diện bị hạn chế. Nếu cảm thấy không thể sử dụng chiến lược thay thế nào, bạn có thể gửi lỗi để yêu cầu xem xét lại quy định hạn chế.
Các quy định hạn chế về giao diện không phải SDK chứa thông tin quan trọng khác. 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ề khả năng bảo mật của 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ề cách triển khai TLS
Hoạt động 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 quá trình tạo, hệ thống sẽ gửiIOException
thay vìNullPointerException
. - Lớp
SSLEngine
xử lý dễ dàng mọi cảnh báoclose_notify
xảy ra.
Để tìm hiểu thêm về cách tạo các yêu cầu web an toàn trong một ứ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ế hơn nữa các lệnh gọi hệ thống có sẵn cho các ứng 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ã hoá.
Tích hợp các phương pháp triển khai tham số và thuật toán
Android 9 cung cấp các cách triển khai bổ sung cho các tham số thuật toán trong Conscrypt. Các tham số này bao gồm: AES, DESEDE, OAEP và EC. 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, thì bạn sẽ nhận được cảnh báo khi yêu cầu triển khai Bouncy Castle đối với một trong các thuật toán không dùng nữa. Tuy nhiên, nếu bạn nhắm đến Android 9, mỗi yêu cầu này sẽ gửi một NoSuchAlgorithmException
.
Các thay đổi khác
Android 9 ra mắt một số thay đổi khác liên quan đến mật mã học:
- Khi sử dụng khoá PBE, nếu Bouncy Castle dự kiến có một vectơ khởi động (IV) nhưng ứng dụng của bạn không cung cấp vectơ khởi động đó, thì bạn sẽ nhận được cảnh báo.
- Việc triển khai Conscrypt của thuật toán mật mã ARC4 cho phép bạn chỉ định ARC4/ECB/NoPadding hoặc ARC4/NONE/NoPadding.
- Nhà cung cấp Crypto Java Cryptographic Kiến (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 khoá RSA từ những vùng đệm lớn hơn cấu trúc khoá, thì trường hợp ngoại lệ sẽ không còn xảy ra nữa.
Để 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 bài viết Mật mã học.
Các tệp đã mã hoá bảo mật trên Android không còn được hỗ trợ nữa
Android 9 sẽ ngừng hỗ trợ các tệp mã hoá bảo mật (ASEC) trên Android.
Trong Android 2.2 (API cấp 8), Android đã ra mắt 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 đã giới thiệu một công nghệ thiết bị lưu trữ có thể sử dụng mà các nhà phát triển có thể sử dụng thay cho ASEC.
Nội dung cập nhật đối với 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 dùng để cung cấp các API công khai bên dưới android.icu package
và được sử dụng nội bộ trong nền tảng Android để hỗ trợ quá trình quốc tế hoá.
Ví dụ: API này được dùng để triển khai các lớp Android trong java.util
, java.text
và android.text.format
.
Bản cập nhật cho ICU 60 chứa nhiều thay đổi nhỏ nhưng hữu ích, bao gồm cả việc hỗ trợ dữ liệu Biểu tượng cảm xúc 5.0 và các định dạng ngày/giờ được cải tiến, như được nêu trong ghi chú phát hành của 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 là đồng nghĩa với GMT.
ICU hiện cung cấp bản dịch tên vùng theo giờ GMT và UTC. Thay đổi này ảnh hưởng đến cách định dạng và phân tích cú pháp
android.icu
của các vùng như "GMT", "Etc/GMT", "UTC", "Etc/UTC" và "Zulu". java.text.SimpleDateFormat
nay sử dụng ICU để cung cấp tên hiển thị theo giờ UTC /GMT, nghĩa là:- Việc định dạng
zzzz
sẽ tạo ra một chuỗi dài đã bản địa hoá cho nhiều ngôn ngữ. Trước đây, công cụ này tạo ra "UTC" cho giờ UTC và các chuỗi như "GMT+00:00" cho giờ GMT. - Việc phân tích cú pháp
zzzz
sẽ nhận ra các chuỗi như "Thời gian phối hợp chung" và "Giờ chuẩn Greenwich". - Các ứ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à dữ liệu đầu ra cho
zzzz
bằng mọi ngôn ngữ.
- Việc định dạng
- Hành vi của
java.text.DateFormatSymbols.getZoneStrings()
đã thay đổi:- Tương tự 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 tiêu chuẩn khi không có tên, thay vì là chuỗi được cố định giá trị trong mãUTC
. - Một số mã vùng được nhận dạng chính xác dưới dạng từ đồng nghĩa với các vùng khác. Do đó, Android sẽ tìm thấy các chuỗi cho mã vùng cũ (chẳng hạn như
Eire
) mà trước đây không phân giải được.
- Tương tự như
- Khu vực Châu Á/Hà Nội không còn là khu vực được nhận diệ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 ra giá trị đó. Hành vi này nhất quán với hành vi hiện có củaandroid.icu
.
- Nền tảng này xử lý GMT và UTC tốt hơn; UTC không còn là đồng nghĩa với GMT.
- Phương thức
android.icu.text.NumberFormat.getInstance(ULocale, PLURALCURRENCYSTYLE).parse(String)
có thể gửi mộtParseException
ngay cả khi phân tích cú pháp văn bản đơn vị tiền tệ hợp lệ. Hãy tránh vấn đề này bằng cách sử dụngNumberFormat.parseCurrency
có sẵn kể từ Android 7.0 (API cấp 24) cho văn bản đơn vị tiền tệ kiểuPLURALCURRENCYSTYLE
.
Các thay đổi trong quá trình 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ợ bởi khung, nhưng cũng giúp bạn linh hoạt hơn trong việc xây dựng và chạy kiểm thử bằng thư viện của bên thứ ba hoặc logic tuỳ chỉnh.
Đã xoá các 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 3 thư viện:
android.test.base, android.test.runner và android.test.mock.
Thay đổi này cho phép bạn chạy thử nghiệm trên một phiên bản JUnit hoạt động hiệu quả 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 sắp xếp các lớp dựa trên JUnit 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 nội dung Thiết lập dự án để kiểm thử Android.
Thay đổi bản dựng của bộ thử nghiệm
Phương thức addRequirements()
trong lớp
TestSuiteBuilder
đã bị xoá và lớp TestSuiteBuilder
cũng không được dùng nữa.
Phương thức addRequirements()
yêu cầu các nhà phát triển cung cấp các đối số có loại là API ẩn, khiến API này không hợp lệ.
Bộ giải mã Java UTF
UTF-8 là bộ ký tự mặc định trong Android. Một chuỗi 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 theo các tiêu chuẩn Unicode nghiêm ngặt hơn so với các phiên bản trước. Các thay đổi bao gồm:
- Định dạng không ngắn nhất của UTF-8, chẳng hạn như
<C0, AF>
, được coi là định dạng kém. - Dạng thay thế của UTF-8, chẳng hạn như
U+D800
..U+DFFF
, được coi là định dạng không hợp lệ. - Phần con lớn nhất đượ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
", phần phụ tối đa là "C0
", "AF
" và "F4 80 80
". "F4 80 80
" có thể là tiếp nối ban đầu của "F4 80 80 80
", nhưng "C0
" không thể là tiếp nối ban đầu của bất kỳ chuỗi đơn vị mã nào được định dạng đúng. Do đó, dữ liệu đầu ra sẽ là "A\ufffd\ufffdA\ufffdA
". - Để giải mã 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 JNINewStringUTF()
.
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 một chứng chỉ – sử dụng các tên có sẵn trong đuôi subjectAltName
(SAN
) hoặc khi không có đuôi SAN
, hãy quay lại sử dụng commonName
(CN
).
Tuy nhiên, tính năng dự phòng cho CN
không còn được dùng trong RFC 2818. Vì lý do này, Android không còn quay lại sử dụng CN
nữa. Để xác minh tên máy chủ, máy chủ
phải hiển thị chứng chỉ có SAN
trùng 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 đáng tin cậy nữa.
Việc tra cứu địa chỉ mạng có thể gây ra lỗi vi phạm mạng
Các hoạt động 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à hoạt động chặn. Thao tác chặn 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 các 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 hoạt động tra cứu địa chỉ mạng yêu cầu phân giải tên.
Bạn không nên gửi ứng dụng của mình khi đã bật StrictMode
. Nếu bạn làm như vậy, ứng dụng của bạn có thể gặp 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 xem là hoạt động chặn. Độ phân giải địa chỉ IP dạng số hoạt động giống như trong các phiên bản trước Android 9.
Gắn thẻ cổng
Trong các phiên bản nền tảng thấp hơn Android 9, nếu một socket được gắn thẻ bằng phương thức setThreadStatsTag()
, thì socket sẽ không được gắn thẻ khi được gửi đến một quy trình khác bằng IPC liên kết với vùng chứa ParcelFileDescriptor
.
Trong Android 9 trở lên, thẻ ổ cắm được lưu giữ khi gửi đến một quy trình khác bằng IPC liên kết. 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, chẳng hạn như 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 (tức là bỏ 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ố lượng byte còn trống đượ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 của mạng dành cho VPN
Trong 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 gây khó khăn cho việc xác định xem việc sử dụng VPN có khiến người dùng ứng dụng bị tính phí hay không. Ví dụ: việc kiểm tra NET_CAPABILITY_NOT_METERED
sẽ không xác định được các mạng cơ bản có được đo lượng dữ liệu hay không.
Trên 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 mạng truyền tải và chức năng của mọi mạng cơ sở, đồng thời trả về kết quả là tính 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 tính năng mạng của VPN và các mạng cơ sở.
Các tệp trong thư mục xt_qta thủ không còn truy cập được vào ứng dụng
Kể từ Android 9, các ứng dụng không được phép truy cập 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ị không có các tệp này.
Các API công khai dựa vào những tệp này, TrafficStats
và NetworkStatsManager
, 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 hoàn toàn không hoạt động trên các thiết bị khác nhau.
Yêu cầu về FLAG_ACTIVITY_NEW_TASK hiện đã được thực thi
Với Android 9, bạn không thể bắt đầu một hoạt động từ ngữ cảnh không 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 chuyể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ề tính năng xoay màn hình
Kể từ Android 9, chế độ xoay dọc sẽ có những thay đổi đáng kể. Trong Android 8.0 (API cấp 26), người dùng có thể chuyển đổi giữa các chế độ xoay tự động xoay và dọc bằng cách sử dụng thẻ thông tin Quicksettings (Cài đặt nhanh) hoặc chế độ cài đặt Display (Hiển thị). Chế độ dọc được đổi tên thành khoá xoay và sẽ hoạt động khi chế độ tự động xoay được tắt. 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 mà Hoạt động hiển thị ở trên cùng hỗ trợ. Hoạt động không nên giả định rằng nó sẽ luôn hiển thị ở chế độ dọc. Nếu Hoạt động trên cùng có thể hiển thị ở nhiều chế độ xoay ở chế độ tự động xoay, thì các tuỳ chọn tương tự sẽ có ở chế độ khoá xoay, 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 một hướng cụ thể (ví dụ: screenOrientation=landscape
) bỏ qua lựa chọn ưu tiên về khoá người dùng và hoạt động giống như trong Android 8.0.
Bạn có thể đặt lựa chọn ưu tiên về hướng màn hình ở cấp Hoạt động trong Tệp kê khai Android hoặc lập trình bằng setRequestedOrientation().
Chế độ khoá chế độ xoay hoạt động bằng cách đặt tuỳ chọn xoay người dùng mà WindowManager sử dụng khi xử lý chế độ xoay Hoạt động. Lựa chọn xoay vòng người dùng có thể thay đổi trong các trường hợp sau. Lưu ý rằng sẽ có một sai số khi quay lại hướng 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 bắt buộc hướng 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 chế độ 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á chế độ xoay, Hoạt động có thể hiển thị ở chế độ 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ể hiển thị theo hướng ngang hoặc ngang đảo ngược. Có thể chỉ hỗ trợ bố cục ngang. |
Chân dung người dùng | Trong chế độ tự động xoay và khoá xoay, Hoạt động có thể được hiển thị theo hướng dọc hoặc dọc đảo ngược. Có thể chỉ hỗ trợ bố cục dọc. |
người dùng toàn quyền | Trong chế độ tự động xoay và khoá chế độ xoay, Hoạt động có thể hiển thị ở chế độ dọc hoặc ngang (và ngược lại). Có thể sẽ hỗ trợ cả bố cục dọc và ngang. Người dùng khoá xoay sẽ được cung cấp tuỳ chọn khoá để đảo ngược hướng dọc, thường là 180o. |
cảm biến, fullSensor, cảm biến Chân dung, sensorLandscape | Tùy chọn chế độ khoá xoay bị bỏ qua và được coi là khi chế độ tự động xoay đang hoạt động. Chỉ sử dụng phương pháp này trong những trường hợp đặc biệt khi có sự cân nhắc rất kỹ lưỡng về trải nghiệm người dùng. |
Việc ngừng sử dụng máy khách Apache HTTP ảnh hưởng đến các ứng dụng có ClassLoader không tiêu chuẩn
Với Android 6.0, chúng tôi đã ngừng hỗ trợ ứng dụng HTTP HTTP.
Thay đổi này không ảnh hưởng đến phần lớn các ứ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 tiêu chuẩn, ngay cả khi ứng dụng không nhắm đến Android 9 trở lên.
Một ứ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 hệ thống ClassLoader
. Các ứng dụng này cần phải uỷ quyền cho ứng dụng
ClassLoader
thay vì tìm kiếm các lớp trong org.apache.http.*
. Nếu các lớp uỷ quyền cho hệ thống ClassLoader
, các ứng dụng sẽ không hoạt động trên Android 9 trở lên kèm theo NoClassDefFoundError
, vì các lớp đó không còn được hệ thống ClassLoader
xác định. Để ngăn chặn các sự cố tương tự trong tương lai, các ứng dụng nên tải các lớp nói chung thông qua ClassLoader
của ứng dụng thay vì truy cập trực tiếp vào hệ thống ClassLoader
.
Liệt kê camera
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 nên 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 máy ảnh trước và sau, thì có thể có nhiều máy ảnh trước hoặc sau để lựa chọn. Bạn nên xem danh sách máy ảnh, kiểm tra các đặc điểm của từng máy ảnh và quyết định máy ảnh nào cần hiển thị cho người dùng.