美文网首页
Android端Flutter插件开发

Android端Flutter插件开发

作者: Gavin_2020 | 来源:发表于2021-01-28 11:37 被阅读0次

    一、简介

    此文章主要记录本人的flutter插件开发过程以及遇到的问题等,如有错误请指正.

    二、开发准备(Windows)

    1.Android Studio 4.0以上
    2.Flutter SDK

    三、环境配置

    1.安装flutter sdk

    下载好之后,解压,找到根目录下的flutter文件下找到flutter_console.bat,双击运行并启动flutter命令行。

    2.更新环境变量

    要在终端运行 flutter 命令, 你需要添加以下环境变量到系统PATH:

    转到 “控制面板>用户帐户>用户帐户>更改我的环境变量”
    在“用户变量”下检查是否有名为“Path”的条目:
    如果该条目存在, 追加 flutter\bin的全路径,使用 ; 作为分隔符.
    如果条目不存在, 创建一个新用户变量 Path ,然后将 flutter\bin的全路径作为它的值.
    在“用户变量”下检查是否有名为”PUB_HOSTED_URL”和”FLUTTER_STORAGE_BASE_URL”的条目,如果没有,也添加它们。
    重启Windows以应用此更改

    3.测试flutter环境

    打开命令行输入:flutter doctor

    flutter_plugin.png
    如图可以看到有两个报错为插件工具没有导入可查看这里解决问题:
    https://www.jianshu.com/p/3dc7dbd0712c

    四、插件开发

    1.使用Android Studio创建flutter插件

    参照: https://www.jianshu.com/p/3dc7dbd0712c

    2.编译插件桥接类

    找到插件桥接类


    微信截图_20210125172304.png

    打开后可以看到很多红色报错,如下图可以点开新的AS界面进行编译:


    微信截图_20201224104312.png
    3.方法简介
    onAttachedToEngine方法

    初始化方法,"flutter_vin_plugin"为定义好的插件桥接类名,后面调用需要一一对应。

    @Override
        public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
            channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "flutter_vin_plugin");
            channel.setMethodCallHandler(this);
        }
    
    onMethodCall方法

    接受从js层获取参数的方法"isCropImage"等都是传递的参数标识通过MethodCall 对象获取传递过来的数据
    startScanVin等为自定义的原生方法,里面可以自定义一些操作

        @Override
        public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
            resultPlugin = result;
            String isCrop = call.argument("isCropImage");
            ConstantConfig.isImportCrop = !TextUtils.isEmpty(isCrop) && isCrop.equals("1");
            ConstantConfig.isCheckMotorbike = Boolean.getBoolean(call.argument("containMoto") + "");
            initOcrFile();
            if (call.method.equals("scanVin")) { 
                startScanVin();
            } else if (call.method.equals("imageVin")) {  
                startImport();
            } else {
                unInitOcrApi();
                result.notImplemented();
            }
        }
    
    onAttachedToActivity方法

    此方法的包含一些原生的activity中的一些监听方法,添加监听后可实现对应的原生方法。
    ①addRequestPermissionsResultListener: 对应原生中的权限监听方法
    ②addActivityResultListener:对应原生中activity回调方法等一些有关activity生命周期的方法

    @Override
        public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
            this.activity = binding.getActivity();
            binding.addRequestPermissionsResultListener(new PluginRegistry.RequestPermissionsResultListener() {
                @Override
                public boolean onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
                    switch (requestCode) {
                        case SCAN_PERMISSION_CODE:
                            if (permissions.length != 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {//失败
                                Toast.makeText(activity, "请允许权限在识别", Toast.LENGTH_SHORT).show();
                            } else {//成功
                                //启动启动VIN码扫描识别页面
                                Intent intent = new Intent(activity, ScanVinActivity.class);
                                activity.startActivityForResult(intent, VIN_RECOG_CODE);
                            }
                            break;
                        case IMPORT_PERMISSION_CODE:
                            if (permissions.length != 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {//失败
                                Toast.makeText(activity, "请允许权限在识别", Toast.LENGTH_SHORT).show();
                            } else {//成功
                                //启动启动VIN码导入识别页面
                                Intent intent = new Intent(activity, VinRecogActivity.class);
                                activity.startActivityForResult(intent, VIN_RECOG_CODE);
                            }
                            break;
                    }
                    return false;
                }
            });
            binding.addActivityResultListener(new PluginRegistry.ActivityResultListener() {
                @Override
                public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
                    if (data != null && requestCode == VIN_RECOG_CODE) {
                        //接收所有识别结果,图片
                        String vinResult = data.getStringExtra("vinResult");
                        //接收识别结果的状态码,0表示成功,其他值表示识别失败
                        int recogCode = data.getIntExtra("recogCode", -1);
                        String vinThumbPath = data.getStringExtra("vinThumbPath");
                        String vinAreaPath = data.getStringExtra("vinAreaPath");
                        Map<String, String> map = new HashMap<>();
                        map.put("ocrResult", vinResult);
                        map.put("ocrThumbPath", vinThumbPath);
                        map.put("ocrAreaPath", vinAreaPath);
                        resultPlugin.success(map);
                    }
                    return false;
                }
            });
        }
    

    到此插件部分已经开发的差不多了

    五、引用插件

    1.在插件中的demo调用测试

    找到插件目录下的lib文件夹下的文件打开如下;


    微信截图_20210128104358.png

    此文件为插件原生与js端沟通的桥梁所有的方法交互都需要通过此方法
    如下图,一共定义几个方法,比如licName等参数是js传递过来的参数,将这些参数放入param中,通过我们上面定义的flutter_vin_plugin的对象_channel执行invokeMethod方法调用原生并声明原生中的方法名scanVin以及传递js端数据集合param,,通过map接受原生中返回的数据即可.


    微信截图_20210128105151.png
    找到js端主页
    微信截图_20210128110329.png

    打开后可以定义我们在桥接中定义好的方法名称


    微信截图_20210128110637.png
    下面在main.dart中定义对应调用的方法:
    result为从原生获取的数据_resultOcr为定义好的变量.
        Future<void> scanVin() async {
          Map<String, String> result;
        // 参数说明 ("授权文件名称","是否屏蔽部分校验规则") 0为false 1为true
          result = await FlutterVinPlugin.scanVin("7332DBAFD2FD18301EF6", "0"); // TODO 扫描识别
          setState(() {
            _resultMap = result;
            _resultOcr = _resultMap['ocrResult'];
            _resultThumbPath = _resultMap['ocrThumbPath'];
            _resultAreaPath = _resultMap['ocrAreaPath'];
          });
        }
    

    然后即可在view中点击监听调用:


    微信截图_20210128110842.png

    main.dart中这里不多做描述了,具体可以查看官方文档学习如何开发。

    2.在实际项目中调用测试
    ①将插件复制进Flutter项目目录中
    ②Flutter项目中的pubspec.yaml文件,进行如下图配置,path根据自己的插件的相对路径配置
    图片1.png
    ③在你的项目中打开pubspec.yam文件执行插件引用如图:
    图片2.png
    ④在你的项目中打开example下GeneratedPluginRegistrant.Java代码,可以看到这里已经成功引用了FlutterVinPlugin插件如图
    图片3.png

    六、调试运行

    微信截图_20210128113627.png

    运行成功


    微信截图_20210128113700.png

    相关文章

      网友评论

          本文标题:Android端Flutter插件开发

          本文链接:https://www.haomeiwen.com/subject/qaytoktx.html