Flutter插件 权限管理 Permission_handler使用

作者:LJLThomson 来源:blog.csdn.net 时间:2021-10-13 05:11

Flutter permission权限申请

1.简介

在我们Android和IOS开发中,都会涉及到权限问题,而Flutter是需要将IOS和Android权限柔和起来的,分别需要适配Android和IOS,

推荐使用Permission_handler。

2.使用

1.依赖

dependencies:
  permission_handler: ^7.1.0
import 'package:permission_handler/permission_handler.dart';

在Android manifest添加相应权限:

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

全部使用AndroidX,抛弃过去的support支持包

android.useAndroidX=true
android.enableJetifier=true

compileSdkVersion和targetSdkVersion要设置为28以上

    compileSdkVersion 28
    targetSdkVersion 28

在IOS中,将以下内容添加到您的Podfile文件中:

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      ... # Here are some configurations automatically generated by flutter

      # You can remove unused permissions here
      # for more infomation: https://github.com/BaseflowIT/flutter-permission-handler/blob/develop/permission_handler/ios/Classes/PermissionHandlerEnums.h
      # e.g. when you don't need camera permission, just add 'PERMISSION_CAMERA=0'
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',

        ## dart: PermissionGroup.calendar
        # 'PERMISSION_EVENTS=0',

        ## dart: PermissionGroup.reminders
        # 'PERMISSION_REMINDERS=0',

        ## dart: PermissionGroup.contacts
        # 'PERMISSION_CONTACTS=0',

        ## dart: PermissionGroup.camera
        # 'PERMISSION_CAMERA=0',

        ## dart: PermissionGroup.microphone
        # 'PERMISSION_MICROPHONE=0',

        ## dart: PermissionGroup.speech
        # 'PERMISSION_SPEECH_RECOGNIZER=0',

        ## dart: PermissionGroup.photos
        # 'PERMISSION_PHOTOS=0',

        ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
        # 'PERMISSION_LOCATION=0',

        ## dart: PermissionGroup.notification
        # 'PERMISSION_NOTIFICATIONS=0',

        ## dart: PermissionGroup.mediaLibrary
        # 'PERMISSION_MEDIA_LIBRARY=0',

        ## dart: PermissionGroup.sensors
        # 'PERMISSION_SENSORS=0',   

        ## dart: PermissionGroup.bluetooth
        # 'PERMISSION_BLUETOOTH=0'
      ]
    end
  end
end

2.使用

enum PermissionStatus {
  /// The user denied access to the requested feature.
  denied, //权限被拒绝

  /// The user granted access to the requested feature.
  granted, //通过

  /// The OS denied access to the requested feature. The user cannot change
  /// this app's status, possibly due to active restrictions such as parental
  /// controls being in place.
  /// *Only supported on iOS.*
  restricted, //IOS

  ///User has authorized this application for limited access.
  /// *Only supported on iOS (iOS14+).*
  limited, //IOS

  /// The user denied access to the requested feature and selected to never
  /// again show a request for this permission. The user may still change the
  /// permission status in the settings.
  /// *Only supported on Android.*
  permanentlyDenied, //拒绝,且不在提示
}

3.检查权限


  void checkPermission() async {
    Permission permission = Permission.storage;
    PermissionStatus status = await permission.status;
    print('检测权限$status');
    if (status.isGranted) {
      //权限通过
    } else if (status.isDenied) {
      //权限拒绝, 需要区分IOS和Android,二者不一样
      requestPermission(permission);
    } else if (status.isPermanentlyDenied) {
      //权限永久拒绝,且不在提示,需要进入设置界面,IOS和Android不同
      openAppSettings();
    } else if (status.isRestricted) {
      //活动限制(例如,设置了家长///控件,仅在iOS以上受支持。
      openAppSettings();
    } else {
      //第一次申请
      requestPermission(permission);
    }
  }

————————注意:isPermanentlyDenied,在没有申请之前,都会是Denied,而不是permanentlyDenied

4.申请权限

  void requestPermission(Permission permission) async {
    //发起权限申请
    PermissionStatus status = await permission.request();
    // 返回权限申请的状态 status
    print('权限状态$status');
    if (status.isPermanentlyDenied) {
       openAppSettings();
    }
  }

5.申请多个权限


  void requestPermissions() async {
    Map<Permission, PermissionStatus> statuses = await [
      Permission.location,
      Permission.storage,
    ].request();
    print('位置权限:${statuses[Permission.location]}');
    print('存储权限:${statuses[Permission.storage]}');
  }

6.打开设置

if (await Permission.speech.isPermanentlyDenied) {
  // The user opted to never again see the permission request dialog for this
  // app. The only way to change the permission's status now is to let the
  // user manually enable it in the system settings.
  openAppSettings();
}

7.在Android上,显示理由

bool isShown = await Permission.contacts.shouldShowRequestRationale;

————————不太清楚需要怎么用

代码演示如下:

import 'package:flutter/cupertino.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
        home: Scaffold(
      appBar: AppBar(title: Text('FlutterDemo')),
      body: PermissionDemo(),
    ));
  }
}

