はじめに
以前、「権限(Permission)のリクエスト方法」の記事を書きましたがFlutter2になって試したところ全く動かなくなっていました。
なので、今回は改めて権限のリクエストをFlutter2系で実装してみたいと思います。
前回の記事はこちら
環境
- Flutter 2.2.3
 - permission_handler 8.1.4+2
 
準備
プラグインの最新バージョンを確認
下記のサイトにアクセスし、バージョンを確認します。

記事作成の時点では8.1.4+2が最新バージョンでした

プラグインのインストール
pubspec.yamlのdependenciesに「permission_handler: ^8.1.4+2」を追記します。もしくは常に最新版を使う設定の「permission_handler: any」を追記します。
dependencies:
  flutter:
    sdk: flutter
  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.2
  permission_handler: ^8.1.4+2
その後、プロジェクト配下で「flutter pub get」コマンドを実行
よくわからない場合はAndroid Studioでpubspec.yamlファイルを開くと右上に「Pub get」ボタンがあるのでそれを押してください。

これでプラグインのインストールは完了です。
アプリの設定を追加および変更
次にアプリの設定を追加及び変更を行います。
この対応をしないと予期せぬタイミングでアプリがクラッシュするので絶対に対応を行ってください。
OS毎に対応する必要があります。
Android
gradle.propertiesに追記
gradle.propertiesに以下を追記してください。
Flutter2系でプロジェクトを作成した場合は既に記述がある場合もあります。
android.useAndroidX=true
android.enableJetifier=true
compileSdkVersionの変更
android/app/build.gradleを開き、compileSdkVersionを30に変更してください。
ただし、Flutter2系でプロジェクトを作成した場合は既に変更されている場合もあります。
android {
  compileSdkVersion 30
  ...
}
android.の依存関係を修正
Androidで使われているandroid.の依存関係を全てAndroidX(androidx.)へ変更してください。
Flutter2系でプロジェクトを作成した場合は既に対応されているので特に何もする必要はありません。
やり方はAndroidの公式のサイトを参考にしてください

AndroidManifest.xmlに必要な権限(Permission)を追加
android/app/src/main/AndroidManifest.xmlに使いたい権限を追加してください。
debugやprofileフォルダにもAndroidManifest.xmlはありますが、基本的にはmainフォルダのものに対応すれば平気です。
例えばカメラとBluetoothの権限を付与したい場合は、以下のように記述します。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.test">
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <application
        android:name="io.flutter.app.FlutterApplication"
        android:icon="@mipmap/ic_launcher"
...
下記のGitHubには全ての権限(Permission)が入ったサンプルがありますので参考にしてみてください。
これでAndroidは完了です。
iOS
Info.plistに権限(Permission)に説明文を追加
Android StudioでiOSフォルダを右クリックして[Flutter]→[Open iOS module in Xcode]を選択して、Xcodeを開きます。
-1024x576.png)
Xcodeが開いたら、Runner/Runner/Info.plistを開きます。

そこに利用する権限の説明文を追加します。ここに入力する内容はユーザー表示されます。
例えばカメラロール、カメラ、マイクを利用するのであれば以下の3つを追加します。
- Privacy – Photo Library Usage Description
 - Privacy – Camera Usage Description
 - Privacy – Microphone Usage Description
 

(オプション)Podfileを編集
多分ですが、この項目はやらなくても平気ですがやることをオススメします。
iOSでアプリを提出する際には利用している全ての権限がInfo.plistには必要です。
この対応をすることで、Info.plistに漏れが合った場合にAssertを表示してくれる仕組みだそうです。
ios/Podfileを開きます。
そしてこの部分を
post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
  end
end
下記のようにまずは書き換えます
post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(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
そして、必要な権限の部分のコメントアウトを解除(#を取り除く)します。
仮に必要な権限がカメラとマイクならばPERMISSION_CAMERAとPERMISSION_MICROPHONEのコメントを解除して以下のようにします。
post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(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
そして、その後プロジェクト配下で「flutter clean」を実行してください。
よくわからない場合はAndroid Studioから[Tools]→[Flutter]→[Flutter Clean]を実行してください。
-1024x576.png)
これでiOSは完了です。
使い方
権限(Permission)の状態を確認するには以下のようなコードを書きます。
    // カメラの権限の状態を調べる.
   final status = await Permission.camera.status;
statusの種類は
| PermissionStatus | 内容 | 
| denied | ユーザーが拒否した状態。 | 
| granted | ユーザーが許可した状態。 | 
| restricted | OSによって拒否された状態。iOSのみサポート。 | 
| limited | ユーザーが制限付きで許可した状態。iOSのみサポート。 | 
| permanentlyDenied | ユーザーが拒否した状態。この許可を要求する際は許可ダイアログが表示されない。Androidのみサポート | 
次に許可ダイアログを表示する方法は以下のような2パターンです。
ただし、許可ダイアログは最初の1回しか表示されません。
    // カメラの権限をリクエスト
    final status = await Permission.camera.request();
    // カメラの権限をリクエストかつ許可がもらえたかどうかを判定する.
    if (await Permission.camera.request().isGranted) {
        // ここは権限の許可がある状態の処理を書く.
    }
また、複数同時に権限をリクエストすることもできます。
    // カメラとマイクの権限を一気にリクエスト.
    Map<Permission, PermissionStatus> statuses = await [
      Permission.camera,
      Permission.microphone,
    ].request();
他におすすめなのは端末の設定画面を開くこともできます。
openAppSettings();
サンプルコード
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}
class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
  void requestPermission() async {
    final status = await Permission.photos.request();
    if (!status.isGranted) {
      await Future.delayed(Duration(seconds: 1));
      openAppSettings();
      return;
    }
    // ここにphotoを使う処理を書く.
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'TEST',
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: requestPermission,
        tooltip: 'Permission',
        child: Icon(Icons.security),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}
さいごに
プラグインのメインのバージョンが上がると、とたんに動かなくなるから焦りますよね?
  
  
  
  



コメント