欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

自己写一个flutter插件

程序员文章站 2022-04-19 11:29:03
某些场景下或者现有pub插件无法满足我们的需求的时候需要自己写一个插件现在有这样一个场景,需要给定一个图片的url,然后下载图片到指定目录中(/storage/emulated/0/Android/data/com.zx.plugintest/files/Caches)。现在有一个插件,image_gallery_saver ,但它将网络文件保存在了我们的相册目录中。1、在flutter根目录下新建一个flutter 插件打开androidstudio terminalflutter.....

某些场景下或者现有pub插件无法满足我们的需求的时候需要自己写一个插件

现在有这样一个场景,需要给定一个图片的url,然后下载图片到指定目录中(/storage/emulated/0/Android/data/com.zx.plugintest/files/Caches)。现在有一个插件,image_gallery_saver ,但它将网络文件保存在了我们的相册目录中。

 

1、在flutter根目录下新建一个flutter 插件

打开androidstudio terminal 

flutter create --template=plugin  --org com.zx --platforms=android,ios -a java -i swift save_img_plugin

其中 com.zx 是插件包名的一部分,save_img_plugin 是插件的名称。插件的完整包名为 com.zx.save_img_plugin

为什么没有使用IDE 的选项创建呢,我创建出来没有android 和 ios的原生工程目录 

参考 https://blog.csdn.net/zytry/article/details/108997168

2、pubspec.yaml 添加插件

save_img_plugin:
  path: save_img_plugin

pub get 一下

3、在插件的lib\save_pic_plugin.dart添加如下代码

static Future saveImage(Uint8List imageBytes,
      {int quality = 80, String name}) async {
    assert(imageBytes != null);
    final result =
    await _channel.invokeMethod('saveImageToLocal', <String, dynamic>{
      'imageBytes': imageBytes,
      'quality': quality,
      'name': name,
    });
    return result;
  }

这里的代码是给其他flutter调用者 提供的外部接口。

4、实现native调用方法

package com.zx.save_img_plugin;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import androidx.annotation.NonNull;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import io.flutter.Log;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
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;

/** SaveImgPlugin */
public class SaveImgPlugin implements FlutterPlugin, MethodCallHandler {

  private static final String TAG = "SaveImgPlugin";
  private MethodChannel channel;
  private Context mContext;

  @Override
  public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
    channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "save_img_plugin");
    channel.setMethodCallHandler(this);
    mContext = flutterPluginBinding.getApplicationContext();
  }

  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
    Log.d(TAG,"---onMethodCall---");
    if (call.method.equals("saveImageToLocal")) {

      byte[] image = null;
      int quality = 100;
      String name = "splash.jpg";
      if (null != call.argument("imageBytes")) {
        image = call.argument("imageBytes");
      } else {
        result.error("the argument imageBytes is null","","");
      }

      if (null != call.argument("name")) {
        name = call.argument("name");
      }

      if (null != call.argument("quality")) {
        quality = call.argument("quality");
        if(quality <= 0 || quality>100) {
          result.error("the quality is in range(0,100]","","");
        }
      }
      result.success(saveImageToLocal(BitmapFactory.decodeByteArray(image,0,image.length), quality, name));
    }
  }

  private boolean saveImageToLocal(Bitmap bmp, int quality, String name) {
    Log.d(TAG,"---saveImageToLocal---");
    Context context = mContext.getApplicationContext();
    String cacheDir = context.getExternalFilesDir("Caches").getPath();
    Log.d(TAG,"---cacheDir---" + cacheDir);
    File file = new File(cacheDir + File.separator + name);  //将图片保存到刚创建好的目录下
    try {
      FileOutputStream out = new FileOutputStream(file);
      if (bmp != null) {
        bmp.compress(Bitmap.CompressFormat.JPEG, quality, out);
      }
      out.close();
      return true;
    } catch (IOException e) {
      e.printStackTrace();
    }
    return false;
  }

  @Override
  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
    channel.setMethodCallHandler(null);
  }
}

注意 :

1、flutter (save_pic_plugin.dart)传递的参数 saveImageToLocal 必须和 原生 if (call.method.equals("saveImageToLocal"))  中判断的名称相同才能进入对应逻辑。

2、平台通道数据类型支持

平台通道使用标准消息编/解码器对消息进行编解码,它可以高效的对消息进行二进制序列化与反序列化。由于Dart与原生平台之间数据类型有所差异,下面我们列出数据类型之间的映射关系。

Dart Android iOS
null null nil (NSNull when nested)
bool java.lang.Boolean NSNumber numberWithBool:
int java.lang.Integer NSNumber numberWithInt:
int, 如果不足32位 java.lang.Long NSNumber numberWithLong:
int, 如果不足64位 java.math.BigInteger FlutterStandardBigInteger
double java.lang.Double NSNumber numberWithDouble:
String java.lang.String NSString
Uint8List byte[] FlutterStandardTypedData typedDataWithBytes:
Int32List int[] FlutterStandardTypedData typedDataWithInt32:
Int64List long[] FlutterStandardTypedData typedDataWithInt64:
Float64List double[] FlutterStandardTypedData typedDataWithFloat64:
List java.util.ArrayList NSArray
Map java.util.HashMap NSDictionary

当在发送和接收值时,这些值在消息中的序列化和反序列化会自动进行。

在android 清单文件中添加两个权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>

至于权限怎么添加和使用,方式如下:

5、新建一个permission.dart

import 'package:permission_handler/permission_handler.dart';


Future<bool> requestStoragePermission() async {
  final storageStatus = await PermissionHandler().requestPermissions([PermissionGroup.storage]);
  if (storageStatus[PermissionGroup.storage] == PermissionStatus.granted) {
    return true;
  } else {
    return false;
  }
}

6、使用

import 'Permission.dart' as Permission;

void savePic() async {
    Permission.requestStoragePermission().then((value)  async {
      if(value) {
        var response = await Dio().get(
            "https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/image/h%3D300/sign=a62e824376d98d1069d40a31113eb807/838ba61ea8d3fd1fc9c7b6853a4e251f94ca5f46.jpg",
            options: Options(responseType: ResponseType.bytes));
        SaveImgPlugin.saveImage(Uint8List.fromList(response.data),quality:100,name:'mypic1.png').then((value) {
          setState(() {
            tip = 'down load over';
          });
        });
      }
    });
  }

完后在日志中找到 ---cacheDir---/storage/emulated/0/Android/data/com.zx.plugintestapp/files/Caches  ,这个里面就有我们下载好的图片文件。

ok,整个插件的基础开发就是这些了。

 

 

 

 

 

 

本文地址:https://blog.csdn.net/UserNamezhangxi/article/details/112568360

相关标签: android flutter