스터디/Flutter+Dart

Flutter Permission 권한확인 (permission_handler)

Dalmangyi 2019. 7. 31.

이번에는 Permission에 대해서 써볼까 합니다 

권한은 사용자에게 허락을 맡고 쓰는 기능을 말하는데요. 

주로 파일을 쓸 때, 쓸 수 있는 권한을 앱에 부여할 것인지.

카메라나 갤러리에 접근할 수 있는 권한을 부여할 것인지를 사용자에게 물어보게 됩니다. 

 

이런 기능들이 은근히 귀찮은 부분들이 많은데.

안드로이드는 박상권님의 Permission Library를 쓰면 정말 간단히 되고,

아이폰에서는 오히려 쉽게 되다 보니 딱히 안써본거 같습니다 

 

잡소리를 이만하고 시작해보겠습니다!..

 

 

플러터의 권한확인 패키지

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

퍼미션 승인 체크를 할 수 잇고.

퍼미션을 요청할 수 잇고

퍼미션 세팅창을 열 수 있는 패키지라고 합니다

 

 

 

 

 

 

사용자에게 요청할 수 있는 권한 종류

사용자에게 요청하는 권한들은 보호 레벨 위험 수준의 권한들입니다. 

보호 레벨이란 개인정보를 포함하거나 사용자로 인해 생성된 데이터를 접근해서

다른 앱에 영향을 줄 수 있는 데이터들을 필요로 하는 정도를 의미합니다.

 

안드로이드의 권한을 접근하는 커맨드와 아이폰의 권한 커맨드는 같은 의미도 있지만,

서로 다른 의미로 쓰는 경우도 있고, 한쪽 플랫폼에서만 지원하는 것도 있습니다.

그래서 아래처럼 정리해봅니다 

 

enum PermissionGroup {

Type (Return / Request) (value) Android iOS

unknown 

(Only ReturnType)

 - -

calendar (0)

달력 관리

Calendar Calendar (Events)

camera (1)

사진 찍기, 비디오 녹화

Camera Photos (Camera Roll and Camera)

contacts (2)

연락처 관리

Contacts Address Book

location (3)

현재 기기 위치

Fine And Coarse Location CoreLocation (Always and WhenInUse)

locationAlways (4)

현재 기기 위치

Fine and Coarse Location CoreLocation (Always)

locationWhenInUse (5)

현재 기기 위치

Find And Coarse Location CoreLocation (WhenInUse)

microphone (7)

오디오 녹음

Microphone Microphone

speech (13)

오디오 말하기 (글자 읽어주기)

Microphone Speech

phone (8)

전화 걸기, 관리

Phone x

reminders (10)

미리 알림

x Reminders

sensors (11)

심박수 및 신체 센서

Body Sensors CoreMotion

sms (12)

문자 보내기, 보기

Sms x

storage (14)

사진, 미디어, 파일 접근

External Storage x

photos (9)

미디어 라이브러리

x MPMediaLibrary

}

 

권한 옆에 괄호 친 숫자는 디버깅시 사용되는 숫자 입니다.

 

사용자의 확인을 필요로 하지 않은 블루투스 같은 권한은 리스트에 없습니다

블루투스의 경우 안드로이드의 메니페스트에 직접 추가, 아이폰에는 Capabilities에서 'Uses Bluetooth LE accessories'를 직접 선택 해야 합니다.

 

 

 

 

라이브러리 추가 

패키지를 쓰기 위해.. 우선, pubspec.yaml 파일의 디펜던시(dependencies)에 라이브러리를 추가합니다

dependencies: 
	permission_handler: ^3.2.0

 

 

 

 

안드로이드X 기능 지원

안드로이드에서는 도와주는 라이브러리들을 android.support.* 패키지명으로 사용했고, 

그 라이브러리들을 정리했던것을 android.arch.* 패키지로 새롭게 제공했었는데

기존처럼 라이브러리를 찾아 다녀야 하고, 테스트 해봐야 하는 번거로움을 없애는 의미로 Android를 빠르게 시작(초보개발)할 수 있게 Jetpack이란 것을 만들어서 제공하기 시작했는데 이때 나온 패키지명이 androidx.* 패키지 입니다 

 

이 기능을 사용할것인지 아닌지를 설정할 수 있습니다

 

1) android/gradle.properties 파일에 아래 코드를 추가합니다

android.useAndroidX=true
android.enableJetifier=true

 

2) android/app/build.gradle 파일에 compileSdkVersion을 28 이상으로 설정합니다

android {
 compileSdkVersion 28

 ...
}

 

 

 

플랫폼 별 권한 추가

예를 들어서 카메라를 다뤄보겠습니다

