12/08/2018, 10:21

Introduce Permissions on the Android M

Android M Developer Preview giới thiệu một mô hình permission mới cho ứng dụng trong quá trình người dùng cài đặt và nâng cấp các ứng dụng. Nếu một ứng dụng chạy trên nền tảng Android M Preview có hỗ trợ mô hình permission mới, người dùng không phải cung cấp bất cứ permission nào khi cài đặt và ...

Android M Developer Preview giới thiệu một mô hình permission mới cho ứng dụng trong quá trình người dùng cài đặt và nâng cấp các ứng dụng. Nếu một ứng dụng chạy trên nền tảng Android M Preview có hỗ trợ mô hình permission mới, người dùng không phải cung cấp bất cứ permission nào khi cài đặt và nâng cấp ứng dụng. Thay vào đó, ứng dụng yêu cầu các permission cần thiết và hệ thống sẽ hiển thị một hộp thoại tới người dùng để yêu cầu permission.

Nếu một ứng dụng hỗ trợ mô hình permission mới, nó vẫn có thể được cài đặt và chạy trên các thiết bị chạy phiên bản thấp hơn Android M và sử dụng mô hình permission cũ trên các thiết bị này.

1. Overview

Sau đây là những key components của mô hình permission mới này:

  • Declaring Permissions: Ứng dụng khai báo tất cả các permission nó cần trong manifest giống như các nền tảng Android trước đây.
  • Permission Groups: Các permission được phân chia thành các nhóm permission, dựa trên chức năng của chúng. Ví dụ: nhóm permission CONTACTS bao gồm các permission đọc, ghi thông tin contact và profile của người dùng.
  • Limited Permissions Granted at Install Time (Giới hạn các permission được cung cấp khi cài đặt): Khi người dùng cài đặt hoặc cập nhật ứng dụng, hệ thống cung cấp cho ứng dụng tất cả các permission được yêu cầu thuộc vào PROTECTION_NORMAL. Ví dụ: alarm clock và internet là các permission thuộc PROTEXTION_NORMAL, vì vậy chúng tự động được cung cấp vào thời điểm cài đặt ứng dụng.
  • User Grants Permissions at Run-Time (Người dùng cung cấp permission vào thời điểm run-time): Khi ứng dụng yêu cầu một permission, hệ thống hiển thị một hộp thoại tới người dùng cho phép người dùng quyết định, sau đó gọi chức năng callback của ứng dụng để ghi nhận permission đó có được cung cấp hay không. Nếu người dùng cung cấp permission, ứng dụng sẽ được cấp phép cho các chức năng mà permission được khai báo trong manifest.

Mô hình permission này thay đổi cách ứng dụng chạy các tính năng mà cần có các permission. Sau đây là các hoạt động development nên được tuân theo với mô hình này:

  • Always Check for Permissions (Luôn luôn kiểm tra các permission): Khi ứng dụng cần thực hiện bất cứ hành động nào cần permission, nên kiểm tra permission đó đã được cung cấp cho hay chưa. Nếu chưa, phải yêu cầu cung cấp permission đó.
  • Handle Lack of Permissions Gracefully: Nếu ứng dụng không được cung cấp permission thích hợp, nó nên xử lý rõ ràng. Ví dụ, nếu permission cần cho một tính năng được thêm vào, ứng dụng có thể disable tính năng đó khi permission không được cung cấp. Nếu permission là thiết yếu cho các chức nâng chính của ứng dụng, ứng dụng có thể disable tất cả các chức năng hoặc đề nghị người dùng phải cung cấp permission này.
  • Permission are Revocable: Người dùng có thể hủy bỏ một permission của ứng dụng tại bất kỳ thời điểm nào. Nếu người dùng tắt một permission, ứng dụng không được thông báo. Vì vậy, ứng dụng nên kiểm tra permission trước khi thực hiện bất cứ hành động nào.

Lưu ý: Nếu ứng dụng hướng tới Android M Developer Preview, nó phải sử dụng mô hình permission mới.

System apps and signature permissions

Thông thường, khi người dùng cài đặt một ứng dụng, hệ thống chỉ cung cấp các permission PROTEXTION_NORMAL. Tuy nhiên, trong một số trường hợp, hệ thống cung cấp thêm các permission:

  • Nếu ứng dụng là một phần của hệ thống image, nó sẽ tự động cấp tất cả các permission được liệt kê trong manifest.
  • Nếu các ứng dụng yêu cầu các permission trong manifest thuộc PROTECTION_SIGNATURE, và ứng dụng được ký kết với các certificate tương tự như các ứng dụng mà khai báo các permission, hệ thống sẽ cấp các permission này khi cài đặt.

Trong cả hai trường hợp, người dùng vẫn có thể thu hồi các permission bất cứ lúc nào bằng cách vào màn hình Settings của hệ thống và chọn Apps>app_name>Permission. Ứng dụng nên tiếp tục kiểm tra các permission lúc run-time và yêu cầu chúng nếu cần thiết.

Forwards and backwards compatibility

