问题引出
在Android 6.0 (Android M / API 23)之前,当App需要使用某些权限时,直接在Manifest 清单文件中静态设置权限即可。但是在Android 6.0 之后,有些危险权限,例如涉及到用户隐私的权限,不光要静态申请,还要在运行时动态的申请。下面我们来结合代码一起学习动态申请权限的方法
解决思路
例如,我们写 一个Button,点击这个Button 就可以直接拨打特定的电话号码,
- 布局文件就不用上代码了,全篇就只有一个按钮,置于页面正中就行了。
- 我们都知道拨打电话需要申请
Manifest.permissions.CALL_PHONE
权限,所以我们在Manifest文件中首先添加
...
<uses-permission android:name="android.permission.CALL_PHONE"/>
...
- 在MainActivity中找到按钮,给按钮绑定点击事件(常规操作,代码略)
- 在按钮的点击事件中需要两个逻辑
- 当用户已经给了权限,那么就直接拨打电话
- 当用户没给权限,需要动态申请,申请完权限在回调函数
onRequestPermissionsResult()
中处理接下来的逻辑(当然是继续拨打电话了。。。)
onRequestPermissionsResult()
详细处理逻辑- 判断请求码
- 判断用户是否给应用授权
代码讲解
下面正式上代码,代码主要涉及上面的第4步和第5步
// 第4步的代码
btn_call.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (ActivityCompat.checkSelfPermission
(getApplicationContext(), Manifest.permission.CALL_PHONE)
!= PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.CALL_PHONE}, 10086);
Log.i(TAG, "onClick: 点击了拨打电话的按钮");
} else {
makeCall();
}
}
});
重点解释一下这个代码,在第5行的if判断中,ActivityCompat.checkSelfPermission()
方法返回结果只有PERMISSION_GRANTED = 0
或者PERMISSION_DENIED = -1
两种结果。当结果不等于PERMISSION_GRANTED
时,我们申请权限,调用ActivityCompat.requestPermissions
方法进行权限申请。申请了权限,会执行第5步的回调方法。如果结果相等,那么直接调用makeCall()
方法。
下面进入第5步的回调方法
// 第5步的代码
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
Log.i(TAG, "onActivityResult: ");
switch (requestCode) {
case 10086:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
makeCall();
} else {
Log.i(TAG, "onRequestPermissionsResult: 用户不给权限");
}
break;
default:
Log.i(TAG, "onActivityResult: 权限被拒绝了");
Toast.makeText(this, "权限被拒绝了", Toast.LENGTH_SHORT).show();
break;
}
}
该回调方法三个默认参数requestCode
,permissions
,grantResults
介绍:
-
- requestCode 请求码:在第4步申请权限时传入的请求码,在第5步通过switch语句进行判断具体是谁在申请权限,进行不同的处理。
-
- permissions 权限数组:在第4步的时候我们申请权限,
ActivityCompat.requestPermissions()
的第二个参数就是一个String 类型的数组,也就是说我们可以一次性申请多个权限,同理,我们这里传入的参数也就是用户申请的所有权限数组
- permissions 权限数组:在第4步的时候我们申请权限,
-
- grantResults 申请结果:在申请多个权限时,用户可能会拒绝有些权限,申请结果保存在该int型的数组中。
第5步的代码中第8行的判断,当用户给了权限,就正常执行makeCall()
方法,否则进入else流程,进行其他处理。