참고로 아이폰 에뮬레이터에서는 카메라 권한을 확인할 수 없습니다

1) Android 권한 Manifest 파일 (android/app/src/main/AndroidManifest.xml) 에 추가

<manifest>
    ...
    <uses-permission android:name="android.permission.CAMERA"/>
    ...
</manifest>

 

2) iOS 권한 Info.plist 파일 (ios/Runner/Info.plist) 에 추가

<dict>
    ...
    <key>NSCameraUsageDescription</key>
    <string>${PRODUCT_NAME} Camera Usage</string>
    ...
</dict>

 

 

 

패키지 추가

import 'package:permission_handler/permission_handler.dart';

 

 

권한확인 요청하기

권한 확인은 기본적으로 비동기로 작동하기 때문에 await과 async가 따라 다닙니다

void permission() async {

  Map<PermissionGroup, PermissionStatus> permissions = await PermissionHandler().requestPermissions([PermissionGroup.camera]);
  print('per1 : $permissions');
  
}

여러개의 권한을 배열로 묶어서 한번에 요청할 수 있습니다.

하지만 한번 승인경우에는 requestPemissions가 동작할 필요가 없어서 바로 결과가 리턴됩니다

거절 한 경우에는 안드로이드는 다시 요청할 수 있지만, 아이폰의 경우는 거절을 누르게 되면 직접 세팅창으로 접속해서 수락으로 변경해야 합니다 (세팅창 접근 기능에 대한 설명을 하단에 써두었습니다)

 

왼쪽부터 - 안드로이드 권한 요청, 안드로이드 권한 재요청, 아이폰 권한 요청

아이폰의 Info.plist파일에서 ${PRODUCT_NAME} 이라는 빌드 스키마에서 따온 이름이 적용되어 있다. 

Runner를 다른 이름으로 바꿀려면 스키마를 바꾸던가. ${} 부분을 다른걸로 바꾸면 된다. 

바꿀때 참고 링크 : https://flutter.dev/docs/deployment/ios

 

 

 

 

권한 확인창에서 누르는 응답을 모아서 Map 형태로 return 해준다. 

I/flutter (27912): per1 : {PermissionGroup.camera: PermissionStatus.granted}

 

 

권한 상태

이 패키지에서 권한의 상태는 다음과 같이 정의되어 있습니다

enum PermissionStatus {

모름 unknown 상태를 알 수 없음. 주로 Manifest 혹은 Info.plist에 추가하지 않았을 경우 입니다.
거절 denied 요청한 기능에 대한 액세스 권한이 사용자에 의해 거부되었습니다.
불가 disabled 기능에 대한 액세스 권한은 사용자가 부여하지만, 이 기능은 사용할 수 없는 경우.
허용 granted 요청한 기능에 대해 엑세스 권한이 사용자에 의해 부여된 경우.
제한 restricted iOS전용. 사용자가 요청한 기능에 대해 제한된 액세스 권한을 부여한 경우. (주로 거절로 생각합니다)

}

 

 

권한 상태 확인하기

PermissionStatus permission = await PermissionHandler().checkPermissionStatus(PermissionGroup.camera);
print('per2 : $permission');

권한 상태 확인은 한번에 1개의 상태만 체크할 수 있습니다

flutter: per2 : PermissionStatus.denied

 

 

 

 

앱 설정창 키기 

bool isOpened = await PermissionHandler().openAppSettings();
print('setting open : $isOpened');

열리거나 열리지 않고 나면 print가 찍힙니다 

flutter: setting open : true

스크린에 나와있는것처럼 에뮬레이터에서는 앱의 설정 화면으로 갈 수 없으니 참고해주세요 

 

 

왼쪽부터 - 안드로이드 앱 설정화면, 아이폰 에뮬레이터 앱 설정화면, 아이폰 실제폰 앱 설정화면

 

+) 동시 실행 경고

권한확인을 이미 요청했는데도 불구하고 권한확인을 요청할 경우에 뜨는 Exception입니다

 

 

 

개인정보보호 법.....

앱 권한 사용시, 한국에선 방송통신위원회에서 공시한것처럼 개인정보보호법을 준수해서 개인정보보호 안내서를 작성해서 사용자에게 제공해야 합니다. 안내서는 주로 앱의 개인정보보호 링크를 통해서 제공합니다

자세한건 링크를 통해서 확인해주세요

https://kcc.go.kr/user.do?mode=view&page=A05030000&boardId=1113&boardSeq=44546 

 

 

 

 

마치며

완료! 권한이 이렇게 쉽게 될줄이야..

flutter에서 permission까지 관리해주는 plugin이 나오면 좋겠지만.

일단은 이정도로 만족하며 글을 마칩니다.

 

 

 

 

댓글