众所周知,Android在6.0版本后将权限修改成了动态权限,而iOS则一直使用的是动态权限,所以在Flutter应用开发中如果涉及到一些危险权限,就需要进行动态申请,动态申请权限可以使用Flutter的permission_handler。
基本使用
1,配置权限
首先,打开Android工程下的AndroidManifest.xml文件,具体路径如下:在androidappsrcmainAndroidManifest.xml中配置,然后添加如下所示的权限。
动态权限申请
目前,这个插件已经升级了好几版,而不同版本处理方法也不一样,特别是最新的5.0.0版本和之前的版本,用法差别比较大。
4.3.0
例如,下面是4.3.0版本的用法:
- 权限列表:PermissionGroup中的字段
- 权限状态列表:PermissionStatus中字段
- 打开权限设置页面:await PermissionHandler().openAppSettings();
- 申请权限
示例如下:
await Map map= PermissionHandler().requestPermissions([ 权限列表])
然后,是获取申请权限的状态,如下:
PermissionStatus contactsPermStatus = await PermissionHandler().checkPermissionStatus(PermissionGroup.contacts);
下面是一个完整的示例:
///请求权限
void _requestPermission() async {
debugPrint("进入闪屏页面");
// 申请权限
// PermissionStatus storageStatus ;
PermissionStatus cameraStatus;
await PermissionHandler().requestPermissions(
[ PermissionGroup.camera]).then((value) {
debugPrint("返回:$value");
// storageStatus=value[PermissionGroup.storage];
cameraStatus=value[PermissionGroup.camera];
});
debugPrint("请求权限,并获取权限:$cameraStatus");
//校验权限
if (cameraStatus == PermissionStatus.granted) {
debugPrint("校验权限:用户都同意了");
//用户都同意了(用&&)
///权限都申请成功初始化闪屏
_initSplash();
} else if ( cameraStatus == PermissionStatus.denied) {
debugPrint("校验权限:有任何一组权限被用户拒绝");
//用户拒绝了(用||)
///有任何一组权限被用户拒绝
//拼接提示权限文本
StringBuffer sb = new StringBuffer();
sb.write(cameraStatus == PermissionStatus.denied ? "相机," : "");
String tip = Utils.removePostfix(sb.toString(), ",");
Utils.showCustomDialog(
context,
ConfirmDialog(
"您拒绝了应用的必要权限:\n[$tip],是否重新申请?",
canBackDismiss: false,
confirmCallback: () => _requestPermission(),
cancelCallback: () => SystemNavigator.pop(),
));
} else if ( cameraStatus == PermissionStatus.neverAskAgain) {
debugPrint("校验权限:有权限永久拒绝");
//有权限永久拒绝(用||)
///有任何一组权限选了不再提示
//拼接提示权限文本
StringBuffer sb = new StringBuffer();
sb.write(cameraStatus == PermissionStatus.neverAskAgain ? "相机," : "");
String tip = Utils.removePostfix(sb.toString(), ",");
Utils.showCustomDialog(
context,
ConfirmDialog(
"您禁用了应用的必要权限:\n[$tip],请到设置里允许?",
canBackDismiss: false,
confirmText: "去设置",
confirmCallback: () async {
await PermissionHandler().openAppSettings(); //打开设置页面
SystemNavigator.pop();
},
cancelCallback: () => SystemNavigator.pop(),
));
}
}
效果图如下:
5.0.0
5.0.0版本和之前的写法大体类似,只是方法和参数字段发生了改变,如下所示。
- 权限列表:Permission中的字段
- 权限状态列表:PermissionStatus中字段
- 打开权限设置页面:openAppSettings();
- 申请权限
await [权限列表].request(); //可以使用then,用权限获取状态
- 获取权限状态await Permission.camera.status
- 判断权限状态:await Permission.camera.isDenied|isGranted等
下面是详细的使用示例:
///请求权限
void _requestPermission() async {
debugPrint("进入闪屏页面");
// 申请权限
// PermissionStatus cameraStatus;
await [Permission.camera].request();
// .then((value){
//设置申请后的结果
// cameraStatus=value[Permission.camera];
// });
//或者直接调用:
debugPrint("请求权限,并获取权限");
if(await Permission.camera.isDenied){
}
//校验权限
if (await Permission.camera.isGranted) {
debugPrint("校验权限:用户都同意了");
//用户都同意了(用&&)
///权限都申请成功初始化闪屏
_initSplash();
} else if ( await Permission.camera.isDenied) {
debugPrint("校验权限:有任何一组权限被用户拒绝");
//用户拒绝了(用||)
///有任何一组权限被用户拒绝
//拼接提示权限文本
StringBuffer sb = new StringBuffer();
sb.write(await Permission.camera.isDenied? "相机," : "");
String tip = Utils.removePostfix(sb.toString(), ",");
Utils.showCustomDialog(
context,
ConfirmDialog(
"您拒绝了应用的必要权限:\n[$tip],是否重新申请?",
canBackDismiss: false,
confirmCallback: () => _requestPermission(),
cancelCallback: () => SystemNavigator.pop(),
));
} else if ( await Permission.camera.isPermanentlyDenied) {
debugPrint("校验权限:有权限永久拒绝");
//有权限永久拒绝(用||)
///有任何一组权限选了不再提示
//拼接提示权限文本
StringBuffer sb = new StringBuffer();
sb.write( await Permission.camera.isPermanentlyDenied ? "相机," : "");
String tip = Utils.removePostfix(sb.toString(), ",");
Utils.showCustomDialog(
context,
ConfirmDialog(
"您禁用了应用的必要权限:\n[$tip],请到设置里允许?",
canBackDismiss: false,
confirmText: "去设置",
confirmCallback: () async {
await openAppSettings(); //打开设置页面
SystemNavigator.pop();
},
cancelCallback: () => SystemNavigator.pop(),
));
}
}