Các thay đổi về Android 6.0

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 nên nắm rõ và cân nhắc trong ứng dụng của mình.

Nếu trước đây bạn đã phát hành một ứng dụng cho Android, hãy lưu ý rằng những thay đổi này trong nền tảng sẽ ả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 quản lý quyền mới mà giờ đây, người dùng có thể quản lý trực tiếp quyền cho ứ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 hiển thị 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 từng quyền đối với 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á tiết kiệm pin mới cho các 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ị chưa cắm điện, hệ thống sẽ tắt quyền truy cập mạng, đồng thời tạm ngưng quá trình đồng bộ hoá và công việc đối với các ứng dụng được cho là ở 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.solibssl.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

Để tăng cường khả năng bảo vệ dữ liệu cho người dùng, 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()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 Wi-Fi hoặc Bluetooth ở chế độ nền, các thiết bị bên ngoài sẽ thấy thao tác này là bắt nguồn từ một địa chỉ MAC được tạo ngẫu nhiên.

Thông báo

Bản phát hành này sẽ 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 nhiều lần một thông báo, hãy sử dụng lại phiên bản 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 của bạn 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.

Các thay đổi về 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

Màn hình hiển thị các tính năng lựa chọn văn bản mới trong thanh công cụ nổi

Giờ đây, khi người dùng chọn văn bản trong ứng dụng, bạn có thể cho thấy các thao tác lựa chọn văn bản như Cut, CopyPaste (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ó:

  1. Trong đối tượng View hoặc Activity, hãy thay đổi các lệnh gọi ActionMode từ startActionMode(Callback) thành startActionMode(Callback, ActionMode.TYPE_FLOATING).
  2. Thay vào đó, hãy triển khai ActionMode.Callback hiện tại và mở rộng ActionMode.Callback2.
  3. Ghi đè phương thức onGetContentRect() để cung cấp toạ độ của đối tượng Rect 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ị.
  4. 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 không hợp lệ, hãy gọi phương thức invalidateContentRect().

Nếu bạn đang sử dụng Thư viện hỗ trợ Android bản sửa đổi 22.2, hãy lưu ý rằng thanh công cụ nổi không tương thích ngược và appcompat sẽ kiểm soát các đối tượng ActionMode theo mặc định. Đ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), cho phép khung hỗ trợ ActionBar hoặc các chế độ của thanh công cụ nổi, còn 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ợ.

Các thay đổi về dấu trang của trình duyệt

Bản phát hành này sẽ ngừng hỗ trợ dấu trang chung. Các phương thức android.provider.Browser.getAllBookmarks()android.provider.Browser.saveBookmark() hiện đã bị xoá. Tương tự, các quyền READ_HISTORY_BOOKMARKSWRITE_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 các dấu trang từ nhà cung cấp toàn cầu hoặc sử dụng quyền dấu trang. Thay vào đó, ứng dụng của bạn sẽ lưu trữ dữ liệu dấu trang trong nội bộ.

Các thay đổi đối với 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). Các 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.

  • Ứng dụng của bạn hiệ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ượng WifiConfiguration do người dùng hoặ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 đặt disableAllOthers=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 với các mạng khác như vậy nữa. Nếu targetSdkVersion của ứng dụng là “20” trở xuống, thì mục này sẽ được ghim vào mạng Wi-Fi đã chọn. Nếu targetSdkVersion của ứng dụng là “21” trở lên, hãy sử dụng các API đa mạng (chẳng hạn như openConnection(), bindSocket() và phương thức bindProcessToNetwork() mới) để đảm bảo rằng lưu lượng truy cập mạng của ứng dụng đó được gửi trên mạng đã chọn.

Các thay đổi về dịch vụ camera

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. Các thay đổi về 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 mà người dùng nhìn thấy thường được ưu tiên hơn, giúp việc thu nạ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ệc onError() được gọi cho ứng dụng bị loại bỏ. Trong API Camera2, điều này dẫn đến việc gọi onDisconnected() 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, dịch vụ máy ảnh hiện đã phát hiện và cho phép các trường hợp sử dụng nhiều quy trình, trong đó việc 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 đang mở nào. 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 các ứ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 đó bị loại bỏ. Chỉ có quyền truy cập vào máy ảnh trong hồ sơ người dùng 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

Môi trường thời gian chạy ART hiện 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 dùng thư viện appcompat phiên bản 7 hoặc thư viện recyclerview phiên bản, bạn phải cập nhật ứng dụng để dùng lên 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 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à giá trị mặc định, vì vậy, các lệnh gọi đến dlopen(3) không sử dụng RTLD_LOCAL một cách rõ ràng sẽ bị ảnh hưởng (trừ phi ứng dụng của bạn rõ ràng sử dụng RTLD_GLOBAL). Với RTLD_LOCAL, các biểu tượng 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ày đến dlopen(3) (thay vì được các mục nhập DT_NEEDED tham chiếu đến).

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 bằng tính năng chuyển vị trí 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 được hay không, ứng dụng của bạn sẽ ghi nhật ký lỗi dlopen(3) và đưa vào văn bản mô tả vấn đề 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

Nền tảng hiện thực hiện quy trình xác thực nghiêm ngặt hơn đối với tệp APK. Tệp APK được coi là bị hỏng nếu một 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ị thông 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 trên thiết bị qua kết nối USB, người dùng phải cấp quyền một cách rõ ràng cho các tương tác đó. Nếu ứng dụng của bạn hỗ trợ hoạt động tương tác của người dùng với thiết bị qua cổng USB, hãy cân nhắc việc bật tính năng tương tác một cách rõ ràng.

Các thay đổi của Android for Work

Bản phát hành này bao gồm các thay đổi sau đây về hành vi cho Android for Work:

  • Danh bạ công việc trong bối cảnh cá nhân. Nhật ký cuộc gọi của Trình quay số Google hiện 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ành true sẽ ẩn danh bạ trong hồ sơ công việc trong Nhật ký cuộc gọi của Trình quay số của Google. Danh bạ công việc chỉ có thể hiển thị cùng với danh bạ cá nhân trên các thiết bị qua Bluetooth nếu bạn đặt setBluetoothContactSharingDisabled() thành false. Theo mặc định, giá trị này được đặt thành true.
  • Xoá cấu hình Wi-Fi: Cấu hình Wi-Fi do Chủ sở hữu hồ sơ thêm vào (ví dụ: thông qua các lệnh gọi đến phương thức addNetwork()) giờ đây sẽ bị xoá nếu hồ sơ công việc đó bị xoá.
  • Khoá cấu hình Wi-Fi: Người dùng không thể sửa đổi hoặc xoá 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 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 mình. 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 kiểm soát chính sách thiết bị xuống thông qua tính năng 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 kiểm soát chính sách thiết bị (DPC) được thêm vào thiết bị bên ngoài ngữ cảnh được quản lý, giờ đây, quy trình thêm tài khoả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 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:
    • Các phương thức DevicePolicyManager.createAndInitializeUser()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ợ để 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 quay lạ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ặc ACTION_PROVISION_MANAGED_DEVICE, hệ thống sẽ trả về một mã kết quả RESULT_CANCELED.
  • 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ành NetworkStats.
  • Thay đổi đối với chế độ cài đặt chung: