flutter 1.12 版本插件开发与获取权限总结

开发流程:

1、使用object-c和java语言模板创建插件项目,command line : flutter create --template=plugin -i objc -a java mobile_state

关键文件:

//这里是你的插件在dart 中引用的类文件,也就是衔接native的dart插件类

lib/mobile_state.dart

//这里是你的插件对应的原生android文件

android/src/main/java/com/example/mobile_state/MobileStatePlugin.java

 

2、修改 lib/mobile_state.dart 下对应的 MethodChannel 与 invokeMethod() 方法中的参数

3、 通过invokeMethod() 方法发送的消息,在 java类文件中的 onMethodCall 方法中进行统一入口判断与实现

4、通过result类返回信息传递给dart

5、本地引用插件

 

在项目的 pubspec.yml 文件的依赖部分声明插件名称,这里的名称必须和你插件项目中的 pubspec.yml 文件的 name 一致。

 

格式:

dependencies: 
  flutter: 
    sdk: flutter 
  [插件name]: 
    path: [插件的项目路径,可用绝对或相对路径]

参考:

dependencies: 
  flutter: 
    sdk: flutter 
  mobile_state: 
    path: /opt/coding/flutter/plugins/test/flutter_plugin_test/

 

注意事项:

 

1、因为dart 语言和flutter 快速发展,在插件的java文件中,会有 onAttachedToEngine 和 registerWith 两个方法,目的是将类注册到dart对应的MethodChannel 中,

这两个方法功能一致,在一个项目中,只会触发其中一个方法,如果你使用的是 flutter >= 1.12.x ,则只会触发 onAttachedToEngine方法,如果是 flutter <= 1.12.x 版本则会触发 registerWith .

所以,当你在不同的版本中需要调用原生的交互时,特别要注意应该使用哪个方法进行原生调用。

2、关于 插件中引用 activity 的方式.

在 registerWith 方法中,通过方法参数中的 Registrar registrar 参数,进行获取.

registrar.activity()

如果你是 1.12.x 版本,那么在插件类中实现 ActivityAware 接口。

 

参考代码:

 

public class MyPlugin implements FlutterPlugin, ActivityAware {
  //...normal plugin behavior is hidden...

  @Override
  public void onAttachedToActivity(ActivityPluginBinding activityPluginBinding) {
    // TODO: your plugin is now attached to an Activity
  }

  @Override
  public void onDetachedFromActivityForConfigChanges() {
    // TODO: the Activity your plugin was attached to was destroyed to change configuration.
    // This call will be followed by onReattachedToActivityForConfigChanges().
  }

  @Override
  public void onReattachedToActivityForConfigChanges(ActivityPluginBinding activityPluginBinding) {
    // TODO: your plugin is now attached to a new Activity after a configuration change.
  }

  @Override
  public void onDetachedFromActivity() {
    // TODO: your plugin is no longer associated with an Activity. Clean up references.
  }
}

 

参考链接: https://github.com/flutter/flutter/wiki/Experimental:-Create-Flutter-Plugin

 

3、关于插件中可能遇到的权限申请和检查,则在拿到activity后按android 开发方式进行开发即可。

步骤:

1、首先需要向 AndroidMainfest.xml中添加权限

2、在申请权限的插件类中实现权限回调方法 onRequestPermissionsResult

3、然后再使用 ActivityCompat.requestPermissions 方法动态申请权限。

 

这里注意一下权限申请方法参数的意义,对于一个新手,网上很多资料都没有说明清楚。

 

权限申请方法: ActivityCompat.requestPermissions

参数列表:

参数

说明

Activity activity

当前申请权限的 activity,在插件类中通过实现ActivityAware 接口获取

String[] permissions

申请权限数组,这个可以再网上找到android权限列表

int requestCode

这个参数用于标识,哪个方法申请的权限,因为权限处理均在一个方法中,可能很多处代码均申请了权限,所以在处理时需要根据标识进行对应的返回结果处理。这个 requestCode 也会在 权限回调方法 onRequestPermissionsResult 中用上。

 

在插件中获取手机号码\IMEI等信息的完整参考代码:

 

package com.example.mobile_state;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.telephony.TelephonyManager;
import android.util.Log;

import androidx.annotation.NonNull;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.Registrar;

import android.Manifest;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;


/** MobileStatePlugin */
public class MobileStatePlugin implements FlutterPlugin, MethodCallHandler, ActivityAware {
  private static final int MY_PERMISSIONS_REQUEST_READ_PHONE_STATE = 0;
  private static PluginRegistry.Registrar registrar;
  private TelephonyManager telephonyManager;
  static final String CHANNEL = "plugins.zcaij.com/mobile_state";
  static Activity activity;


  ///activity 生命周期
  @Override
  public void onAttachedToActivity(ActivityPluginBinding activityPluginBinding) {
    Log.e("onAttachedToActivity", "onAttachedToActivity");
    activity = activityPluginBinding.getActivity();
  }

  @Override
  public void onDetachedFromActivityForConfigChanges() {
    Log.e("onDetachedFromActivityForConfigChanges", "onDetachedFromActivityForConfigChanges");

  }

  @Override
  public void onReattachedToActivityForConfigChanges(ActivityPluginBinding activityPluginBinding) {
    Log.e("onReattachedToActivityForConfigChanges", "onReattachedToActivityForConfigChanges");
  }

  @Override
  public void onDetachedFromActivity() {
    Log.e("onDetachedFromActivity", "onDetachedFromActivity");
  }


  @Override
  public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
    final MethodChannel channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), CHANNEL);
    channel.setMethodCallHandler(new MobileStatePlugin());
  }

  // This static function is optional and equivalent to onAttachedToEngine. It supports the old
  // pre-Flutter-1.12 Android projects. You are encouraged to continue supporting
  // plugin registration via this function while apps migrate to use the new Android APIs
  // post-flutter-1.12 via https://flutter.dev/go/android-project-migration.
  //
  // It is encouraged to share logic between onAttachedToEngine and registerWith to keep
  // them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called
  // depending on the user's project. onAttachedToEngine or registerWith must both be defined
  // in the same class.
  public static void registerWith(Registrar registrar) {

    final MethodChannel channel = new MethodChannel(registrar.messenger(), CHANNEL);
    channel.setMethodCallHandler(new MobileStatePlugin());
    activity = registrar.activity();

  }


  void getNumber(){
    String num = telephonyManager.getLine1Number();
    Log.d("xxxxx",num);
  }

  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {

    telephonyManager =  (TelephonyManager)activity.getSystemService(Context.TELEPHONY_SERVICE);


    if (call.method.equals("getPhoneNumber")) {


      int x = activity.checkSelfPermission(Manifest.permission.READ_PHONE_STATE);
      if(x != 0)
      {

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


      }else{
        getNumber();
      }


      result.success("xxxxx");

    } else {
      result.notImplemented();
    }
  }


  public void onRequestPermissionsResult(int requestCode,
                                         String[] permissions, int[] grantResults) {
    switch (requestCode) {
      case MY_PERMISSIONS_REQUEST_READ_PHONE_STATE: {
        // If request is cancelled, the result arrays are empty.
        if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
          // permission was granted, yay! Do the
          // contacts-related task you need to do.
        } else {
          // permission denied, boo! Disable the
          // functionality that depends on this permission.
          getNumber();
        }
        return;
      }

      // other 'case' lines to check for other
      // permissions this app might request.
    }
  }

  @Override
  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
  }


}

 

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页