class PermissionDemo extends StatefulWidget {
  PermissionDemo({Key key}) : super(key: key);

  @override
  _PermissionDemoState createState() {
    return _PermissionDemoState();
  }
}

class _PermissionDemoState extends State<PermissionDemo> {
  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  void checkPermission() async {
    Permission permission = Permission.storage;
    PermissionStatus status = await permission.status;
    print('检测权限$status');
    if (status.isGranted) {
      //权限通过
    } else if (status.isDenied) {
      //权限拒绝, 需要区分IOS和Android,二者不一样
      requestPermission(permission);
    } else if (status.isPermanentlyDenied) {
      //权限永久拒绝,且不在提示,需要进入设置界面,IOS和Android不同
      openAppSettings();
    } else if (status.isRestricted) {
      //活动限制(例如,设置了家长///控件,仅在iOS以上受支持。
      openAppSettings();
    } else {
      //第一次申请
      requestPermission(permission);
    }
  }

  void requestPermission(Permission permission) async {
    //发起权限申请
    PermissionStatus status = await permission.request();
    // 返回权限申请的状态 status
    print('权限状态$status');
    if (status.isPermanentlyDenied) {
       openAppSettings();
    }
  }

  void checkPermission2() async {
    Permission storagePermission = Permission.storage;
    Permission locationPermission = Permission.location;
    requestPermissions();
  }

  void requestPermissions() async {
    Map<Permission, PermissionStatus> statuses = await [
      Permission.location,
      Permission.storage,
    ].request();
    print('位置权限:${statuses[Permission.location]}');
    print('存储权限:${statuses[Permission.storage]}');

    bool isShown = await Permission.contacts.shouldShowRequestRationale;
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Center(
      child: Column(
        children: <Widget>[
          OutlinedButton(onPressed: () {
            checkPermission();
          }, child: Text('申请权限存储权限')),
          OutlinedButton(onPressed: () {
            checkPermission2();
          }, child: Text('多权限申请'))
        ],
      ),
    );
  }
}

3.判断平台

依赖

import 'dart:io';
Platform.isIOS
Platform.isAndroid

4.权限封装

import 'package:flutter/cupertino.dart';
import 'package:permission_handler/permission_handler.dart';

class PermissionHelper {
  static VoidCallback defaultCall = () {};

  ///检查权限
  static void check(List<Permission> permissionList,
      {String errMsg,
      VoidCallback onSuccess,
      VoidCallback onFailed,
      VoidCallback onOpenSetting}) async {
    bool flag = true;
    for (var value in permissionList) {
      var status = await value.status;
      if (!status.isGranted) {
        flag = false;
        break;
      }
    }
    if (!flag) {
      PermissionStatus permissionStatus =
          await requestPermission(permissionList);
      if (permissionStatus.isGranted) {
        onSuccess != null ? onSuccess() : defaultCall();
      } else if (permissionStatus.isDenied) {
        onFailed != null ? onFailed() : defaultCall();
      } else if (permissionStatus.isPermanentlyDenied) {
        onOpenSetting != null ? onOpenSetting() : defaultCall();
      } else if (permissionStatus.isRestricted) {
        //IOS单独处理
        onOpenSetting != null ? onOpenSetting() : defaultCall();
      } else if (permissionStatus.isLimited) {
        //IOS单独处理
        onOpenSetting != null ? onOpenSetting() : defaultCall();
      }
    }
  }

  //申请权限
  static Future<PermissionStatus> requestPermission(
      List<Permission> permissionList) async {
    Map<Permission, PermissionStatus> statuses = await permissionList.request();
    PermissionStatus currentPermissionStatus = PermissionStatus.granted;
    statuses.forEach((key, value) {
      if (!value.isGranted) {
        currentPermissionStatus = value;
        return;
      }
    });
    return currentPermissionStatus;
  }
}

  • onSuccess : 同意
  • onFailed : 其中一个不同意
  • onOpenSetting 需要去设置

使用,代码案例如下

import 'package:flutter/cupertino.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:flutter/material.dart';

import 'PermissionHelper.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
        home: Scaffold(
      appBar: AppBar(title: Text('FlutterDemo')),
      body: PermissionDemo(),
    ));
  }
}

class PermissionDemo extends StatefulWidget {
  PermissionDemo({Key key}) : super(key: key);

  @override
  _PermissionDemoState createState() {
    return _PermissionDemoState();
  }
}

class _PermissionDemoState extends State<PermissionDemo> {
  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Center(
      child: Column(
        children: <Widget>[
          OutlinedButton(
              onPressed: () {
                List<Permission> permissions = [
                  Permission.storage,
                  Permission.location
                ];
                PermissionHelper.check(permissions,
                    onSuccess: () {
                      print('onSuccess');
                    }, onFailed: () {
                      print('onFailed');
                    }, onOpenSetting: () {
                      print('onOpenSetting');
                      openAppSettings();
                    });
              },
              child: Text('申请权限存储权限')),
          OutlinedButton(onPressed: () {}, child: Text('多权限申请'))
        ],
      ),
    );
  }
}