安卓6.0系统逐渐普及,对于安卓6.0中的SDK也有了一些变化,查看具体的详情请参考官方文档http://developer.android.com/intl/zh-cn/about/versions/marshmallow/android-6.0-changes.html,当然了,运行时权限也是SDK所发生的变化之一,那么本文介绍一下申请动态权限的步骤及简单的封装。
对于安卓6.0系统所持有的动态权限,主要是分为两种:
1.普通权限,也就是说不会影响到用户的隐私的权限,比如说访问网络(大家都知道,几乎每一个APP都需要有访问网络的需求,所以说访问网络也是必不可少的),还有就是手 机震动等都是普通权限
2.危险权限,也就是说会影响到用户隐私的权限,比如说打电话,访问通讯录等有关用户隐私的权限都是属于危险权限,安卓6.0规定有24中危险权限,如下图:
1.MainActivity布局文件
<Button android:onClick="but" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="请求打电话权限"/>2.Manifest清单文件中加入权限<uses-permission android:name="android.permission.CALL_PHONE" />3.Activity中的逻辑代码public void but(View v){//判断是否已经申请过动态权限了---按钮的点击事件中的逻辑代码/** * 第一个参数为上下文 * 第二个参数为要申请的权限 * */if(ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE)!= PackageManager.PERMISSION_GRANTED){ //没有申请权限,则去申请权限 /** * 第二个参数为要申请权限的数据 * 第三个参数为表示是在哪一个地方申请的权限,也就是标识 */ ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CALL_PHONE},1);}else{ //权限申请过了,执行打电话的方法 myPhone(); }}//拨打电话的方法public void myPhone(){ try{ //申请过权限,拨打电话 Intent intent=new Intent(Intent.ACTION_CALL); //指定电话号码 intent.setData(Uri.parse("tel://13121980161")); startActivity(intent); }catch (SecurityException e){ e.PRintStackTrace(); }}//判断网络是否请求成功了---重写Activity的onRequestPermissionsResult 方法@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { //此处判断的是上方的标记“1” case 1: //判断是否申请权限成功 if(grantResults.length>0&&grantResults[0]== PackageManager.PERMISSION_GRANTED){ //权限申请成功,执行打电话的方法 myPhone(); Toast.makeText(this, "申请权限成功....", Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(this, "申请权限失败....", Toast.LENGTH_SHORT).show(); } break; default: break; } }四、实际案例Demo-申请多个权限------打电话、访问sd卡
1.在上一个Demo基础上再添加一个访问sd卡的权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />2.Button按钮中的逻辑
public void but(View view) { //申请多个权限,首先要创建一个集合,添加几个权限就必须做几次判断 //判断如果申请过的权限就不在添加到集合当中重复申请了 ArrayList<String> permissionList=new ArrayList<>(); if(ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE)!= PackageManager.PERMISSION_GRANTED){ //添加到集合当中 permissionList.add(Manifest.permission.CALL_PHONE); } if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){ //添加到集合当中 permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); } //判断集合是否为空,不为空则请求权限 if(!permissionList.isEmpty()){ ActivityCompat.requestPermissions(this,permissionList.toArray( new String[permissionList.size()]),1); }else{ doSomething();//此方法中就是一个Toast }}3.重写ActivityonRequestPermissionsResult 方法的逻辑@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { //此处判断的是上方的标记“1” case 1: //判断将要申请的权限大于0个,则申请权限 if(grantResults.length>0){ for(int grantResult:grantResults){ if(grantResult!=PackageManager.PERMISSION_GRANTED){ Toast.makeText(this, "某一个权限被拒绝了!", Toast.LENGTH_SHORT).show(); return; } } doSomething();//此方法中就是一个Toast } break; default: break; } }五、实际案例Demo-申请运行时权限之3种封装
1.使用一个透明的Activity,当需要申请危险权限时,则创建此Activity,申请之后就可以销毁掉。
2.使用RxPermission也可以对运行时权限进行封装
3.使用一个BaseActivity进行封装,在这里,就主要提供一下用BaseActivity封装的方法
public class BaseActivity extends AppCompatActivity { //1.如何让调用者知道权限是否申请成功 回调 //2.如果不是在Activity中调用,所需的上下文怎么处理 可以通过让所有的创建的Activity都 // 存到一个集合当中,取其栈顶的Activity作为上下文 private static PermissioLitener mLitener; private static Activity topActivity; public static void requestRuntimePermision(String[] permission, PermissioLitener permissioLitener){ //传过来的回调监听 mLitener=permissioLitener; //获取当前的栈顶Activity topActivity = listActivity.getActivity(); ArrayList<String> list=new ArrayList<>(); for (String per:permission) { //如果当前的这个权限没有被申请 if(ContextCompat.checkSelfPermission(topActivity,per)!= PackageManager.PERMISSION_GRANTED){ //添加到list集合当中 list.add(per); } } //判断list集合是否为空,不为空则申请权限 if(!list.isEmpty()){ ActivityCompat.requestPermissions(topActivity,list.toArray(new String[list.size()]),1); }else{ Toast.makeText(topActivity, "所有的权限都已经通过了!", Toast.LENGTH_SHORT).show(); //权限通过的回调方法 mLitener.onGranted(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { //此处判断的是上方的标记“1” case 1: if(grantResults.length>0){ ArrayList<String> list=new ArrayList<>(); for (int i = 0; i < grantResults.length; i++) { int grantResult=grantResults[i]; String permission=permissions[i]; if(grantResult!=PackageManager.PERMISSION_GRANTED){ list.add(permission); } } //判断所有的权限是否都通过了 if(!list.isEmpty()){ mLitener.onDenied(list); }else{ mLitener.onGranted(); } } break; default: break; } }}//将所有创建的Activity都存于listActivity中public class listActivity { public static ArrayList<Activity> listActivity=new ArrayList<>(); //添加Activity的方法 public static void addActivity(Activity activity){ listActivity.add(activity); } //销毁Activity的方法 public static void removeActivity(Activity activity){ listActivity.remove(activity); } //返回Activity的方法 public static Activity getActivity(){ if(listActivity.isEmpty()){ return null; }else{ //防止list集合中的Activity被销毁,返回栈顶Activity return listActivity.get(listActivity.size()-1); } }}public interface PermissioLitener { //申请的所有权限都通过了所执行的方法 void onGranted(); //申请的权限有的失败了,将申请失败的权限放进集合作为参数提示用户 void onDenied(ArrayList<String> list);}此时在任意一个类中申请权限时是这样的BaseActivity.requestRuntimePermision(new String[]{Manifest.permission.CALL_PHONE,Manifest.permission.WRITE_EXTERNAL_STORAGE}, new PermissioLitener() { @Override public void onGranted() { //所有的权限申请成功 } @Override public void onDenied(ArrayList<String> list) { //权限有的申请失败了,list中为申请失败的权限 }});好了,到这里呢,大家是不是对运行时权限有了一定的了解。。。。也挺简单的事吧,加油!
新闻热点
疑难解答