Các thay đổi về Android 6.0

Cùng với các tính năng và khả năng mới, Android 6.0 (API cấp 23) bao gồm nhiều thay đổi về hệ thống và thay đổi 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 hiểu và lưu ý 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 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, trong đó người dùng hiện có thể trực tiếp quản lý các quyền cho ứng dụng trong thời gian chạy. Mô hình này giúp người dùng dễ xem và kiểm soát các quyền hơn, đồng thời tinh giản quy trình cài đặt và cập nhật tự động 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ẻ đố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 cấp quyền trong thời gian 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 trong 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 quản lý quyền mới trong ứng dụng của bạn, hãy xem bài viết Xử lý 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 một số tính năng tối ưu hoá mới giúp tiết kiệm điện năng cho ứng dụng và thiết bị ở 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 ở những chế độ mới này.

  • Chế độ nghỉ: Nếu người dùng rút thiết bị khỏi nguồn điện và để thiết bị đứng yên khi màn hình tắt, trong một khoảng thời gian, thiết bị sẽ chuyển sang chế độ Nghỉ để cố gắng giữ cho hệ thống ở trạng thái ngủ. Ở chế độ này, các thiết bị sẽ định kỳ tiếp tục hoạt động bình thường trong một 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 ở trạng thái rảnh khi người dùng không chủ động sử dụng ứng dụng đó. Hệ thống sẽ 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ẽ vô hiệu hoá 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 đối với các ứ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 giúp 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 HTTP HTTP

Bản phát hành Android 6.0 sẽ ngừng hỗ trợ ứng dụng HTTP 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 tính năng nén minh bạch và lưu vào bộ nhớ đệm phản hồi, đồng thời giảm thiểu mức tiêu thụ điện năng. Để tiếp tục sử dụng Apache HTTP API, trước tiên, bạn phải khai báo phần phụ thuộc thời gian biên dịch sau đây trong tệp build.gradle:

android {
    useLibrary 'org.apache.http.legacy'
}

Nhàm chánSSL

Android sẽ chuyển từ OpenSSL sang thư viện BoringSSL. Nếu bạn đang dùng Android NDK trong ứng dụng, không được liên kết dựa vào các thư viện mật mã không thuộc 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 gián đoạn mà không có thông báo trên các bản phát hành cũng như 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ật mã học Java thông qua JNI hoặc để liên kết tĩnh với một thư viện mật mã học 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. Giờ đây, phương thức WifiInfo.getMacAddress()BluetoothAdapter.getAddress() sẽ trả về một 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, các thiết bị bên ngoài sẽ thấy thao tác này vì bắt nguồn 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 dùng lớp Notification.Builder để tạo thông báo. Để cập nhật một thông báo nhiều lần, hãy sử dụng lại thực thể Notification.Builder. Hãy 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 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 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.

Lựa chọn văn bản

Màn hình hiển thị các tính năng mới để lựa chọn văn bản 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ư Cắt, Sao chépDán trong thanh công cụ nổi. Cách triển khai 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 phần 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 việc 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 lệnh gọi ActionMode từ startActionMode(Callback) thành startActionMode(Callback, ActionMode.TYPE_FLOATING).
  2. Thay vào đó, hãy sử dụng cách triển khai hiện tại của ActionMode.Callback và làm cho nó 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 khung 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 bị vô hiệu hoá, hãy gọi phương thức invalidateContentRect().

Nếu bạn đang 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 ngăn thanh công cụ nổi hiển thị. Để bật tính năng hỗ trợ ActionMode trong một 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 các đố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 chế độ thanh công cụ nổi, trong khi trên 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, thì đừng truy cập vào dấu trang của nhà cung cấp toàn cầu hoặc hãy sử dụng quyền đối với dấu trang. Thay vào đó, ứng dụng của bạn nên lưu trữ nội bộ dữ liệu dấu trang.

Các thay đổi về kho khoá Android

Với bản phát hành này, 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 tĩnh sẽ không còn bị xoá khi màn hình khoá bảo mật bị tắt hoặc đặt lại (ví dụ: do người dùng hoặc Quản trị viên thiết bị). Các khoá yêu cầu mã hoá khi lưu trữ sẽ bị xoá trong những sự kiện này.

Những thay đổi về mạng và Wi-Fi

Bản phát hành này giới thiệu các thay đổi sau đây về hành vi đối với API Wi-Fi và nối mạng.

  • Ứng dụng của bạn hiện chỉ có thể thay đổi trạng thái của đố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 các ứng dụng khác tạo ra.
  • 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 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, chẳng hạn 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 tương tự nữa. Nếu targetSdkVersion 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ếu targetSdkVersion của ứng dụng là “21” trở lên, hãy sử dụng API đa mạng (chẳng hạn như openConnection(), bindSocket() và phương thức bindProcessToNetwork() mới) để đảm bảo lưu lượng truy cập mạng của ứng dụng được gửi trên mạng đã chọn.

Thay đổi về dịch vụ camera

