关于Android6.0运行时权限的总结(干货)。

三种对运行时权限的封装:

1.用一个透明的Activity来实现


2.用Fragment来实现 (在Fragment中实现的)

https://github.com/tbruyelle/RxPermissions

3.在BaseActivity来实现(主要介绍)

步骤:

1.重写BaseActivity

2.需要的Activity调用

基类:

public class BaseActivity extends AppCompatActivity {

    private  PermissionListener  mPermissionListener;

    //运行时权限的请求方法的封装

    public void requestRuntimePermission(String[] permissions,PermissionListener permissionListener) {

        mPermissionListener = permissionListener;

        List<String> permissionList = new ArrayList<>();

        //判断版本是否大于等于6.0

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

            //循环遍历权限数组

            for (String permission : permissions) {

                if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {

                    //若果没有同意就添加到集合中

                    permissionList.add(permission);

                }

            }

            //判断集合是否为空

            if (!permissionList.isEmpty()) {

                //不为空,就说明有权限没有同意,需要同意

                ActivityCompat.requestPermissions(this, permissionList.toArray(new String[permissionList.size()]), 1);

            } else {//都同意了

            }

        }

    }

    @Override

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

        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        switch (requestCode) {

            case 1:

                if (grantResults.length>0) {//权限不为空

                    List<String> deniedPermissionList = new ArrayList<>();

                    //循环遍历整个权限回调数组吧不同意的添加到集合中去

                    for(int i= 0; i< grantResults.length;i++){

                        int grantResult = grantResults[i];

                        String permission = permissions[i];

                        if(grantResult != PackageManager.PERMISSION_GRANTED) {

                            deniedPermissionList.add(permission);

                        }

                    }

                     //如果集合为空,就走回调的同意方法

                    if(deniedPermissionList.isEmpty()){

                        // Permission Granted

                        mPermissionListener.granted();

                    }else{//如果集合不为空,就走回调的拒绝方法

                        // Permission denied

                        mPermissionListener.denied(deniedPermissionList);

                    }

                }

                break;

            default:

                break;

        }

    }

}

回调接口:

public interface  PermissionListener  {

    void granted();

    void denied(List<String> deniedList );

}

2.应用:

在MainActivity中用到权限申请,要继承BaseActivity 

public class MainActivity extends BaseActivity 

在用到的地方(例如点击某个按钮):代码:

case R.id.text_bt3:

    //运行时权限

    requestRuntimePermission(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.CAMERA}, new PermissionListener() {

        @Override

        public void granted() {

            Toast.makeText(MainActivity.this, "所有权限都同意了", Toast.LENGTH_SHORT).show();

        }

        @Override

        public void denied(List<String> deniedList) {

            for(String denied:deniedList ){

                Toast.makeText(MainActivity.this, denied+"权限被拒绝,请在设置中打开相关权限", Toast.LENGTH_SHORT).show();

            }

        }

    });

    break;

-------------------------------------------------------------------------------------------------------------------------------------------

以上封装只能在Activity中使用,为了扩展性再次优化封装(可以普通类使用)

修改步骤:

1.BaseActivity 中的方法requestRuntimePermission改成static静态的

2.由于静态后找不到上下文环境,所有新建一个Activity的管理类ActivityCollector类

3

1.BaseActivity中

代码如下:

public class BaseActivity extends AppCompatActivity {

    private  static  PermissionListener mPermissionListener;

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

     ActivityCollector.addActivity(this);

}

@Override

protected void onDestroy() {

    super.onDestroy();

    ActivityCollector.removeActivity(this);

}

    //运行时权限的请求方法的封装

    public  static  void requestRuntimePermission(String[] permissions,PermissionListener permissionListener) {

         //获得栈顶Activity

        Activity topActivity = ActivityCollector.getTopActivity();

        if(topActivity == null){//栈顶为空直接返回

            return;

        }

        mPermissionListener = permissionListener;

        List<String> permissionList = new ArrayList<>();

        //判断版本是否大于等于6.0

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

            //循环遍历权限数组

            for (String permission : permissions) {

                if (ContextCompat.checkSelfPermission( topActivity , permission) != PackageManager.PERMISSION_GRANTED) {

                    //若果没有同意就添加到集合中

                    permissionList.add(permission);

                }

            }

            //判断集合是否为空

            if (!permissionList.isEmpty()) {

                //不为空,就说明有权限没有同意,需要同意

                ActivityCompat.requestPermissions( topActivity , permissionList.toArray(new String[permissionList.size()]), 1);

            } else {//都同意了

            }

        }

    }

