Requesting Permissions trên android M

Tại hội nghị I/O 2015 từ 28 đến 29/5 vừa qua. Google đã cho ra mắt phiên bản mới nhất của hệ điều hành Android - version 6.0 với tên gọi là Android Marshmallow (hay còn gọi là Android M). Bên cạnh những chức năng nổi bật mới như là: Chrome Custom Tabs, App Links, Android Pay, Google “Now on Tap”, ... thì một trong những tính năng được developer quan tâm nhất là chức năng Granular App Permissions. Từ phiên bản Android 6.0 sẽ được tích hợp chức năng kiểm soát quyền truy cập cho các ứng dụng, quyền truy cập được gom thành các nhóm (permission group), với tính năng mới này người dùng có thể thay đổi quyền truy cập của ứng dụng bất cứ khi nào từ menu Settings bên trong Hệ điều hành. Vì vậy các ứng dụng trên Android M cần phải check permission khi chạy để tránh trường hợp ứng dụng bị force close do thiếu một số permission cần thiết bị tắt bởi người dùng.

Dưới đây là một tut đơn giản giới thiệu về Requesting Permissions at Run Time trên Android M.

Khai báo Permission trong Manifest

Chú ý:

  • Permission được chia làm 2 loại: Normal and Dangerous Permissions
    • Normal: đây là những quyền không cần phải xin phép user khi sử dụng, hệ thống sẽ tự cấp phép cho các quyền này.
    • Dangerous: đây là những quyền phải xin phép user khi sử dụng, hệ thống không được phép tự động cấp phép cho các quyền này.
  • android.permission.GET_ACCOUNTS: đây là Permission thuộc loại Normal, không phải xin phép user, nhưng nó thuộc group CONTACTS bao gồm các permission: READ_CONTACTS, WRITE_CONTACT, và GET_ACCOUNTS là Permission thuộc loại Dangerous , do đó user có thể revoke group này tại settings của device, khi revoke 1 group thì mọi permission trong group cũng sẽ bị vô hiệu hoá, vì thế đây cũng là một Permission cần phải check trước khi sử dụng.

Trong tut mình sẽ khai báo một số Permission trong Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.app.framgiahoangngocdai.permissionandroidmtest" >

	// Khai báo các quyền cần sử dụng
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
	.....

</manifest>

Check Permission và RequestPermissions

Tại MainActivity ta viết một methold để kiểm tra các Permission thuộc loại dangerous đã được khai báo trong Manifest có được grant không, để thực hiện việc này ta sử dụng phương thức checkSelfPermission(), sau đó sử dụng phương thức requestPermissions() để RequestPermissions cần thiết.

private void checkPermission() {
        String[] listPermission = new String[] {android.Manifest.permission.GET_ACCOUNTS,
                android.Manifest.permission.READ_SMS,
                android.Manifest.permission.READ_PHONE_STATE};
        boolean isOn = false;

        if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.GET_ACCOUNTS) == PackageManager.PERMISSION_GRANTED) {
            textStatus1.setText("On");
        } else {
            textStatus1.setText("Off");
            isOn = true;
        }
        if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_SMS) == PackageManager.PERMISSION_GRANTED) {
            textStatus2.setText("On");
        } else {
            textStatus2.setText("Off");
            isOn = true;
        }
        if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
            textStatus3.setText("On");
        } else {
            textStatus3.setText("Off");
            isOn = true;
        }
        if (isOn){
            ActivityCompat.requestPermissions(this, listPermission, MY_PERMISSIONS_REQUEST);
        }
    }

Xử lý permissions request response

Khi request permission hệ thống sẽ xuất hiện một dialog thông báo để user lựa chọn chấp nhận hay từ chối permission xin cấp tương ứng. Để xử lý các phản hồi của user ta có thể Override phương thức onRequestPermissionsResult().

	@Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == 1) {
            for (int i = 0; i < grantResults.length; i++) {
                switch (i) {
                    case 0:
                        if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                            textStatus1.setText("On");
                        } else {
                            textStatus1.setText("Off");
                        }
                        break;
                    case 1:
                        if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                            textStatus2.setText("On");
                        } else {
                            textStatus2.setText("Off");
                        }
                        break;
                    case 2:
                        if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                            textStatus3.setText("On");
                        } else {
                            textStatus3.setText("Off");
                        }
                        break;
                    default:
                        break;
                }
            }
        }
    }

Chú ý: bạn có thể sử dụng methold shouldShowRequestPermissionRationale() để xem có cần phải hiện dialog request cho user. Phương thức này trả về true nếu ứng dụng đã yêu cầu sự cho phép này trước đây và người dùng từ chối yêu cầu, trả về false nếu người dùng đã từ chối yêu cầu sự cho phép trong quá khứ và đã chọn lựa chọn "Đừng hỏi nữa" trong dialog request. Phương thức này cũng trả về false nếu một chính sách thiết bị nghiêm cấm các ứng dụng từ việc có sự cho phép đó.

rp12-2.png

rp12-4.png

rp12-5.png

Link demo github: https://github.com/GreatHoang/PermissionAndroidMtest