Flutter Permission ( permission_handler )

    이제 앱에서 권한 체크는 필수가 되었죠. 

     

    플러터에서는 permission_handler 라는 좋은 라이브러리가 있습니다. 

    어떠한 권한이 있는지, 어떻게 해야 하는지 궁금하시면 하기 링크에 리스트 되어 있습니다. 

    https://pub.dev/documentation/permission_handler_platform_interface/latest/permission_handler_platform_interface/Permission-class.html#constants

     

    Permission class - permission_handler_platform_interface library - Dart API

    Defines the permissions which can be checked and requested. Implementers Annotations Constructors Permission.byValue(int value) Creates a Permission using the supplied integer value. factory Properties hashCode → int The hash code for this object. [...]

    pub.dev

     

    기본적인 세팅은 Androd, iOS 각각 해줘야 합니다. 

     

    1. Android 

    - 버전 1.12 이전에 프로젝트를 만든 경우 프로젝트에 적용될 수 있습니다. 따라서 아래 링크에 방법으로 진행해주세요. 

    https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects

     

    GitHub - flutter/flutter: Flutter makes it easy and fast to build beautiful apps for mobile and beyond

    Flutter makes it easy and fast to build beautiful apps for mobile and beyond - GitHub - flutter/flutter: Flutter makes it easy and fast to build beautiful apps for mobile and beyond

    github.com

    - 버전 3.1.0부터는 permission_handler 플러그인이 안드로이드X 버전의 안드로이드 지원 라이브러리로 전환되었습니다. 즉, Android 프로젝트도 AndroidX를 지원하도록 업그레이드해야 합니다. 하기 링크를 참고해 주세요. 

    https://docs.flutter.dev/development/androidx-migration

     

    AndroidX Migration

    How to migrate existing Flutter projects to AndroidX.

    docs.flutter.dev

     

    1) "gradle.properties" 파일에 하기 내용을 추가 

    android.useAndroidX=true
    android.enableJetifier=true

    2) "android/app/build.gradle"에서 컴파일 버전응 31 

    android {
      compileSdkVersion 31
      ...
    }

    모두 AndroidX에 의존되어 있습니다. 

    3) AndroidManifest.xml 파일에 사용 권한을 추가합니다. 

    다음은 추가하실 수 있는 권한의 모든 내용입니다. 

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        package="com.baseflow.permissionhandler.example">
    
        <!--
        Internet permissions do not affect the `permission_handler` plugin, but are required if your app needs access to
        the internet.
        -->
        <uses-permission android:name="android.permission.INTERNET"/>
    
        <!-- Permissions options for the `contacts` group -->
        <uses-permission android:name="android.permission.READ_CONTACTS"/>
        <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
        <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
    
        <!-- Permissions options for the `storage` group -->
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    
        <!-- Permissions options for the `camera` group -->
        <uses-permission android:name="android.permission.CAMERA"/>
    
        <!-- Permissions options for the `sms` group -->
        <uses-permission android:name="android.permission.SEND_SMS"/>
        <uses-permission android:name="android.permission.RECEIVE_SMS"/>
        <uses-permission android:name="android.permission.READ_SMS"/>
        <uses-permission android:name="android.permission.RECEIVE_WAP_PUSH"/>
        <uses-permission android:name="android.permission.RECEIVE_MMS"/>
    
        <!-- Permissions options for the `phone` group -->
        <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
        <uses-permission android:name="android.permission.CALL_PHONE"/>
        <uses-permission android:name="android.permission.ADD_VOICEMAIL"/>
        <uses-permission android:name="android.permission.USE_SIP"/>
        <uses-permission android:name="android.permission.READ_CALL_LOG"/>
        <uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
        <uses-permission android:name="android.permission.BIND_CALL_REDIRECTION_SERVICE"/>
    
        <!-- Permissions options for the `calendar` group -->
        <uses-permission android:name="android.permission.READ_CALENDAR" />
        <uses-permission android:name="android.permission.WRITE_CALENDAR" />
    
        <!-- Permissions options for the `location` group -->
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    
        <!-- Permissions options for the `microphone` or `speech` group -->
        <uses-permission android:name="android.permission.RECORD_AUDIO" />
    
        <!-- Permissions options for the `sensors` group -->
        <uses-permission android:name="android.permission.BODY_SENSORS" />
    
        <!-- Permissions options for the `accessMediaLocation` group -->
        <uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
    
        <!-- Permissions options for the `activityRecognition` group -->
        <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
    
        <!-- Permissions options for the `ignoreBatteryOptimizations` group -->
        <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
    
        <!-- Permissions options for the `bluetooth` group -->
        <uses-permission android:name="android.permission.BLUETOOTH" />
        <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
        <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
        <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    
        <!-- Permissions options for the `manage external storage` group -->
        <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
    
        <!-- Permissions options for the `system alert windows` group -->
        <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    
        <!-- Permissions options for the `request install packages` group -->
        <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
    
        <!-- Permissions options for the `access notification policy` group -->
        <uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY"/>
    
        <application
            android:name="io.flutter.app.FlutterApplication"
            android:icon="@mipmap/ic_launcher"
            android:label="permission_handler_example"
            tools:ignore="AllowBackup,GoogleAppIndexingWarning">
    
            <activity android:name="io.flutter.embedding.android.FlutterActivity"
                android:launchMode="singleTop"
                android:theme="@android:style/Theme.Black.NoTitleBar"
                android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
                android:hardwareAccelerated="true"
                android:windowSoftInputMode="adjustResize"
                android:exported="true">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN"/>
                    <category android:name="android.intent.category.LAUNCHER"/>
                </intent-filter>
            </activity>
    
            <meta-data
                android:name="flutterEmbedding"
                android:value="2" />
        </application>
    </manifest>

     

     

    2.  iOS

    Info.plist 파일에 사용 권한을 추가합니다. 다음은 가능한 모든 사용 권한의 전체 목록이 포함된 Info.plist 예제입니다.
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    	<key>CFBundleDevelopmentRegion</key>
    	<string>$(DEVELOPMENT_LANGUAGE)</string>
    	<key>CFBundleExecutable</key>
    	<string>$(EXECUTABLE_NAME)</string>
    	<key>CFBundleIdentifier</key>
    	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    	<key>CFBundleInfoDictionaryVersion</key>
    	<string>6.0</string>
    	<key>CFBundleName</key>
    	<string>example</string>
    	<key>CFBundlePackageType</key>
    	<string>APPL</string>
    	<key>CFBundleShortVersionString</key>
    	<string>$(FLUTTER_BUILD_NAME)</string>
    	<key>CFBundleSignature</key>
    	<string>????</string>
    	<key>CFBundleVersion</key>
    	<string>$(FLUTTER_BUILD_NUMBER)</string>
    	<key>LSRequiresIPhoneOS</key>
    	<true/>
    	<key>UILaunchStoryboardName</key>
    	<string>LaunchScreen</string>
    	<key>UIMainStoryboardFile</key>
    	<string>Main</string>
    	<key>UISupportedInterfaceOrientations</key>
    	<array>
    		<string>UIInterfaceOrientationPortrait</string>
    		<string>UIInterfaceOrientationLandscapeLeft</string>
    		<string>UIInterfaceOrientationLandscapeRight</string>
    	</array>
    	<key>UISupportedInterfaceOrientations~ipad</key>
    	<array>
    		<string>UIInterfaceOrientationPortrait</string>
    		<string>UIInterfaceOrientationPortraitUpsideDown</string>
    		<string>UIInterfaceOrientationLandscapeLeft</string>
    		<string>UIInterfaceOrientationLandscapeRight</string>
    	</array>
    	<key>UIViewControllerBasedStatusBarAppearance</key>
    	<false/>
    
    	<!-- Permission options for the `location` group -->
        <key>NSLocationWhenInUseUsageDescription</key>
        <string>Need location when in use</string>
        <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
        <string>Always and when in use!</string>
        <key>NSLocationUsageDescription</key>
        <string>Older devices need location.</string>
        <key>NSLocationAlwaysUsageDescription</key>
        <string>Can I have location always?</string>
    
        <!-- Permission options for the `mediaLibrary` group -->
        <key>NSAppleMusicUsageDescription</key>
        <string>Music!</string>
        <key>kTCCServiceMediaLibrary</key>
        <string>media</string>
    
        <!-- Permission options for the `calendar` group -->
        <key>NSCalendarsUsageDescription</key>
        <string>Calendars</string>
    
        <!-- Permission options for the `camera` group -->
        <key>NSCameraUsageDescription</key>
        <string>camera</string>
    
        <!-- Permission options for the `contacts` group -->
        <key>NSContactsUsageDescription</key>
        <string>contacts</string>
    
        <!-- Permission options for the `microphone` group -->
        <key>NSMicrophoneUsageDescription</key>
        <string>microphone</string>
    
        <!-- Permission options for the `speech` group -->
        <key>NSSpeechRecognitionUsageDescription</key>
        <string>speech</string>
    
        <!-- Permission options for the `sensors` group -->
        <key>NSMotionUsageDescription</key>
        <string>motion</string>
    
        <!-- Permission options for the `photos` group -->
        <key>NSPhotoLibraryUsageDescription</key>
        <string>photos</string>
    
        <!-- Permission options for the `reminder` group -->
        <key>NSRemindersUsageDescription</key>
        <string>reminders</string>
    
        <!-- Permission options for the `bluetooth` -->
        <key>NSBluetoothAlwaysUsageDescription</key>
        <string>bluetooth</string>
        <key>NSBluetoothPeripheralUsageDescription</key>
        <string>bluetooth</string>
    
        <!-- Permission options for the `appTrackingTransparency` -->
        <key>NSUserTrackingUsageDescription</key>
        <string>appTrackingTransparency</string>
    </dict>
    </plist>​

    permission_handler 플러그인은 매크로를 사용하여 권한이 사용되도록 설정되었는지 여부를 제어합니다.
    1) 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 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/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
    end

    2) 사용할 권한 앞에 있는 # 문자를 제거합니다. 예를 들어, 일정관리에 접근해야 할 경우 코드는 다음과 같아야 합니다.

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

    3) Info.plist에서 해당 권한 설명을 삭제합니다. 예를 들어 카메라 권한이 필요하지 않은 경우 'NScameraUsageDescription'만 삭제하십시오. 다음은 권한과 Info.plist 키 간의 관계를 나열합니다.

    PermissionGroup.calendar | NSCalendarsUsageDescription | PERMISSION_EVENTS | | PermissionGroup.reminders | NSRemindersUsageDescription | PERMISSION_REMINDERS | | PermissionGroup.contacts | NSContactsUsageDescription | PERMISSION_CONTACTS | | PermissionGroup.camera | NSCameraUsageDescription | PERMISSION_CAMERA | | PermissionGroup.microphone | NSMicrophoneUsageDescription | PERMISSION_MICROPHONE | | PermissionGroup.speech | NSSpeechRecognitionUsageDescription | PERMISSION_SPEECH_RECOGNIZER | | PermissionGroup.photos | NSPhotoLibraryUsageDescription | PERMISSION_PHOTOS | | PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse | NSLocationUsageDescription, NSLocationAlwaysAndWhenInUseUsageDescription, NSLocationWhenInUseUsageDescription | PERMISSION_LOCATION | | PermissionGroup.notification | PermissionGroupNotification | PERMISSION_NOTIFICATIONS | | PermissionGroup.mediaLibrary | NSAppleMusicUsageDescription, kTCCServiceMediaLibrary | PERMISSION_MEDIA_LIBRARY | | PermissionGroup.sensors | NSMotionUsageDescription | PERMISSION_SENSORS | | PermissionGroup.bluetooth | NSBluetoothAlwaysUsageDescription, NSBluetoothPeripheralUsageDescription | PERMISSION_BLUETOOTH | | PermissionGroup.appTrackingTransparency | NSUserTrackingUsageDescription | PERMISSION_APP_TRACKING_TRANSPARENCY |
    | PermissionGroup.criticalAlerts | PermissionGroupCriticalAlerts | PERMISSION_CRITICAL_ALERTS |

    4) Clean & Rebuild 하세요. 

     

     

     

    위 내용을 선행하고 권한을 얻는 방법은 다음과 같습니다. 

    if (await Permission.contacts.request().isGranted) {
      // Either the permission was already granted before or the user just granted it.
    }
    
    // You can request multiple permissions at once.
    Map<Permission, PermissionStatus> statuses = await [
      Permission.location,
      Permission.storage,
    ].request();
    print(statuses[Permission.location]);

     

    다른 방법들은 하기 링크를 참고하세요. 

    https://pub.dev/packages/permission_handler

     

    permission_handler | Flutter Package

    Permission plugin for Flutter. This plugin provides a cross-platform (iOS, Android) API to request and check permissions.

    pub.dev

     

    'Flutter(플러터) > Setting' 카테고리의 다른 글

    Flutter Firebase - iOS  (0) 2022.01.14
    Flutter Flavor 빌드 환경 구성  (0) 2022.01.03

    댓글