How to request permissions in a Flutter plugin?

13,582

Use Permission plugin for flutter

Request permission
import 'package:permissions_plugin/permissions_plugin.dart';

Map<Permission, PermissionState> permission = await PermissionsPlugin
    .requestPermissions([
        Permission.ACCESS_FINE_LOCATION,
        Permission.ACCESS_COARSE_LOCATION,
        Permission.READ_PHONE_STATE
    ]);
Check status permission
import 'package:permissions_plugin/permissions_plugin.dart';

Map<Permission, PermissionState> permission = await PermissionsPlugin
    .checkPermissions([
      Permission.ACCESS_FINE_LOCATION,
      Permission.ACCESS_COARSE_LOCATION,
      Permission.READ_PHONE_STATE
    ]);
Share:
13,582
comodoro
Author by

comodoro

Updated on June 08, 2022

Comments

  • comodoro
    comodoro almost 2 years

    I am trying to use a simple Flutter plugin (speech recognition wrapper) and have no idea how to request the appropriate permissions on Android 23 or newer. In the Dart part I have:

      Future requestPermissions() => 
      _channel.invokeMethod("speech.requestPermissions");
    

    In the Android part:

      public class SpeechRecognitionPlugin implements MethodCallHandler, RecognitionListener,
        PluginRegistry.RequestPermissionResultListener {
    

    Plugin registration:

      public static void registerWith(Registrar registrar) {
        final MethodChannel channel = new MethodChannel(registrar.messenger(), "speech_recognition");
        SpeechRecognitionPlugin speechRecognitionPlugin = new 
        SpeechRecognitionPlugin(registrar.activity(), channel);
        channel.setMethodCallHandler(speechRecognitionPlugin);
        registrar.addRequestPermissionResultListener(speechRecognitionPlugin);
      }
    

    Method call:

    else if (call.method.equals("speech.requestPermissions")) {
            Log.d(LOG_TAG, "speech.requestPermissions");
            if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
                    Manifest.permission.RECORD_AUDIO)) {
                Toast.makeText(activity.getApplicationContext(), "This application needs the Record Audio permission for recognition to work", Toast.LENGTH_LONG).show();
            } else {
                Log.d(LOG_TAG, "Requesting permissions");
                ActivityCompat.requestPermissions(activity,
                        new String[]{Manifest.permission.RECORD_AUDIO},
                        1);
            }
            result.success(hasRecordAudioPermission());
    

    Result callback:

    @Override                                                                                            
    public boolean onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults) {
        boolean granted = false;
        switch (requestCode) {
            case 1: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    granted = true;
                }
                speechChannel.invokeMethod("speech.onPermission", granted);
                return true;
            }
        }
        return false;
    }
    

    From logcat I see that the "speech.requestPermissions" call happens, but standard Android system permission request is not shown, just this in the logcat may be related:

    D/ViewRootImpl(21171): #1 mView = android.widget.LinearLayout{64f050b 
    V.E...... ......I. 0,0-0,0 #102039d android:id/toast_layout_root}
    D/ViewRootImpl(21171): MSG_RESIZED_REPORT: ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1
    D/ViewRootImpl(21171): #3 mView = null
    

    What is the correct way to request permissions for Flutter plugins?

    EDIT: This does not apply to the first run, when the dialog shows correctly, but to subsequent runs when the user did not grant the permission at first or revoked it via settings. I realize that changes the question significantly (making it appear as edge case), but Android permissions are not supposed to work that way.

    EDIT: The permissions are present in AndroidManifest.xml

  • comodoro
    comodoro over 6 years
    Thanks for assuring that this is at least a way to go. I have edited the question, first run works, but requesting permissions on the fly does not. Sorry for not mentioning it before.
  • AdaJane
    AdaJane over 6 years
    You will have to add the permission to the manifest as well (if you haven't already done that). See my edited answer for an example
  • AdaJane
    AdaJane over 6 years
    How are you checking to see if the permission has or hasn't already been granted? I'm using this in my plugin: PermissionChecker.checkSelfPermission(registrar.activity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
  • comodoro
    comodoro over 6 years
    int permissionCheck = ContextCompat.checkSelfPermission(activity, Manifest.permission.RECORD_AUDIO); return (permissionCheck == PackageManager.PERMISSION_GRANTED); I will try your version when I get to the code.
  • comodoro
    comodoro over 6 years
    Unfortunately, no change. Now that I think about it, I do not know what did I expect from this change, the permission request call is no different.
  • AdaJane
    AdaJane over 6 years
    Is there any way you could post a more complete version of your code?
  • comodoro
    comodoro over 6 years
    The code I am tinkering with is on github, I have just forked it and commited my changes: github.com/comodoro/speech_recognition
  • AdaJane
    AdaJane over 6 years
    In the branch that you linked the required permissions are not listed in the AndroidManifest.xml
  • comodoro
    comodoro over 6 years
    Indeed, relevant notion. I have always assumed permissions had to be in the app manifest (not the plugin itself), nevertheless this should be tried. It has been, still no change
  • Andris
    Andris about 4 years
    In this package is mentioned, that it only for now supports just android.