2新建的ActivityCollector

public class ActivityCollector {

    private static List<Activity> activityList = new ArrayList<>();

    //添加

    public static void addActivity(Activity activity) {

        activityList.add(activity);

    }

    //删除

    public static void removeActivity(Activity activity) {

        activityList.remove(activity);

    }

    //获得栈顶Activity

    public static Activity getTopActivity() {

        if (activityList.isEmpty()) {

            return null;

        } else {

            return activityList.get(activityList.size() - 1);

        }

    }

    

}

调用:

在一个一般的类中:

直接在类中调用就OK

BaseActivity. requestRuntimePermission(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.CAMERA}, new PermissionListener() {

    @Override

    public void granted() {

        

    }

    @Override

    public void denied(List<String> deniedList) {

    }

});

拓展;基于第一种的添加了小于6.0版本的判断:

行时权限的请求方法的封装

public class BaseActivity extends AppCompatActivity {

    private  PermissionListener  mPermissionListener;

public void requestRuntimePermission(String[] permissions, PermissionListener permissionListener) {

    mPermissionListener = permissionListener;

    List<String> permissionList = new ArrayList<>();

    //判断版本是否大于等于6.0

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

        //循环遍历权限数组

        for (String permission : permissions) {

            if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {

                //若果没有同意就添加到集合中

                permissionList.add(permission);

            }

        }

        //判断集合是否为空

        if (!permissionList.isEmpty()) {

            //不为空,就说明有权限没有同意,需要同意

            ActivityCompat.requestPermissions(this, permissionList.toArray(new String[permissionList.size()]), 1);

        } else {//都同意了

            mPermissionListener.granted();

        }

    } else {

        List<String> deniedPermissionList = new ArrayList<>();

        List p = Arrays.asList(permissions);

        if (p.contains(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {

            try {

                File file = new File(DirectoryBuilder.DIR_FILE + "temp");

                file.createNewFile();

                file.delete();

            } catch (Exception e) {

                deniedPermissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);

            }

        }

        if (p.contains(Manifest.permission.CAMERA)) {

            try {

                Camera camera = Camera.open(0);

                camera.release();

            } catch (Exception e) {

                deniedPermissionList.add(Manifest.permission.CAMERA);

            }

        }

        if (p.contains(Manifest.permission.RECORD_AUDIO)) {

            VoiceChatRecorder voiceRecord = new VoiceChatRecorder();

            boolean isHasPermission = voiceRecord.isHasPermission(this);

            if (!isHasPermission) {

                deniedPermissionList.add(Manifest.permission.RECORD_AUDIO);

            }

        }

        if (deniedPermissionList.size() > 0) {

            mPermissionListener.denied(deniedPermissionList);

        } else {

            mPermissionListener.granted();

        }

    }

}

@Override

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

    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    switch (requestCode) {

        case 1:

            if (grantResults.length > 0) {//权限不为空

                List<String> deniedPermissionList = new ArrayList<>();

                //循环遍历整个权限回调数组吧不同意的添加到集合中去

                for (int i = 0; i < grantResults.length; i++) {

                    int grantResult = grantResults[i];

                    String permission = permissions[i];

                    if (grantResult != PackageManager.PERMISSION_GRANTED) {

                        deniedPermissionList.add(permission);

                    }

                }

                //如果集合为空,就走回调的同意方法

                if (deniedPermissionList.isEmpty()) {

                    // Permission Granted

                    mPermissionListener.granted();

                } else {//如果集合不为空,就走回调的拒绝方法

                    // Permission denied

                    mPermissionListener.denied(deniedPermissionList);

                }

            }

            break;

        default:

            break;

    }

}

//权限回调接口

public interface PermissionListener {

    void granted();

    void denied(List<String> deniedList);

}

}

最后感谢郭神的视频:

视频地址: