【flutter】permission_handler插件使用

丰辰沛
2023-12-01


前言

提供了一个跨平台(iOS、Android)API来请求权限并检查其状态。您还可以打开设备的应用程序设置,以便用户可以授予权限


一、使用步骤

1.引入插件

permission_handler: ^10.2.0

2.配置android权限

(1)从3.1.0版本开始,permission_handler插件切换到AndroidX版本的Android支持库。这意味着您需要确保您的Android项目也已升级以支持AndroidX
(2)将以下内容添加到您的“gradle.properties”文件中:

android.useAndroidX=true
android.enableJetifier=true

(3) 确保将“android/app/build.gradle”文件中的compileSdkVersion设置为33

android {
  compileSdkVersion 33
  ...
}

(4)确保将“android/app/src/main/AndroidManifest.xml”文件中,按需在添加本项目需要用到的权限:(本次以保存图片到本地相册举例)

<!-- 写权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 读权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

3.配置ios权限

(1)将以下内容添加到您的Podfile文件中:

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

    # Start of the permission_handler configuration
    target.build_configurations.each do |config|

      # You can enable the permissions needed here. For example to enable camera
      # permission, just remove the `#` character in front so it looks like this:
      #
      # ## dart: PermissionGroup.camera
      # 'PERMISSION_CAMERA=1'
      #
      #  Preprocessor definitions can be found in: https://github.com/Baseflow/flutter-permission-handler/blob/master/permission_handler_apple/ios/Classes/PermissionHandlerEnums.h
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',

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

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

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

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

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

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

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

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

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

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

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

        ## dart: PermissionGroup.bluetooth
        # 'PERMISSION_BLUETOOTH=1',

        ## dart: PermissionGroup.appTrackingTransparency
        # 'PERMISSION_APP_TRACKING_TRANSPARENCY=1',

        ## dart: PermissionGroup.criticalAlerts
        # 'PERMISSION_CRITICAL_ALERTS=1'
      ]

    end 
    # End of the permission_handler configuration
  end
end

(2)删除您想要使用的权限前面的#字符。例如,如果您需要访问日历,请确保代码如下所示:

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

(3)在Info.plist中删除相应的权限描述,例如,当您不需要相机权限时,只需删除“NSCameraUsageDescription”。以下列出了Permission和The key of Info.plist之间的关系:

PermissionInfo.plistMacro
PermissionGroup.calendarNSCalendarsUsageDescriptionPERMISSION_EVENTS
PermissionGroup.remindersNSRemindersUsageDescriptionPERMISSION_REMINDERS
PermissionGroup.contactsNSContactsUsageDescriptionPERMISSION_CONTACTS
PermissionGroup.cameraNSCameraUsageDescriptionPERMISSION_CAMERA
PermissionGroup.microphoneNSMicrophoneUsageDescriptionPERMISSION_MICROPHONE
PermissionGroup.speechNSSpeechRecognitionUsageDescriptionPERMISSION_SPEECH_RECOGNIZER
PermissionGroup.photosNSPhotoLibraryUsageDescriptionPERMISSION_PHOTOS
PermissionGroup.location PermissionGroup.locationAlways PermissionGroup.locationWhenInUseNSLocationUsageDescription NSLocationAlwaysAndWhenInUseUsageDescription NSLocationWhenInUseUsageDescriptionPERMISSION_LOCATION
PermissionGroup.notificationPermissionGroupNotificationPERMISSION_NOTIFICATIONS
PermissionGroup.mediaLibraryNSAppleMusicUsageDescription kTCCServiceMediaLibraryPERMISSION_MEDIA_LIBRARY
PermissionGroup.sensorsNSMotionUsageDescriptionPERMISSION_SENSORS
PermissionGroup.bluetoothNSBluetoothAlwaysUsageDescription NSBluetoothPeripheralUsageDescriptionPERMISSION_BLUETOOTH
PermissionGroup.appTrackingTransparencyNSUserTrackingUsageDescriptionPERMISSION_APP_TRACKING_TRANSPARENCY
PermissionGroup.criticalAlertsPermissionGroupCriticalAlertsPERMISSION_CRITICAL_ALERTS

二、代码示例

import 'dart:io';

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

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {

  /// 动态申请权限,需要区分android和ios,很多时候它两配置权限时各自的名称不同
  /// 此处以保存图片需要的配置为例
  Future<bool> requestPermission() async {
    late PermissionStatus status;
    // 1、读取系统权限的弹框
    if (Platform.isIOS) {
      status = await Permission.photosAddOnly.request();
    } else {
      status = await Permission.storage.request();
    }
    // 2、假如你点not allow后,下次点击不会在出现系统权限的弹框(系统权限的弹框只会出现一次),
    // 这时候需要你自己写一个弹框,然后去打开app权限的页面
    if (status != PermissionStatus.granted) {
      showCupertinoDialog(
          context: context,
          builder: (context) {
            return CupertinoAlertDialog(
              title: const Text('You need to grant album permissions'),
              content: const Text(
                  'Please go to your mobile phone to set the permission to open the corresponding album'),
              actions: <Widget>[
                CupertinoDialogAction(
                  child: const Text('cancle'),
                  onPressed: () {
                    Navigator.pop(context);
                  },
                ),
                CupertinoDialogAction(
                  child: const Text('confirm'),
                  onPressed: () {
                    Navigator.pop(context);
                    // 打开手机上该app权限的页面
                    openAppSettings();
                  },
                ),
              ],
            );
          });
    } else {
      return true;
    }
    return false;
  }

  // 保存网络图片
  saveNetworkImg(String imgUrl) async {
    // Todo
    // 处理保存网络图片的逻辑
    EasyLoading.showToast('处理保存网络图片的逻辑');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('home'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async{
          // 使用
          // 首先判断是否有权限,没权限就不执行了
          bool permission = await requestPermission();
          permission ? saveNetworkImg('imgUrl') : null;
        },
        child: const Icon(Icons.adb),
      ),
    );
  }
}
 类似资料: