55 Flutter Permission_handler permission application

Flutter permission application

1 Introduction

In our Android and IOS development, permission issues will be involved, and Flutter needs to soften the permissions of IOS and Android, and need to adapt to Android and IOS respectively.

Permission_handler is recommended.

2. Use

1. Dependence

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

Add the corresponding permissions in the 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" />
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

All use AndroidX, abandon the past support package

android.useAndroidX=true
android.enableJetifier=true
  • 1
  • 2

compileSdkVersion and targetSdkVersion should be set to above 28

    compileSdkVersion 28
    targetSdkVersion 28
  • 1
  • 2

In IOS, add the following to yourPodfileIn the file:

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

2. Use

enum PermissionStatus {
  /// The user denied access to the requested feature.
  denied, //Permission denied

  /// The user granted access to the requested feature.
  granted, // pass

  /// 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, //rejected, and not prompted
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

3. Check permissions


  void checkPermission() async {
    Permission permission = Permission.storage;
    PermissionStatus status = await permission.status;
    print('Check permission $status');
    if (status.isGranted) {
      // permission passed
    } else if (status.isDenied) {
      //Permission denied, need to distinguish between IOS and Android, the two are different
      requestPermission(permission);
    } else if (status.isPermanentlyDenied) {
      //The permission is permanently denied, and there is no prompt, you need to enter the setting interface, IOS and Android are different
      openAppSettings();
    } else if (status.isRestricted) {
      // Activity restrictions (e.g. parental /// controls are set, only supported above iOS.
      openAppSettings();
    } else {
      // first application
      requestPermission(permission);
    }
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

————————Note: isPermanentlyDenied, before applying, it will be Denied, not permanentlyDenied

4. Apply for permission

  void requestPermission(Permission permission) async {
    //Initiate permission request
    PermissionStatus status = await permission.request();
    // Return the status status of the permission request
    print('Permission status $status');
    if (status.isPermanentlyDenied) {
       openAppSettings();
    }
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

5. Apply for multiple permissions


  void requestPermissions() async {
    Map<Permission, PermissionStatus> statuses = await [
      Permission.location,
      Permission.storage,
    ].request();
    print('Location permission: ${statuses[Permission.location]}');
    print('Storage permission: ${statuses[Permission.storage]}');
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

6. Open Settings

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();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

7. On Android, show justification

bool isShown = await Permission.contacts.shouldShowRequestRationale;
  • 1

—————— Not sure how to use it

The code demonstration is as follows:

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('Check permission $status');
    if (status.isGranted) {
      // permission passed
    } else if (status.isDenied) {
      //Permission denied, need to distinguish between IOS and Android, the two are different
      requestPermission(permission);
    } else if (status.isPermanentlyDenied) {
      //The permission is permanently denied, and there is no prompt, you need to enter the setting interface, IOS and Android are different
      openAppSettings();
    } else if (status.isRestricted) {
      // Activity restrictions (e.g. parental /// controls are set, only supported above iOS.
      openAppSettings();
    } else {
      // first application
      requestPermission(permission);
    }
  }

  void requestPermission(Permission permission) async {
    //Initiate permission request
    PermissionStatus status = await permission.request();
    // Return the status status of the permission request
    print('Permission status $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('Location permission: ${statuses[Permission.location]}');
    print('Storage permission: ${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('Apply for permission to store permission')),
          OutlinedButton(onPressed: () {
            checkPermission2();
          }, child: Text('Multiple permission application'))
        ],
      ),
    );
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105

3. Judgment Platform

rely

import 'dart:io';
  • 1
Platform.isIOS
Platform.isAndroid
  • 1
  • 2

4. Permission encapsulation

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

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

  ///Check permissions
  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 handles it separately
        onOpenSetting != null ? onOpenSetting() : defaultCall();
      } else if (permissionStatus.isLimited) {
        //IOS handles it separately
        onOpenSetting != null ? onOpenSetting() : defaultCall();
      }
    }
  }

  //request for access
  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;
  }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • onSuccess : agree
  • onFailed : one of them disagrees
  • onOpenSetting needs to be set

Use, the code example is as follows

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('Apply for permission to store permission')),
          OutlinedButton(onPressed: () {}, child: Text('Multiple permission application'))
        ],
      ),
    );
  }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72

Related: 55 Flutter Permission_handler permission application