Cùng với các tính năng và chức năng mới, Android 6.0 (API cấp 23) còn có nhiều thay đổi về hệ thống và hành vi của API. Tài liệu này nêu bật một số thay đổi chính mà bạn cần hiểu và tính đến trong ứng dụng của mình.
Nếu bạn từng phát hành một ứng dụng dành cho Android, hãy lưu ý rằng những thay đổi này trong nền tảng ảnh hưởng đến ứng dụng của bạn.
Quyền trong thời gian chạy
Bản phát hành này giới thiệu một mô hình quyền mới, trong đó người dùng hiện có thể trực tiếp quản lý các quyền của ứng dụng trong thời gian chạy. Mô hình này giúp người dùng cải thiện khả năng xem và kiểm soát các quyền, đồng thời đơn giản hoá quy trình cài đặt và tự động cập nhật cho nhà phát triển ứng dụng. Người dùng có thể cấp hoặc thu hồi quyền riêng lẻ cho các ứng dụng đã cài đặt.
Trên các ứng dụng nhắm đến Android 6.0 (API cấp 23) trở lên, hãy nhớ kiểm tra và yêu cầu quyền khi bắt đầu chạy. Để xác định xem ứng dụng của bạn đã được cấp quyền hay chưa, hãy gọi phương thức checkSelfPermission()
mới. Để yêu cầu quyền, hãy gọi phương thức requestPermissions()
mới. Ngay cả khi ứng dụng của bạn không nhắm đến Android 6.0 (API cấp 23), bạn vẫn nên kiểm thử ứng dụng theo mô hình quản lý quyền mới.
Để biết thông tin chi tiết về cách hỗ trợ mô hình quyền mới trong ứng dụng, hãy xem phần Xử lý các quyền hệ thống. Để biết các mẹo về cách đánh giá tác động đối với ứng dụng của bạn, hãy xem Ghi chú về việc sử dụng quyền.
Chế độ Nghỉ và Chế độ chờ ứng dụng
Bản phát hành này giới thiệu các tính năng tối ưu hoá mới giúp tiết kiệm pin cho thiết bị và ứng dụng ở trạng thái rảnh. Các tính năng này ảnh hưởng đến tất cả ứng dụng, vì vậy, hãy nhớ kiểm thử ứng dụng của bạn ở các chế độ mới này.
- Nghỉ: Nếu người dùng rút phích cắm thiết bị và để thiết bị ở trạng thái tĩnh, màn hình tắt trong một khoảng thời gian, thì thiết bị sẽ chuyển sang chế độ Nghỉ để cố gắng duy trì trạng thái ngủ của hệ thống. Ở chế độ này, các thiết bị định kỳ tiếp tục hoạt động bình thường trong khoảng thời gian ngắn để quá trình đồng bộ hoá ứng dụng có thể diễn ra và hệ thống có thể thực hiện mọi thao tác đang chờ xử lý.
- Chế độ chờ ứng dụng: Chế độ chờ ứng dụng cho phép hệ thống xác định rằng một ứng dụng đang ở trạng thái rảnh khi người dùng không chủ động sử dụng ứng dụng đó. Hệ thống xác định điều này khi người dùng không chạm vào ứng dụng trong một khoảng thời gian nhất định. Nếu thiết bị bị rút phích cắm, hệ thống sẽ tắt quyền truy cập mạng và tạm ngưng các hoạt động đồng bộ hoá cũng như công việc cho những ứng dụng mà hệ thống cho là đang ở trạng thái rảnh.
Để tìm hiểu thêm về những thay đổi tiết kiệm pin này, hãy xem phần Tối ưu hoá cho chế độ Nghỉ và chế độ Chờ ứng dụng.
Xoá ứng dụng khách Apache HTTP
Bản phát hành Android 6.0 sẽ ngừng hỗ trợ ứng dụng Apache HTTP. Nếu ứng dụng của bạn đang dùng ứng dụng này và nhắm đến Android 2.3 (API cấp 9) trở lên, hãy dùng lớp HttpURLConnection
. API này hiệu quả hơn vì giảm mức sử dụng mạng thông qua việc lưu vào bộ nhớ đệm phản hồi và nén minh bạch, đồng thời giảm thiểu mức tiêu thụ điện năng. Để tiếp tục sử dụng các API HTTP của Apache, trước tiên, bạn phải khai báo phần phụ thuộc tại thời điểm biên dịch sau đây trong tệp build.gradle
:
android { useLibrary 'org.apache.http.legacy' }
BoringSSL
Android đang chuyển từ OpenSSL sang thư viện BoringSSL. Nếu bạn đang sử dụng Android NDK trong ứng dụng, đừng liên kết với các thư viện mã hoá không phải là một phần của API NDK, chẳng hạn như libcrypto.so
và libssl.so
. Các thư viện này không phải là API công khai và có thể thay đổi hoặc bị lỗi mà không cần thông báo trên các bản phát hành và thiết bị.
Ngoài ra, bạn có thể gặp phải các lỗ hổng bảo mật. Thay vào đó, hãy sửa đổi mã gốc để gọi các API mã hoá Java thông qua JNI hoặc liên kết tĩnh với một thư viện mã hoá mà bạn chọn.
Quyền truy cập vào Mã nhận dạng phần cứng
Để cung cấp cho người dùng khả năng bảo vệ dữ liệu tốt hơn, kể từ bản phát hành này, Android sẽ xoá quyền truy cập có lập trình vào giá trị nhận dạng phần cứng cục bộ của thiết bị đối với các ứng dụng sử dụng API Wi-Fi và Bluetooth. Phương thức WifiInfo.getMacAddress()
và BluetoothAdapter.getAddress()
hiện trả về giá trị không đổi là 02:00:00:00:00:00
.
Để truy cập vào giá trị nhận dạng phần cứng của các thiết bị bên ngoài ở gần thông qua tính năng quét Bluetooth và Wi-Fi, ứng dụng của bạn hiện phải có quyền ACCESS_FINE_LOCATION
hoặc ACCESS_COARSE_LOCATION
:
Lưu ý: Khi một thiết bị chạy Android 6.0 (API cấp 23) bắt đầu quét tìm Wi-Fi hoặc Bluetooth ở chế độ nền, thao tác này sẽ hiển thị với các thiết bị bên ngoài do có nguồn gốc từ một địa chỉ MAC ngẫu nhiên.
Thông báo
Bản phát hành này xoá phương thức Notification.setLatestEventInfo()
. Thay vào đó, hãy sử dụng lớp Notification.Builder
để tạo thông báo. Để cập nhật thông báo nhiều lần, hãy sử dụng lại thực thể Notification.Builder
. Gọi phương thức build()
để nhận các thực thể Notification
đã cập nhật.
Lệnh adb shell dumpsys notification
không còn in văn bản thông báo nữa.
Thay vào đó, hãy sử dụng lệnh adb shell dumpsys notification --noredact
để in văn bản trong đối tượng thông báo.
Thay đổi đối với AudioManager
Chúng tôi không còn hỗ trợ việc đặt âm lượng trực tiếp hoặc tắt tiếng các luồng cụ thể thông qua lớp AudioManager
. Phương thức setStreamSolo()
không còn được dùng nữa và bạn nên gọi phương thức requestAudioFocus()
. Tương tự, phương thức setStreamMute()
không còn được dùng nữa; thay vào đó, hãy gọi phương thức adjustStreamVolume()
và truyền vào giá trị hướng ADJUST_MUTE
hoặc ADJUST_UNMUTE
.
Chọn văn bản
Khi người dùng chọn văn bản trong ứng dụng, giờ đây, bạn có thể hiển thị các thao tác chọn văn bản như Cắt, Sao chép và Dán trong một thanh công cụ nổi. Cách triển khai hoạt động tương tác của người dùng tương tự như cách triển khai thanh thao tác theo ngữ cảnh, như mô tả trong bài viết Bật chế độ thao tác theo ngữ cảnh cho từng khung hiển thị.
Để triển khai thanh công cụ nổi cho lựa chọn văn bản, hãy thực hiện các thay đổi sau trong các ứng dụng hiện có:
- Trong đối tượng
View
hoặcActivity
, hãy thay đổi các lệnh gọiActionMode
từstartActionMode(Callback)
thànhstartActionMode(Callback, ActionMode.TYPE_FLOATING)
. - Thay vào đó, hãy triển khai
ActionMode.Callback
hiện tại và mở rộngActionMode.Callback2
. - Ghi đè phương thức
onGetContentRect()
để cung cấp toạ độ của đối tượngRect
nội dung (chẳng hạn như hình chữ nhật lựa chọn văn bản) trong thành phần hiển thị. - Nếu vị trí hình chữ nhật không còn hợp lệ và đây là phần tử duy nhất bị vô hiệu, hãy gọi phương thức
invalidateContentRect()
.
Nếu bạn đang sử dụng bản sửa đổi 22.2 của
Thư viện hỗ trợ Android, hãy lưu ý rằng thanh công cụ nổi không tương thích ngược và theo mặc định, appcompat sẽ kiểm soát các đối tượng ActionMode
. Điều này giúp ngăn các thanh công cụ nổi hiển thị. Để bật tính năng hỗ trợ ActionMode
trong AppCompatActivity
, hãy gọi getDelegate()
, sau đó gọi setHandleNativeActionModesEnabled()
trên đối tượng AppCompatDelegate
được trả về và đặt tham số đầu vào thành false
. Lệnh gọi này trả về quyền kiểm soát đối tượng ActionMode
cho khung. Trong các thiết bị chạy Android 6.0 (API cấp 23), điều này cho phép khung hỗ trợ các chế độ ActionBar
hoặc thanh công cụ nổi, trong khi trên các thiết bị chạy Android 5.1 (API cấp 22) trở xuống, chỉ các chế độ ActionBar
mới được hỗ trợ.
Thay đổi về dấu trang trên trình duyệt
Bản phát hành này sẽ ngừng hỗ trợ tính năng dấu trang chung. Các phương thức
android.provider.Browser.getAllBookmarks()
và android.provider.Browser.saveBookmark()
hiện đã bị xoá. Tương tự, các quyền READ_HISTORY_BOOKMARKS
và WRITE_HISTORY_BOOKMARKS
sẽ bị xoá. Nếu ứng dụng của bạn nhắm đến Android 6.0 (API cấp 23) trở lên, đừng truy cập vào
dấu trang từ trình cung cấp chung hoặc sử dụng quyền dấu trang. Thay vào đó, ứng dụng của bạn nên lưu trữ dữ liệu dấu trang trong nội bộ.
Các thay đổi về Kho khoá Android
Với bản phát hành này, Trình cung cấp Kho khoá Android không còn hỗ trợ DSA nữa. ECDSA vẫn được hỗ trợ.
Các khoá không yêu cầu mã hoá khi ở trạng thái nghỉ sẽ không còn bị xoá khi màn hình khoá bảo mật bị vô hiệu hoá hoặc đặt lại (ví dụ: do người dùng hoặc Quản trị viên thiết bị thực hiện). Những khoá yêu cầu mã hoá khi lưu trữ sẽ bị xoá trong những sự kiện này.
Thay đổi về Wi-Fi và mạng
Bản phát hành này giới thiệu các thay đổi về hành vi sau đây đối với API Wi-Fi và API kết nối mạng.
- Giờ đây, ứng dụng của bạn chỉ có thể thay đổi trạng thái của các đối tượng
WifiConfiguration
nếu bạn đã tạo các đối tượng này. Bạn không được phép sửa đổi hoặc xoá các đối tượngWifiConfiguration
do người dùng hoặc các ứng dụng khác tạo. -
Trước đây, nếu một ứng dụng buộc thiết bị kết nối với một mạng Wi-Fi cụ thể bằng cách sử dụng
enableNetwork()
với chế độ cài đặtdisableAllOthers=true
, thì thiết bị sẽ ngắt kết nối với các mạng khác như dữ liệu di động. Trong bản phát hành này, thiết bị không còn ngắt kết nối khỏi các mạng khác như vậy. NếutargetSdkVersion
của ứng dụng là“20”
trở xuống, thì ứng dụng đó sẽ được ghim vào mạng Wi-Fi đã chọn. NếutargetSdkVersion
của ứng dụng là“21”
trở lên, hãy sử dụng các API nhiều mạng (chẳng hạn nhưopenConnection()
,bindSocket()
và phương thứcbindProcessToNetwork()
mới) để đảm bảo lưu lượng truy cập mạng được gửi trên mạng đã chọn.
Thay đổi về Dịch vụ máy ảnh
Trong Bản phát hành này, mô hình truy cập vào tài nguyên dùng chung trong dịch vụ máy ảnh đã được thay đổi từ mô hình truy cập "đến trước, ưu tiên trước" trước đó thành mô hình truy cập ưu tiên các quy trình có mức độ ưu tiên cao. Những thay đổi đối với hành vi của dịch vụ bao gồm:
- Quyền truy cập vào tài nguyên hệ thống con của máy ảnh, bao gồm cả việc mở và định cấu hình thiết bị máy ảnh, được cấp dựa trên "mức độ ưu tiên" của quy trình ứng dụng khách. Các quy trình ứng dụng có hoạt động ở nền trước hoặc hoạt động hiển thị với người dùng thường được ưu tiên hơn, giúp việc thu thập và sử dụng tài nguyên máy ảnh trở nên đáng tin cậy hơn.
- Ứng dụng máy ảnh đang hoạt động cho các ứng dụng có mức độ ưu tiên thấp hơn có thể bị "loại bỏ" khi một ứng dụng có mức độ ưu tiên cao hơn cố gắng sử dụng máy ảnh. Trong API
Camera
không dùng nữa, điều này dẫn đến việconError()
được gọi cho ứng dụng bị loại bỏ. Trong APICamera2
, điều này dẫn đến việc gọionDisconnected()
cho ứng dụng bị loại bỏ. - Trên các thiết bị có phần cứng máy ảnh phù hợp, các quy trình ứng dụng riêng biệt có thể mở và sử dụng đồng thời các thiết bị máy ảnh riêng biệt một cách độc lập. Tuy nhiên, các trường hợp sử dụng nhiều quy trình, trong đó quyền truy cập đồng thời làm giảm đáng kể hiệu suất hoặc chức năng của bất kỳ thiết bị máy ảnh nào đang mở, hiện đã được dịch vụ máy ảnh phát hiện và không cho phép. Thay đổi này có thể dẫn đến việc "loại bỏ" các ứng dụng có mức độ ưu tiên thấp hơn ngay cả khi không có ứng dụng nào khác đang trực tiếp tìm cách truy cập vào cùng một thiết bị camera.
- Việc thay đổi người dùng hiện tại sẽ khiến ứng dụng máy ảnh đang hoạt động trong các ứng dụng thuộc sở hữu của tài khoản người dùng trước đó sẽ bị loại bỏ. Quyền truy cập vào máy ảnh chỉ giới hạn ở những hồ sơ người dùng thuộc quyền sở hữu của người dùng thiết bị hiện tại. Trong thực tế, điều này có nghĩa là tài khoản "Khách" sẽ không thể thoát khỏi các quy trình đang chạy có sử dụng hệ thống phụ của máy ảnh khi người dùng đã chuyển sang một tài khoản khác.
Thời gian chạy
Giờ đây, môi trường thời gian chạy ART triển khai đúng cách các quy tắc truy cập cho phương thức newInstance()
. Thay đổi này khắc phục vấn đề Dalvik kiểm tra không chính xác các quy tắc truy cập trong các phiên bản trước.
Nếu ứng dụng của bạn sử dụng phương thức newInstance()
và bạn muốn ghi đè các bước kiểm tra quyền truy cập, hãy gọi phương thức setAccessible()
với tham số đầu vào được đặt thành true
. Nếu ứng dụng của bạn sử dụng thư viện appcompat v7 hoặc thư viện recyclerview v7, bạn phải cập nhật ứng dụng để sử dụng các phiên bản mới nhất của các thư viện này. Nếu không, hãy đảm bảo rằng mọi lớp tuỳ chỉnh được tham chiếu từ XML đều được cập nhật để có thể truy cập vào các hàm khởi tạo lớp của các lớp đó.
Bản phát hành này cập nhật hành vi của trình liên kết động. Trình liên kết động hiện đã hiểu được sự khác biệt giữa soname
của thư viện và đường dẫn của thư viện (
lỗi công khai 6670) và tính năng tìm kiếm theo soname
hiện đã được triển khai. Các ứng dụng từng hoạt động nhưng có mục nhập DT_NEEDED
không hợp lệ (thường là đường dẫn tuyệt đối trên hệ thống tệp của máy tạo bản dựng) có thể không tải được.
Cờ dlopen(3) RTLD_LOCAL
hiện đã được triển khai chính xác. Xin lưu ý rằng RTLD_LOCAL
là mặc định, vì vậy, các lệnh gọi đến dlopen(3)
không sử dụng rõ ràng RTLD_LOCAL
sẽ bị ảnh hưởng (trừ phi ứng dụng của bạn sử dụng rõ ràng RTLD_GLOBAL
). Với RTLD_LOCAL
, các ký hiệu sẽ không được cung cấp cho các thư viện được tải bằng các lệnh gọi sau đến dlopen(3)
(thay vì được tham chiếu bằng các mục DT_NEEDED
).
Trên các phiên bản Android trước, nếu ứng dụng của bạn yêu cầu hệ thống tải một thư viện dùng chung có các lượt di chuyển văn bản, thì hệ thống sẽ hiển thị cảnh báo nhưng vẫn cho phép tải thư viện.
Kể từ bản phát hành này, hệ thống sẽ từ chối thư viện này nếu phiên bản SDK mục tiêu của ứng dụng là 23 trở lên. Để giúp bạn phát hiện xem một thư viện có tải không thành công hay không, ứng dụng của bạn phải ghi lại lỗi dlopen(3)
và đưa vào văn bản mô tả sự cố mà lệnh gọi dlerror(3)
trả về. Để tìm hiểu thêm về cách xử lý việc di chuyển văn bản, hãy xem hướng dẫn này.
Xác thực APK
Giờ đây, nền tảng này sẽ xác thực tệp APK chặt chẽ hơn. Tệp APK bị coi là bị hỏng nếu tệp được khai báo trong tệp kê khai nhưng không có trong chính tệp APK đó. Bạn phải ký lại tệp APK nếu xoá bất kỳ nội dung nào.
Kết nối USB
Theo mặc định, các kết nối thiết bị qua cổng USB hiện được đặt thành chế độ chỉ sạc. Để truy cập vào thiết bị và nội dung của thiết bị qua kết nối USB, người dùng phải cấp quyền rõ ràng cho các hoạt động tương tác đó. Nếu ứng dụng của bạn hỗ trợ người dùng tương tác với thiết bị qua cổng USB, hãy cân nhắc việc phải bật rõ ràng hoạt động tương tác đó.
Các thay đổi về Android for Work
Bản phát hành này bao gồm các thay đổi về hành vi sau đây đối với Android cho công việc:
- Danh bạ công việc trong bối cảnh cá nhân. Giờ đây, Nhật ký cuộc gọi của Google Dialer hiển thị danh bạ công việc khi người dùng xem các cuộc gọi trước đây.
Việc đặt
setCrossProfileCallerIdDisabled()
thànhtrue
sẽ ẩn những người liên hệ trong hồ sơ công việc khỏi Nhật ký cuộc gọi của Google Dialer. Bạn chỉ có thể hiển thị thông tin liên hệ công việc cùng với thông tin liên hệ cá nhân cho các thiết bị qua Bluetooth nếu đặtsetBluetoothContactSharingDisabled()
thànhfalse
. Theo mặc định, giá trị này được đặt thànhtrue
. - Xoá cấu hình Wi-Fi: Các cấu hình Wi-Fi do Chủ sở hữu hồ sơ thêm (ví dụ: thông qua các lệnh gọi đến phương thức
addNetwork()
) hiện sẽ bị xoá nếu hồ sơ công việc đó bị xoá. - Khoá cấu hình Wi-Fi: Bất kỳ cấu hình Wi-Fi nào do Chủ sở hữu thiết bị đang hoạt động tạo ra đều sẽ không thể sửa đổi hoặc xoá được người dùng nếu
WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN
khác 0. Người dùng vẫn có thể tạo và sửa đổi cấu hình Wi-Fi của riêng họ. Chủ sở hữu thiết bị đang hoạt động có đặc quyền chỉnh sửa hoặc xoá mọi cấu hình Wi-Fi, bao gồm cả những cấu hình không phải do họ tạo. - Tải trình điều khiển chính sách thiết bị xuống thông qua việc thêm tài khoản Google: Khi một tài khoản Google yêu cầu quản lý thông qua ứng dụng trình điều khiển chính sách thiết bị (DPC) được thêm vào một thiết bị bên ngoài ngữ cảnh được quản lý, quy trình thêm tài khoản hiện sẽ nhắc người dùng cài đặt WPC thích hợp. Hành vi này cũng áp dụng cho các tài khoản được thêm thông qua phần Cài đặt > Tài khoản và trong trình hướng dẫn thiết lập thiết bị ban đầu.
- Các thay đổi đối với hành vi cụ thể của API
DevicePolicyManager
:- Việc gọi phương thức
setCameraDisabled()
chỉ ảnh hưởng đến máy ảnh của người dùng gọi; việc gọi phương thức này từ hồ sơ được quản lý sẽ không ảnh hưởng đến các ứng dụng máy ảnh chạy trên người dùng chính. - Ngoài ra, phương thức
setKeyguardDisabledFeatures()
hiện đã có cho Chủ sở hữu hồ sơ cũng như Chủ sở hữu thiết bị. - Chủ sở hữu hồ sơ có thể đặt các hạn chế sau đây khi sử dụng tính năng bảo vệ bàn phím:
KEYGUARD_DISABLE_TRUST_AGENTS
vàKEYGUARD_DISABLE_FINGERPRINT
, ảnh hưởng đến chế độ cài đặt khoá màn hình cho người dùng chính của hồ sơ.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS
, chỉ ảnh hưởng đến thông báo do các ứng dụng trong hồ sơ được quản lý tạo ra.
- Phương thức
DevicePolicyManager.createAndInitializeUser()
vàDevicePolicyManager.createUser()
không còn được dùng nữa. - Phương thức
setScreenCaptureDisabled()
hiện cũng chặn cấu trúc hỗ trợ khi một ứng dụng của người dùng nhất định đang ở nền trước. EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM
hiện đặt mặc định là SHA-256. SHA-1 vẫn được hỗ trợ để đảm bảo khả năng tương thích ngược nhưng sẽ bị xoá trong tương lai.EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM
hiện chỉ chấp nhận SHA-256.- Các API trình khởi chạy thiết bị có trong Android 6.0 (API cấp 23) hiện đã bị xoá.
EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS
bị xoá nên việc cấp phép NFC không thể mở khoá một thiết bị được bảo vệ bằng tính năng đặt lại về trạng thái ban đầu theo phương thức lập trình.- Giờ đây, bạn có thể sử dụng
EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE
bổ sung để truyền dữ liệu đến ứng dụng của chủ sở hữu thiết bị trong quá trình cấp phát NFC cho thiết bị được quản lý. - Các API Android cho công việc được tối ưu hoá cho các quyền trong thời gian chạy của M, bao gồm cả hồ sơ công việc, lớp hỗ trợ và các quyền khác. API quyền
DevicePolicyManager
mới không ảnh hưởng đến các ứng dụng trước phiên bản M. - Khi người dùng thoát khỏi phần đồng bộ của quy trình thiết lập được bắt đầu thông qua ý định
ACTION_PROVISION_MANAGED_PROFILE
hoặcACTION_PROVISION_MANAGED_DEVICE
, hệ thống hiện sẽ trả về mã kết quảRESULT_CANCELED
.
- Việc gọi phương thức
- Thay đổi đối với các API khác:
- Mức sử dụng dữ liệu: Lớp
android.app.usage.NetworkUsageStats
đã được đổi tên thànhNetworkStats
.
- Mức sử dụng dữ liệu: Lớp
- Thay đổi đối với chế độ cài đặt chung:
- Bạn không thể thiết lập các chế độ cài đặt này thông qua
setGlobalSettings()
nữa:BLUETOOTH_ON
DEVELOPMENT_SETTINGS_ENABLED
MODE_RINGER
NETWORK_PREFERENCE
WIFI_ON
- Giờ đây, bạn có thể đặt các chế độ cài đặt chung này thông qua
setGlobalSettings()
:
- Bạn không thể thiết lập các chế độ cài đặt này thông qua