【问题标题】:How to request permissions in a Flutter plugin?如何在 Flutter 插件中请求权限?
【发布时间】:2018-05-31 04:53:41
【问题描述】:

我正在尝试使用一个简单的 Flutter 插件(语音识别包装器),但不知道如何在 Android 23 或更高版本上请求适当的权限。在 Dart 部分我有:

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

在Android部分:

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

插件注册:

  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);
  }

方法调用:

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());

结果回调:

@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;
}

从logcat我看到“speech.requestPermissions”调用发生了,但是没有显示标准的Android系统权限请求,只是logcat中的这个可能是相关的:

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

什么是请求 Flutter 插件权限的正确方法?

编辑:当对话框正确显示时,这不适用于第一次运行,但适用于用户最初未授予权限或通过设置撤销权限时的后续运行。我意识到这会显着改变问题(使其显示为边缘情况),但 Android 权限不应该以这种方式工作。

编辑:权限存在于 AndroidManifest.xml

【问题讨论】:

    标签: android permissions flutter


    【解决方案1】:

    假设您想使用permission_handler 包请求相机权限。

    1. pubspec.yaml 文件中:

      permission_handler: ^8.0.0+2
      
    2. (Android)添加android/app/src/main/AndroidManifest.xml文件的权限

      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 
        ...
       </manifest>
      
    3. (对于 iOS),

      (i) 将此添加到您的 info.plist 文件中

      <key>NSCameraUsageDescription</key>
      <string>App needs camera permission to work</string>
      

      (ii) 将'PERMISSION_CAMERA=1' 添加到您的Podfile

      post_install do |installer|
        installer.pods_project.targets.each do |target|
          flutter_additional_ios_build_settings(target)
      
          target.build_configurations.each do |config|
            config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
              '$(inherited)',
      
              ## Add the following line.
               'PERMISSION_CAMERA=1'
            ]
      
          end
        end
      end
      
    4. 请求许可:

      final status = await Permission.camera.request();
      if (status == PermissionStatus.granted) {
        print('Permission granted');
      } else if (status == PermissionStatus.denied) {
        print('Permission denied. Show a dialog and again ask for the permission');
      } else if (status == PermissionStatus.permanentlyDenied) {
        print('Take the user to the settings page.');
        await openAppSettings();
      }
      

    【讨论】:

      【解决方案2】:

      使用Permission plugin for flutter

      请求许可
      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
          ]);
      
      检查状态权限
      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
          ]);
      

      【讨论】:

      • 在这个包中提到,它现在只支持android。
      【解决方案3】:

      我有这个为位置权限工作。我唯一不同的是在您的方法调用中:

      ActivityCompat.requestPermissions(activity,
                      new String[]{Manifest.permission.RECORD_AUDIO},
                      1);
      

      我没有使用“ActivityCompat”,而是将注册器存储在本地最终变量中,并且我正在执行以下操作:

      registrar.activity().requestPermissions(activity,
                      new String[]{Manifest.permission.RECORD_AUDIO},
                      1);
      

      编辑:还要确保您已在 AndroidManifest.xml 中包含相关权限

      <manifest xmlns:android="http://schemas.android.com/apk/res/android">
      
          <!-- Add this -->
          <uses-permission android:name="android.permission.RECORD_AUDIO" />
      
          <!-- Flutter stuff --->
      </manifest>
      

      【讨论】:

      • 感谢您确保这至少是可行的方法。我已经编辑了问题,第一次运行有效,但即时请求权限却没有。很抱歉之前没有提及。
      • 您还必须将权限添加到清单中(如果您还没有这样做的话)。请参阅我编辑的答案以获取示例
      • 您如何检查权限是否已被授予?我在我的插件中使用它: PermissionChecker.checkSelfPermission(registrar.activity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
      • int permissionCheck = ContextCompat.checkSelfPermission(activity, Manifest.permission.RECORD_AUDIO);返回(permissionCheck == PackageManager.PERMISSION_GRANTED);当我得到代码时,我会试试你的版本。
      • 很遗憾,没有变化。现在想来,我不知道我对这个变化有什么期望,权限请求调用也不例外。
      猜你喜欢
      • 2021-11-01
      • 2021-02-15
      • 2020-07-20
      • 2019-09-03
      • 2020-07-31
      • 2021-01-26
      • 2022-08-02
      • 1970-01-01
      • 2021-09-10
      相关资源
      最近更新 更多