Trong bản phát hành này, mô hình để truy cập vào các tài nguyên dùng chung trong dịch vụ máy ảnh đã được thay đổi từ mô hình truy cập "ai đến trước" trước đây thành mô hình truy cập mà các quy trình có mức độ ưu tiên cao được ưu tiên. Các thay đổi đối với hành vi của dịch vụ bao gồm:

  • Quyền truy cập vào các 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. Các quy trình ứng dụng có hoạt động mà người dùng nhìn thấy hoặc hoạt động trên nền trước thường có mức độ ưu tiên cao 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, việc này dẫn đến việc onDisconnected() được gọi 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 nay phát hiện và không cho phép các trường hợp sử dụng đa tiến 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 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 trực tiếp tìm cách truy cập vào cùng thiết bị máy ảnh đó.
  • 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 thuộc 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" chẳng hạn sẽ không thể rời khỏi các quy trình đang chạy sử dụng hệ thống con 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

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 sẽ khắc phục vấn đề, trong đó Dalvik kiểm tra các quy tắc truy cập không chính xác 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 chế độ kiểm tra quyền truy cập, hãy gọi phương thức setAccessible() có 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 v7 hoặc thư viện recyclerview v7, thì bạn phải cập nhật ứng dụng để dùng lên những 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 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. Những ứng dụng từng hoạt động mà có cá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 xây dựng) có thể không tải được.

Cờ dlopen(3) RTLD_LOCAL hiện đã được triển khai chính xác. Hãy 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 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 mục nhập DT_NEEDED tham chiếu).

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 chia sẻ có tính năng chuyển vị trí văn bản, thì hệ thống sẽ hiển thị một 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 thư viện có tải được hay không, ứng dụng của bạn sẽ ghi lại lỗi dlopen(3) và bao gồm 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 này hiện thực hiện quy trình xác thực tệp APK nghiêm ngặt 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 tệp APK đó. Tệp APK phải được ký lại nếu có bất kỳ nội dung nào bị xoá.

Kết nối USB

Theo mặc định, 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ợ tương tác người dùng với thiết bị qua cổng USB, hãy lưu ý rằng hoạt động tương tác phải được bật một cách rõ ràng.

Các thay đổi đối với Android for Work

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

  • Thông tin liên hệ công việc trong bối cảnh cá nhân. Giờ đây, Nhật ký cuộc gọi của Google sẽ hiển thị danh bạ công việc khi người dùng xem các cuộc gọi trước đây. Nếu bạn đặt setCrossProfileCallerIdDisabled() thành true, thì danh bạ trên hồ sơ công việc sẽ bị ẩn trong Nhật ký cuộc gọi của Google Dialer. Danh bạ công việc chỉ có thể hiển thị cùng với danh bạ cá nhân cho 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 thiết lập là true.
  • Xoá cấu hình Wi-Fi: Cấu hình Wi-Fi mà Chủ sở hữu hồ sơ thêm vào (ví dụ: thông qua lệnh gọi đến phương thức addNetwork()) nay sẽ bị xoá nếu hồ sơ công việc đó bị xoá.
  • Khoá cấu hình Wi-Fi: Người dùng sẽ không thể sửa đổi hoặc xoá mọi cấu hình Wi-Fi do Chủ sở hữu thiết bị đang hoạt động tạo 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á bất kỳ cấu hình Wi-Fi nào, bao gồm cả những cấu hình không do họ tạo.
  • Tải trình kiểm soát chính sách thiết bị xuống thông qua thêm Tài khoản Google: Khi một Tài khoản Google yêu cầu quản lý qua ứng dụng trình kiểm soát chính sách thiết bị (DPC) được thêm vào một thiết bị bên ngoài bối cảnh được quản lý, thì quy trình thêm tài khoản giờ đây sẽ nhắc người dùng cài đặt WPC phù hợp. Hành vi này cũng áp dụng cho những 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 các 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 đối với người dùng gọi. Việc gọi phương thức này từ hồ sơ được quản lý 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ó sẵn 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ế bảo vệ bàn phím sau:
    • 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 ứng dụng của người dùng cụ thể đang chạy ở nền trước.
    • EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM hiện mặc định là SHA-256. SHA-1 vẫn được hỗ trợ cho 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 tạo thiết bị tồn tại trong Android 6.0 (API cấp 23) nay bị xoá.
    • EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS bị xoá để cấp phép khi bật NFC không thể mở khoá thiết bị được bảo vệ đã đặ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 dữ liệu bổ sung EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE để truyền dữ liệu đến ứng dụng của chủ sở hữu thiết bị trong khi cấp phép NFC của thiết bị được quản lý.
    • API Android for Work được tối ưu hoá cho các quyền khi bắt đầu chạy M, bao gồm cả hồ sơ Công việc, lớp hỗ trợ và các quyền khác. Các API quyền DevicePolicyManager mới không ảnh hưởng đến các ứng dụng trước M.
    • Khi người dùng rời 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ặc ACTION_PROVISION_MANAGED_DEVICE, hệ thống sẽ trả về mã kết quả RESULT_CANCELED.
  • Thay đổi đối với các API khá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: