Android权限

一.所属权限组 权限

日历	READ_CALENDAR
日历	WRITE_CALENDAR
相机	CAMERA
联系人	READ_CONTACTS
联系人	WRITE_CONTACTS
联系人	GET_ACCOUNTS
位置	ACCESS_FINE_LOCATION
位置	ACCESS_COARSE_LOCATION
麦克风	RECORD_AUDIO
电话	READ_PHONE_STATE
电话	CALL_PHONE
电话	READ_CALL_LOG
电话	WRITE_CALL_LOG
电话	ADD_VOICEMAIL
电话	USE_SIP
电话	PROCESS_OUTGOING_CALLS
传感器	BODY_SENSORS
短信	SEND_SMS
短信	RECEIVE_SMS
短信	READ_SMS
短信	RECEIVE_WAP_PUSH
短信	RECEIVE_MMS
存储	READ_EXTERNAL_STORAGE
存储	WRITE_EXTERNAL_STORAGE

二.AndroidManifest.xml静态申请权限

<uses-permission android:name="android.permission.上表的权限字符" />

三.然后,在java代码中写动态申请权限的逻辑(这是官网的写法)

public void requestPower() {
    //判断是否已经赋予权限
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.上表权限字符)
                != PackageManager.PERMISSION_GRANTED) {
           //如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true。
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.上表权限字符)) {//这里可以写个对话框之类的项向用户解释为什么要申请权限,并在对话框的确认键后续再次申请权限
            } else {
            //申请权限,字符串数组内是一个或多个要申请的权限,1是申请权限结果的返回参数,在onRequestPermissionsResult可以得知申请结果
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.上表权限字符,}, 1);
            }
        }
    }
//注意,因为判断语句,其实实际上当用户拒绝一次权限申请后,再次调用方法,不会再出现申请权限对话框。而如果不把权限写在数组里,而是每条权限放在一个多个以下方法里一起调用,实际上,每次一起调用这多个方法,实际只申请这些方法的一条权限

四.判断权限申请结果的方法

//判断权限申请结果的方法(在权限申请对话框消失后执行)(注意:PERMISSION_GRANTED变量,导入的是: 
import static android.content.pm.PackageManager.PERMISSION_GRANTED):
@Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (requestCode == 1) {
            for (int i = 0; i < permissions.length; i++) {
                if (grantResults[i] == PERMISSION_GRANTED) {
                    Toast.makeText(this, "" + "权限" + permissions[i] + "申请成功", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, "" + "权限" + permissions[i] + "申请失败", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }
//当系统要求用户授予权限时,用户可以选择指示系统不再要求提供该权限。这种情况下,无论应用在什么时候使用 requestPermissions() 再次要求该权限,系统都会立即拒绝此请求。

五.EasyPermissions 的使用

1.在build.gradle中
	dependencies {
	    compile 'pub.devrel:easypermissions:0.4.0'
	}
2.使用方式一:
	1.开发过程中,遇到需要使用动态权限时,添加如下代码
		if (EasyPermissions.hasPermissions(this, "android.permission.XXXX")) {
	      //具备权限 直接进行操作
	  	} else {
	      //权限拒绝 申请权限
	      EasyPermissions.requestPermissions(this, "", PERMISSION_CAMERA, "android.permission.XXXX"); }
	2.然后在activity或fragment中 覆盖onRequestPermissionsResult方法
		@Override
		public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
		       super.onRequestPermissionsResult(requestCode, permissions, grantResults);
		       // 将结果转发到EasyPermissions 
		        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
		  }
	3.最后用activity或fragment实现 EasyPermissions.PermissionCallbacks接口 复写它的两个回调方法
		@Override
		    public void onPermissionsGranted(int requestCode, List<String> perms) {//某些权限已被授予
		
		    }
		
		    @Override
		    public void onPermissionsDenied(int requestCode, List<String> perms) { //某些权限已被拒绝
		        if (requestCode == PERMISSION_CAMERA) {
		        //显示dialog来提示用户去设置
		            new AppSettingsDialog.Builder(this).setRationale("1231414").setTitle("标题").build().show();
		        }
		    }
3.使用方式二:
	1.在Activity中使用
		EasyPermissions.of(this)
        .reqCode(111)
        .perms(Manifest.permission.CAMERA)
        .callBack(new PermissionInfo() {
            @Override
            public void onGranted(List<String> perms) {
                Toast.makeText(MyActivity.this, "onGranted", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onDenied(List<String> perms) {
                Toast.makeText(MyActivity.this, "onDenied", Toast.LENGTH_SHORT).show();
            }
        });
	2.申请多个权限
		String[] LOCATION_AND_CONTACTS = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_CONTACTS};
		EasyPermissions.of(this)
		        .reqCode(112)
		        .perms(LOCATION_AND_CONTACTS)
		        .callBack(new PermissionInfo() {
		            @Override
		            public void onGranted(List<String> perms) {
		                StringBuilder sb = new StringBuilder();
		                for (String per : perms){
		                    sb.append(per + " ");
		                }
		
		                Toast.makeText(MyActivity.this, "onGranted " + sb.toString().trim(), Toast.LENGTH_SHORT).show();
		            }
		
		            @Override
		            public void onDenied(List<String> perms) {
		                StringBuilder sb = new StringBuilder();
		                for (String per : perms){
		                    sb.append(per + "\n\n");
		                }
		
		                Toast.makeText(MyActivity.this, "onDenied " + sb.toString().trim(), Toast.LENGTH_SHORT).show();
		            }
		        });
	3.跳转到设置页面,由于Android各大厂商自定制系统,可能存在兼容性问题
		public static void toSettingAct(Activity act){
		    act.startActivityForResult(
		            new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).setData(Uri.fromParts("package", act.getPackageName(), null)),
		            APP_SETTINGS_RC);
		}
	4.BaseActivity的回调
	    @Override
	    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
	        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
	
	        EasyPermissions.onResult(requestCode, permissions, grantResults);
	    }

六、RxPermissions

1.https://github.com/tbruyelle/RxPermissions

七、原生调用

(1)、基本步骤:
	1、检查是否授予权限:
		ContextCompat.checkSelfPermission(mContext, permissions[i])
		注:返回的结果为PackageManager.PERMISSION_GRANTED(0)表示授予权限
	2、请求权限:
		ActivityCompat.requestPermissions(WelcomeActivity.this, permissions, 1);
		注:permissions为数组,单个的权限,传new String[]{permission}参数, 1为requestCode,在权限回调中需要使用。
	3、请求权限后的回调:
		public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {}
	4、判断用户拒绝权限是是否勾选don't  ask again选项,若勾选需要客户手动打开权限:
		ActivityCompat.shouldShowRequestPermissionRationale(WelcomeActivity.this, permissions[i])			
		注:ActivityCompat.shouldShowRequestPermissionRationale(activity,permission)  这个方法是在用户拒绝权限后返回true。也就是说:用户第一次点击一个需要权限的地方,该方法返回false(因为用户没拒绝~),当用户拒绝掉该权限,下次点击此权限处,该方法会返回true。为true的时候,显示对话框对该权限说明,并让用户选择是否再次申请权限。当用户拒绝权限并勾选don't ask again选项后,会一直返回false,并且 ActivityCompat.requestPermissions 不会弹出对话框,系统直接deny,并执行 onRequestPermissionsResult 方法:

(2)、常用思路:
	在实际项目中,为了开发的方便,在欢迎界面,将常用的权限申请一次性申请,一般申请写存储卡、定位等权限。在某个具体操作的时候(如:打电话)再单独进行权限判断。
	1、欢迎界面权限申请流程:①、检查需要申请的权限状态,将未授权的单独保存到集合中;     ②、集合为空,进入首页(已全都授予权限),不为空,请求权限;     ③、当用户拒绝时,判断是否勾选don't ask again,未勾选,重新申请权限,已勾选,跳过欢迎界面,进入主界面。
	2、具体操作权限申请流程:①、请求权限;     ②、在请求回调中,当用户拒绝时,需判断是否勾选don't ask again,未勾选,重新申请权限,已勾选,跳转到设置界面。
	
	步骤:
		1、首先声明一个数组permissions,将需要的权限都放在里面:

			String[] permissions = new String[]{Manifest.permission.CALL_PHONE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
			List<String> mPermissionList = new ArrayList<>();

		2、创建一个mPermissionList,逐个判断哪些权限未授予,未授予的权限存储到mPerrrmissionList中

			/**
			 * 判断哪些权限未授予
			 */
			mPermissionList.clear();
			for (int i = 0; i < permissions.length; i++) {
			    if (ContextCompat.checkSelfPermission(mContext, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
			        mPermissionList.add(permissions[i]);
			    }
			}

		3、判断permissionList是否为空,不为空的,调用ActivityCompat.requestPermissions()授予权限。如果permissionList为空,表示权限都授予了,执行对应的方法

			/**
			 * 判断是否为空
			 */
			if (mPermissionList.isEmpty()) {//未授予的权限为空,表示都授予了
			    delayEntryPage();
			} else {//请求权限方法
			    String[] permissions = mPermissionList.toArray(new String[mPermissionList.size()]);//将List转为数组
			    ActivityCompat.requestPermissions(WelcomeActivity.this, permissions, 1);
			}

		4、在权限回调中,判断用户是否授权,当用户拒绝授权的,需判断用户是否勾选don't ask again选项。分下面两种情况:
			①.拒绝权限,但未勾选don't ask again选项,重新申请权限
			②.拒绝权限,并且勾选don't ask again选项,跳过欢迎界面,在用户需要的时候再申请。

			boolean mShowRequestPermission = true;//用户是否禁止权限
			@Override
			public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
			    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
			    switch (requestCode) {
			        case 1:
			            for (int i = 0; i < grantResults.length; i++) {
			                if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
			                    //判断是否勾选禁止后不再询问
			                    boolean showRequestPermission = ActivityCompat.shouldShowRequestPermissionRationale(WelcomeActivity.this, permissions[i]);
			                    if (showRequestPermission) {//
			                        judgePermission();//重新申请权限
			                        return;
			                    } else {
			                        mShowRequestPermission = false;//已经禁止
			                    }
			                }
			            }
			            delayEntryPage();
			            break;
			        default:
			            break;
			    }
			}

		5、进入App,用户具体操作的时候(如:打电话)申请权限流程,基本上同上面一样,唯一不同的是,当用户拒绝权限的时候跳转到系统应用设置界面。跳转到应用设置界面的代码:

			Uri packageURI = Uri.parse("package:" + AppUtils.getAppPackageName());
			Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
			startActivity(intent);
			//注:为了增强用户体验,在需要跳转到应用设置界面的时候,展示一个对话框,进行文字说明,当用户点击确定的时候再跳转到设置界面。
			AlertDialog mPermissionDialog;
			/**
			 * 不再提示权限 时的展示对话框
			 */
			private void showPermissionDialog() {
			    if (mPermissionDialog == null) {
			        mPermissionDialog = new AlertDialog.Builder(mContext)
			                .setMessage("已禁用权限,请手动授予")
			                .setPositiveButton("设置", new DialogInterface.OnClickListener() {
			                    @Override
			                    public void onClick(DialogInterface dialog, int which) {
			                        cancelPermissionDialog();
			                        Uri packageURI = Uri.parse("package:" + AppUtils.getAppPackageName());
			                        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
			                        startActivity(intent);
			                    }
			                })
			                .setNegativeButton("取消", new DialogInterface.OnClickListener() {
			                    @Override
			                    public void onClick(DialogInterface dialog, int which) {
			                        cancelPermissionDialog();
			                    }
			                })
			                .create();
			    }
			    mPermissionDialog.show();
			}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值