Android6.0 运行权限的理解以及封装于基类的用法

来源:互联网 发布:知乎客户端电脑版下载 编辑:程序博客网 时间:2024/05/22 17:01

Android6.0后,对于权限有了更严格的管控,在6.0之前只要AndroidManifest中注册即可,但是6.0之后,还是沿用之前的方法,就会出现一系列的问题。一旦用到需要用到权限方面的问题的时候,只要你没有运行时的去检测权限是否开启,就很有可能crash。

其中有一种偷懒的手段,便是将AndroidManifest的targetSdkVersion设置在小于23的范围内,这样仅仅只要和以前一样,在AndroidMainfest中注册即可。但是随着Android快速的发展,将targetSdkVersion局限在23以下,这绝对不是一个好的开发人员,仅仅是为了完成工作的话,可是会被同行鄙视的哦=。=

所以我们就来探索一下这个必须要学会的技能,以及进一步的封装后,方便使用,也是作为程序员必要的手段吧!

首先我们可以看下原汁原味的写法:

  @Override    public void onClick(View v) {        if (!(checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED)) {            requestCameraPermission();        }    }    private static final int REQUEST_PERMISSION_CAMERA_CODE = 1;    private void requestCameraPermission() {        requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_PERMISSION_CAMERA_CODE);    }    @Override    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {        super.onRequestPermissionsResult(requestCode, permissions, grantResults);        if (requestCode == REQUEST_PERMISSION_CAMERA_CODE) {            int grantResult = grantResults[0];            boolean granted = grantResult == PackageManager.PERMISSION_GRANTED;            Log.i(LOGTAG, "onRequestPermissionsResult granted=" + granted);        }    }

这是一个请求相机权限的代码,首先请求对相机权限,用户进行权限选择后,通过回调判断用户是否授此功能,来进行不同的操作。

乍一看 ,代码并不是很多,但若是每个activity都需要进行授权功能,就会觉得代码开始冗余了。java中提到,相同的代码,不要超过2次,这也是封装思想。你也可以当cv战士,但这对你今后的成长,有害无益。思想不提神,写10年的代码,也不会进步。

所以接下来我们来封装一下吧,先贴一下整个代码:

public class BaseActivity extends AppCompatActivity {    /**     * (23以及之后需要运行时动态监测的权限)     * 身体传感器     * 日历     * 摄像头     * 通讯录     * 地理位置     * 麦克风     * 电话     * 短信     * 存储空间     */    public static final int REQUEST_CODE = 0;    private String[] permissions;    public interface PermissionCallBackListening {        void permissionGranted();        void permissionDenied();    }    //回调接口,暴露接口给用户操作    public PermissionCallBackListening listening;    //PermissionCallBackListening的实现类,本身也是一个抽象类,可进行部分操作    abstract class SimplepermiassionCallBackListening implements PermissionCallBackListening {        @Override        public void permissionDenied() {        }    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);    }    /**     * 设置有多少权限需要加入提示(大于sdk23可用)     */    public void setPermissions(String[] permissions, PermissionCallBackListening listening) {        this.permissions = permissions;        this.listening = listening;                if(permissions.length==0)            return;            requestPermissions();    }    @Override    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {        super.onRequestPermissionsResult(requestCode, permissions, grantResults);        if (requestCode == REQUEST_CODE) {            if (userGrantedAllPermissions(grantResults)) {                // 授权成功、                listening.permissionGranted();            } else {                // 授权失败                listening.permissionDenied();            }        }    }    /**     * 对用户进行授权请求     */    public void requestPermissions() {        ActivityCompat.requestPermissions(this, permissions,                REQUEST_CODE);    }    /**     * 判断用户是否全都点击了授权     */    public boolean userGrantedAllPermissions(@NonNull int[] grantResults) {        int length = grantResults.length;        for (int i = 0; i < length; i++) {            // TODO: 2016/10/14            if (!(grantResults[i] == PackageManager.PERMISSION_GRANTED)) {                return false;            }        }        return true;    }}

这里介绍下2个对象,PermissionCallBackListening和SimplepermiassionCallBackListening,一个用户暴露给用户操作,一个是对PermissionCallBackListening的二次封装。主要介绍下第二个对象,Simple类的诞生主要是为了开发者对于权限失败后进行统一处理,不需要在activity内在进行一次重写。这个看需求,若是要统一处理,就用;单一处理,直接用第一个。代码如下:

 //没有Simple类实现时,必须要重写2个方法        findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                setPermissions(permissions, new PermissionCallBackListening() {                    @Override                    public void permissionGranted() {                        Toast.makeText(MainActivity.this, "授权成功", Toast.LENGTH_SHORT).show();                        //拍照存储操作                        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);                        startActivityForResult(intent, 2);                    }                    @Override                    public void permissionDenied() {                        Toast.makeText(MainActivity.this, "未授权成功", Toast.LENGTH_SHORT).show();                    }                });            }        });        //有Simple类实现时,只需要重写一个方法。当申请权限失败的时候,可以在simple类进行统一处理        setPermissions(permissions, new SimplepermiassionCallBackListening() {            @Override            public void permissionGranted() {            }        });

一旦将上述封装到基类,对于后面继承此基类的子Activity或者也可以写到fragment的基类中,用起来都是非常方便的。