Nếu một ứng dụng không được khai báo target tới Android M Developer Preview, ứng dụng vẫn tiếp tục sử dụng mô hình permission cũ thậm chí trên các thiết bị Android M Preview. Khi người dùng cài đặt ứng dụng, hệ thống yêu cầu người dùng cấp tất cả các permission được liệt kê trong manifest.

Lưu ý: Trên các thiết bị chạy Android M Developer Preview, một người dùng có thể tắt các permission của bất cứ ứng dụng nào từ màn hình Settings của ứng dụng (bao gồm cả các ứng dụng legacy). Nếu người dùng tắt các permission của một ứng dụng legacy, hệ thống âm thầm vô hiệu hóa các chức năng phù hợp. Khi ứng dụng cố gắng thực hiện một hoạt động mà đòi hỏi phải có permission đó, các hoạt động không nhất thiết phải gây ra một ngoại lệ. Thay vào đó, nó có thể trả về một tập hợp dữ liệu rỗng, báo ra một lỗi,... Ví dụ, nếu truy vấn một calendar mà không có permission, phương thức trả về một tập hợp dữ liệu rỗng.

Nếu cài đặt một ứng dụng sử dụng mô hình permission mới trên một thiết bị mà không cạy Android M Preview, hệ thống xử lý nó giống như bất kỳ ứng dụng khác: hệ thống yêu cầu người dùng cung cấp tất cả các permission được khai báo trong manifest tại thời điểm cài đặt ứng dụng.

Lưu ý: Đối với việc release phiên bản preview, phải thiết lập phiên bản minimum SDK là M Preview SDK để compile với preview SDK. Có nghĩa là không thể test các ứng dụng trên nền tảng cũ trong khi developer preview.

Permissions versus intents

Trong nhiều trường hợp, có thể lựa chọn giữa hai cách để ứng dụng thực hiện một tác vụ. Có thể yêu cầu permission để tự thực hiện hoạt động. Hoặc, có thể sử dụng intent để gọi một ứng dụng khác thực hiện tác vụ này.

Ví dụ, giả sử một ứng dụng cần chụp ảnh với camera của thiết bị. Ứng dụng đó có thể yêu cầu permission android.permission.CAMERA, cho phép ứng dụng có thể truy cập trực tiếp vào camera, sau đó sử dụng các API camera để điều khiển camera và chụp ảnh. Cách tiếp cận này cho phép ứng dụng kiểm soát đầy đủ quá trình chụp ảnh, và cho phép kết hợp camera UI vào trong ứng dụng.

Tuy nhiên, nếu không cần kiểm soát như vậy, có thể chỉ cần sử dụng một intent ACTION_IMAGE_CAPTURE để yêu cầu một hình ảnh. Khi start intent, người dùng sẽ được nhắc nhở để chọn một ứng dụng camera. Các ứng dụng máy ảnh trả về hình ảnh trong phương thức onActivityResult() của ứng dụng.

Tương tự như vậy, nếu cần thực hiện một cuộc gọi điện thoại, truy cập vào contact của người dùng bằng cách tạo một intent thích hợp hoặc có thể yêu cầu permission và truy cập trực tiếp vào các đối tượng thích hợp. Mỗi cách tiếp cận có ưu và nhược điểm riêng.

Nếu sử dụng Permission:

  • Ứng dụng có toàn quyền kiểm soát các trải nghiệm người dùng khi thực hiện các hoạt động. Tuy nhiên, kiểm soát rộng như vậy làm tăng thêm sự phức tạp của tác vụ, vì cần phải thiết kế một giao diện người dùng (UI) phù hợp.
  • Người dùng sẽ được nhắc nhở để cấp permission một lần, lần đầu tiên thực hiện hoạt động. Sau đó, ứng dụng có thể thực hiện các hoạt động mà không cần sự tương tác bổ sung từ người dùng. Tuy nhiên, nếu người dùng không cấp (hoặc thu hồi) permission, ứng dụng sẽ không thể thực hiện được các hoạt động.

Nếu sử dụng intent:

  • Không cần thiết kế giao diện người dùng cho các hoạt động. Các ứng dụng có sẵn được gọi bởi các intent, cung cấp giao diện người dùng. Tuy nhiên, điều này có nghĩa là không kiểm soát được trải nghiệm người dùng.
  • Nếu người dùng không có một ứng dụng mặc định cho các hoạt động được gọi bởi intent, hệ thống sẽ hiển thị hộp thoại cho phép người dùng chọn một ứng dụng.

2. Coding for Runtime Permissions

Enabling the new permissions model

Để enable mô hình permission mới trong Android M Developer Preview, thiết lập targetSdkVersion là "MNC" và compileSdkVersion là "android-MNC". Như vậy, sẽ enable tất cả các tính năng.

Đối với việc release bản preview, phải thiết lập minSdkVersion là "MNC" để compile với perview SDK.

Designating a permission for the M Preview only

