【Flutter】端末機能の使用権限を管理する

こんにちは、株式会社Pentagonの小寺です。

今回はカメラやアルバム、マイクといった端末機能を使用する際に使用権限を確認し、権限がなければ使用許可を求める方法を説明します。

【こんな人に読んで欲しい】

flutterを用いて端末機能を使用しようと考えている方

【この記事を読むメリット】

端末機能の使用権限の管理方法がわかる

目次

使用するパッケージ

今回はpermission_handlerと呼ばれるパッケージを使用して権限の確認、使用許可を求めていきます。また、今回のブログではカメラとアルバムの使用許可を例に説明します。

https://pub.dev/packages/permission_handler

Androidの設定

まず、android配下にあるgradle.propertiesに以下を追記してください。

android.useAndroidX=true
android.enableJetifier=true

Flutterバージョン3.1.0以降、permission_handlerプラグインがAndroidXに対応したことを受け、、permission_handlerを利用するアプリでもAndroidXをサポートする必要があります。このため、android/app/build.gradleのファイルでcompileSdkVersionが33に設定されていることを確認してください。


android {
  compileSdkVersion 33
  ...
}

次はandroid/src/main/AndroidManifest.xmlファイル内で、端末機能を使用するために以下のコードを追記してください。注意事項として、AndroidはOSバージョン13以降で使用許可の方法が変わっているため、13以前と以降の設定をそれぞれ追記する必要があります。

<!-- Permissions options for the camera group -->
<!-- Permissions options for the storage group -->

以上でAndroidの設定は完了です。

iOSの設定

iOSでもAndroidと同様に端末機能を使用するための設定を行います。
ios/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

上記のコードでは端末機能の使用許可を列挙しています。必要な標準機能の箇所のコメントアウトを外してください。今回はカメラとアルバムを使用するため、'PERMISSION_CAMERA=1',
'PERMISSION_PHOTOS=1',
これらのコードのコメントアウトをはずしています。

次にios/Runner/info.plistに以下のコードを追記してください。

NSCameraUsageDescription
このアプリではカメラを使用します
NSMicrophoneUsageDescription
このアプリではアルバムを使用します

こちらも今回はカメラとアルバムの使用のため上記2点を記載していますが、他の端末機能を使用する場合は該当する設定内容を記載してください。
内にある文言は実際にアプリで端末機能の使用許可を求める際に表示されるポップアップの文章です。必要に応じて文言を変更してください。
以上でiOSの設定が完了です。

権限のステータス一覧

permission_handlerで使われる権限ステータスの一覧を列挙します。

状態 説明
granted ユーザーが許可した状態
denied ユーザーが拒否した状態
restricted OSによって拒否された状態。iOSのみサポート
permanentDenied ユーザーが拒否した状態。Androidのみサポート
limited ユーザーが制限付きで許可した状態。iOSのみサポート

現在のステータスを取得する

カメラやアルバムを使用する際に現在の使用権限のステータスを確認し、許可されている状態であれば使用する、許可されていなければOSの設定画面を開く実装を行います。
まず、下記のコードで現在の状態を取得します。

カメラの場合

Future isCameraPermitted() async {
  final status = await Permission.camera.status;
  return status.isGranted || status.isLimited;
}

アルバムの場合

Future isPhotosPermitted() async {
  final status = await _getPermissionStatus();
  return status.isGranted || status.isLimited;
}

Future _getPermissionStatus() async {
  if (Platform.isAndroid) {
    final androidInfo = await DeviceInfoPlugin().androidInfo;
    final androidOsVersionStr = androidInfo.version.release.split('.').first;
    final androidOsVersion = int.parse(androidOsVersionStr);
    // アルバムを開く際にandroid13以前のrequest方法が違うためstatusの取得方法を変えている
    // ref: https://pub.dev/packages/permission_handler FAQ参照
    if (androidOsVersion < 13) {
      return Permission.storage.status;
    }
  }
  return Permission.photos.status;
}

アルバムの状態の取得については、androidの13以前と以降によって使用権限ステータスの取得方法が異なります。
_getPermissionStatus内でまず、端末がandroidかどうかを判断します。androidであればif文の中で端末のバージョン取得を行います。バージョンが13以降であればアルバムの権限取得はPermission.storage.statusで行い、13以前またはiOSではPermission.photos.statusで現在の状態を取得できます。
bool値であるstatusパラメタでは、grantedまたはlimitedであれば許可されている状態のためtrueを返し、それ以外はfalseを返しています。

まとめ

端末機能を使う場合は権限の取得が必須になるため、使う機能によって権限ステータスの取得を実装するようにしてください。また、androidについては取得方法がOSバージョンによって異なる場合があるので注意しましょう。

おまけ

Flutterに関する知識を深めたい方には、『Flutterの特徴・メリット・デメリットを徹底解説』という記事がおすすめです。

この記事では、Flutter アプリ開発の基本から、Flutter とは何か、そして実際のFlutter アプリ 事例を通じて、その将来性やメリット、デメリットまで詳しく解説しています。
Flutterを使ったアプリ開発に興味がある方、またはその潜在的な可能性を理解したい方にとって、必見の内容となっています。

ぜひ一度ご覧ください。

採用情報はこちら
目次