1. 程式人生 > >android開發6.0許可權適配

android開發6.0許可權適配

寫部落格只是為了方便記憶,希望自己能夠堅持下去。

在android開發中,如果專案的targetSdkVersion >= 23,在手機版本為android6.0+的手機上執行時,某些危險的許可權需要使用者授權,如果使用者不同意,而直接執行某些程式碼,會造成程式的崩潰。
這裡寫圖片描述

Runtime Permissions
This release introduces a new permissions model, where users can now directly manage app permissions at runtime. This model gives users improved visibility and control over permissions, while streamlining the installation and auto-update processes for app developers. Users can grant or revoke permissions individually for installed apps.

On your apps that target Android 6.0 (API level 23) or higher, make sure to check for and request permissions at runtime. To determine if your app has been granted a permission, call the new checkSelfPermission() method. To request a permission, call the new requestPermissions() method. Even if your app is not targeting Android 6.0 (API level 23), you should test your app under the new permissions model.

For details on supporting the new permissions model in your app, see Working with System Permissions. For tips on how to assess the impact on your app, see Permissions Best Practices.
這是官網的英文介紹。詳細https://developer.android.com/training/permissions/best-practices.html#testing

下面寫一個小例子來說明一下用法。(獲取打電話的許可權)

public void onc(View v) {

        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.CALL_PHONE)
                == PackageManager.PERMISSION_GRANTED) {//使用者同意權限
            call();

        } else {//使用者不同意,向用戶請求許可權
            if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CALL_PHONE)) {
                AlertDialog dialog = new AlertDialog.Builder(this)
                        .setMessage("撥打電話需要賦予許可權,不開啟將無法撥打!")
                        .setPositiveButton("確定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CALL_PHONE}, 1);

                            }
                        })
                        .setNegativeButton("取消", null).create();
                dialog.show();
                return;
            }
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, 1);
        }


    }

    public void call() {
        Intent intent = new Intent(Intent.ACTION_CALL);
        Uri data = Uri.parse("tel:" + "10086");
        intent.setData(data);
        startActivity(intent);
    }

這裡有3個方法

  • checkSelfPermission 判斷許可權是否授權
    (PackageManager.PERMISSION_GRANTED表示已同意,PackageManager.PERMISSION_DENIED未同意)
  • shouldShowRequestPermissionRationale 如果使用者已經拒絕過1次,返回true,其他情況返回false
    主要使用者給使用者提示,當用戶拒絕第一次後,提示許可權用途,當用戶再次拒絕並勾上不再詢問後,提示手動開啟許可權。
  • requestPermissions 申請許可權

申請許可權回撥

 @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {


        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            call();

        } else {
            //使用者勾選了不再詢問
            //提示使用者手動開啟許可權
            if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CALL_PHONE)) {
                AlertDialog dialog = new AlertDialog.Builder(this)
                        .setMessage("撥打電話的許可權已被禁止,請手動開啟")
                        .setPositiveButton("確定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                Intent localIntent = new Intent();
                                localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                if (Build.VERSION.SDK_INT >= 9) {
                                    localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
                                    localIntent.setData(Uri.fromParts("package", MainActivity.this.getPackageName(), null));
                                } else if (Build.VERSION.SDK_INT <= 8) {
                                    localIntent.setAction(Intent.ACTION_VIEW);
                                    localIntent.setClassName("com.android.settings", "com.android.settings.InstalledAppDetails");
                                    localIntent.putExtra("com.android.settings.ApplicationPkgName", MainActivity.this.getPackageName());
                                }
                                startActivity(localIntent);

                            }
                        })
                        .setNegativeButton("取消", null).create();
                dialog.show();

            }
        }


        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

最後看一下效果
這裡寫圖片描述

附錄–危險許可權
Permission Group Permissions
android.permission-group.CALENDAR
android.permission.READ_CALENDAR
android.permission.WRITE_CALENDAR

android.permission-group.CAMERA
android.permission.CAMERA

android.permission-group.CONTACTS
android.permission.READ_CONTACTS
android.permission.WRITE_CONTACTS
android.permission.GET_ACCOUNTS

android.permission-group.LOCATION
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_COARSE_LOCATION

android.permission-group.MICROPHONE
android.permission.RECORD_AUDIO

android.permission-group.PHONE
android.permission.READ_PHONE_STATE
android.permission.CALL_PHONE
android.permission.READ_CALL_LOG
android.permission.WRITE_CALL_LOG
com.android.voicemail.permission.ADD_VOICEMAIL
android.permission.USE_SIP
android.permission.PROCESS_OUTGOING_CALLS

android.permission-group.SENSORS
android.permission.BODY_SENSORS

android.permission-group.SMS
android.permission.SEND_SMS
android.permission.RECEIVE_SMS
android.permission.READ_SMS
android.permission.RECEIVE_WAP_PUSH
android.permission.RECEIVE_MMS
android.permission.READ_CELL_BROADCASTS

android.permission-group.STORAGE
android.permission.READ_EXTERNAL_STORAGE
android.permission.WRITE_EXTERNAL_STORAGE