Có thể sử dụng phần tử mới <uses-permission-sdk-m> trong manifest để cho biết rằng một permission chỉ cần thiết trên Android M Developer Preview. Nếu khai báo một permissin theo cách này, thì bất cứ khi nào ứng dụng được cài đặt trên thiết bị cũ hơn, hệ thống không nhắc nhở người dùng cung cấp permission cho ứng dụng. Với việc sử dụng <uses-permission-sdk-m>, có thể thêm các permission mới với các phiên bản updated của ứng dụng mà không bắt buộc người dùng cung cấp permission khi cài đặt các bản update.

Nếu ứng dụng đang chạy trên một thiết bị Android M Developer Preview, <uses-permission-sdk-m> cư xử giống như <uses-permission>. Hệ thống không nhắc nhở người dùng cung cấp bất kỳ permission khi cài đặt ứng dụng, và các ứng dụng yêu cầu permission khi cần thiết.

Prompting for permissions

Nếu ứng dụng sử dụng mô hình permission mới, người dùng sẽ không được yêu cầu cung cấp tất cả các permission khi ứng dụng được chạy lần đầu tiên trên thiết bị Android M Preview. Thay vào đó, ứng dụng chỉ yêu cầu permission khi cần thiết. Khi ứng dụng yêu cầu một permission, hệ thống hiển thị một hộp thoại cho người dùng lựa chọn.

Nếu ứng dụng chạy trên một thiết bị có sdk level 22 hoặc thấp hơn, ứng dụng sẽ sử dụng mô hình permission cũ. Khi người dùng cài đặt ứng dụng, sẽ được đề nghị cung cấp tất cả các permission mà ứng dụng khai báo trong manifest, ngoại trừ các permission được khai báo với phần tử <uses-permission-sdk-m>.

Check what platform the app is running on

Mô hình permission mới này chỉ hỗ trợ trên các thiết bị chạy Android M Developer Preview. Trước khi gọi bất kỳ phương thức sử dụng permission nào, ứng dụng cần xác thực nền tảng mà nó đang chạy bằng cách kiểm tra giá trị của Build.VERSION.CODENAME. Nếu thiết bị đang chạy Android M Developer Preview, giá trị của CODENAME là "MNC".

Check if the app has the needed permission

Khi người dùng cố gắng thực hiện một hành động mà yêu cầu một permission, ứng dụng sẽ kiểm tra xem hiện tại có được cấp permission để thực hiện thao tác đó hay không. Để làm điều này, ứng dụng gọi phương thức Context.checkSelfPermission(permission_name). Ứng dụng sẽ thực hiện kiểm tra này ngay cả khi nó biết người dùng đã cấp permission đó, bởi vì người dùng có thể hủy bỏ các permission của ứng dụng tại bất kỳ thời điểm nào. Ví dụ, nếu người dùng muốn sử dụng một ứng dụng để chụp ảnh, nó sẽ gọi Context.checkSelfPermission(Manifest.permission.CAMERA).

Request permissions if necessary

Nếu ứng dụng chưa được cung cấp các permission cần thiết, nó sẽ gọi phương thức Activity.requestPermissions(String[], int) để yêu cầu các permission thích hợp.Các tham số được truyền vào là các permission và số nguyên "request code". Phương thức này là không đồng bộ, nó được return ngay lập tức, sau khi người dùng tương tác với hộp thoại, hệ thống sẽ gọi một phương thức callback với result trả về, thông qua "request code" đã truyền vào phương thức requestPermission().

Ví dụ, đoạn code sau sẽ kiểm tra ứng dụng có permission đọc contact người dùng hay không, và yêu cầu permission này nếu cần thiết:

    if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {

    requestPermissions(new String[]{Manifest.permission.READ_CONTACTS},
            MY_PERMISSIONS_REQUEST_READ_CONTACTS);

    // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
    // app-defined int constant

    return;

	}

Handle the permissions request response

Khi một ứng dụng yêu cầu các permission, hệ thống sẽ hiển thị một hộp thoại cho người dùng. Khi người dùng responds, hệ thống sẽ gọi phương thức Activity.onRequestPermissionResult(int, String[], int[]). Ứng dụng cần override phương thức này. Ví dụ, nếu ứng dụng yêu cầu truy cập READ_CONTACTS:

@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // permission was granted, yay! do the
                // calendar task you need to do.
            } else {
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }
        // other 'switch' lines to check for other
        // permissions this app might request
    }
}

Nếu người dùng cung cấp một permission, hệ thống sẽ cung cấp cho ứng dụng tất cả các permission được đăng ký trong manifest. Nếu người dùng từ chối yêu cầu, ứng dụng nên có hành động thích hợp. Ví dụ, có thể disable bất kỳ menu action nào mà phụ thuộc vào permission này.

Khi hệ thống yêu cầu người dùng cấp một permission, người dùng có thể lựa chọn cho hệ thống không yêu cầu permission đó lại nữa. Khi đó, một ứng dụng sử dụng phương thức requestPermission() để yêu cầu sự cho phép đó, hệ thống ngay lập tức từ chối yêu cầu. Trong trường hợp này, hệ thống gọi phương thức onRequestPermissionResult() giống như cách người dùng từ chối yêu cầu thông qua hộp thoại.

0