运行权限


android在6.0版本引入了运行权限,当你在进行敏感操作的时候,需要用户授予权限才能进行下一步的操作。就是app不能直接操作必须要用户同意。比如:联系人,app不能直接获取用户手机上的联系人信息,必须要用户授予app权限才可以。这样就保护了用户的个人信息。

但是,这种给开发者带来了点麻烦,必须在多敲几行代码了

权限分为正常权限、危险权限和特殊权限:

 目前危险权限有:

android开发 申请权限弹窗 安卓开发 权限_android



特殊权限: SYSTEM_ALERT_WINDOW 和  WRITE_SETTINGS  

只有危险权限才要用户去授权;其余权限不用,app可以直接操作。

特殊权限需要手动去开启,这个更可怕;

看看代码:


在activity中创建的方法,中间代码注销掉了,因为,当你安装app后第一返回的是false,然后点击拒绝权限后,在请求返回true,如果你勾选不在提醒,然后在拒绝权限,再次请求返回的是false。而且无法填出对话框了。所以这块很蛋疼的。与其这样还不如不要这些判断代码,当检查没有权限的时候,直接去请求权限。


public void checkPermission()
    {
        //检查是否有权限
        if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)!= PackageManager.PERMISSION_GRANTED)
        {
            //如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true。
            //如果用户在过去拒绝了权限请求,并在权限请求系统对话框中选择了 Don't ask again 选项,此方法将返回 false。如果设备规范禁止应用具有该权限,此方法也会返回 false。
//            if(ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.READ_CONTACTS))
//            {
//                Log.e("ok",true+"");
//                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 0);
//            }else{
//                Log.e("ok",false+"");
//                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 0);
//            }


              ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, 0);
        }
    }


复写acitivity的这个方法,请求权限成功后作出的相应,如果勾选了不在提醒的情况下,在去请求权限的话,是不会弹出对话框的,所以要手动的去开启权限了。

@Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case 0:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    //已获取权限

                    //响应事件
                } else {
                    //权限被拒绝
                    Intent intent = getAppDetailSettingIntent(MainActivity.this);
                    startActivity(intent);
                }

                break;
        }
    }
        /**
         * 获取应用详情页面intent
         *
         * @return
         */
    public Intent getAppDetailSettingIntent(Context context) {
        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", context.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", context.getPackageName());
        }
        return localIntent;
    }


多个权限同时申请的时候:


public class RequestActivity extends AppCompatActivity{
    private String[] permission = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.READ_PHONE_STATE
            };
    private ArrayList<String> list=new ArrayList<>();
    private String[] objects;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_request_permission);
        check();
        checkPermission();
    }

    public void click(View view){
        Intent intent = getAppDetailSettingIntent(RequestActivity.this);
        startActivity(intent);
    }

    public void check(){
        for(int i=0;i<permission.length;i++){
            //如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true。需要走申请权限的流程;
            //如果用户在过去拒绝了权限请求,并在权限请求系统对话框中选择了 Don't ask again 选项,此方法将返回 false。如果设备规范禁止应用具有该权限,此方法也会返回 false。
            //-1是没有权限,可以申请权限;选择了 Don't ask again 选项则直接回调结果;
            //0 是已经有权限了;
            //
            int i1 = ContextCompat.checkSelfPermission(this, permission[i]);
            Log.e("TAG","quanxianjieguo:"+i1);
            if(ContextCompat.checkSelfPermission(this, permission[i])== PackageManager.PERMISSION_DENIED)
            {
                list.add(permission[i]);
            }
        }
        objects=new String[list.size()];
        for(int i=0;i<list.size();i++){
            objects[i]=list.get(i);
        }
    }

    public void checkPermission()
    {
        ActivityCompat.requestPermissions(this, objects, 0);
        Log.e("TAG","0000000000000");
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case 0:
                for(int i=0;i<permissions.length;i++){
                    Log.e("TAG","权限:"+permissions[i]+"----结果:"+grantResults[i]);

                    if (grantResults.length > 0 && grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                        Log.e("TAG","权限允许");
                        //已获取权限

                        //响应事件
                    } else if(grantResults[i] == PackageManager.PERMISSION_DENIED){
                        //ActivityCompat.shouldShowRequestPermissionRationale 返回false标识勾选了不在询问;
                        if(!ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])){
                            //勾选了不在询问;//当同时申请多个权限的时候,这里会调用多次,需要注意;
                            Intent intent = getAppDetailSettingIntent(RequestActivity.this);
                            startActivity(intent);
                        }else{
                            //权限被拒绝
                            Log.e("TAG","权限拒绝");
                        }
                    }
                }
                break;
        }
    }


在fragment中申请权限的时候:


调用fragment的申请权限的方法:


requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO}, 0);

才能会掉到 fragment中的结果方法;