IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Flutter 图片、视频上传 -> 正文阅读

[移动开发]Flutter 图片、视频上传

在开发过程中,我们经常会用到图片上传,有的时候还要视频上传,那我们如何实现图片和视频上传呢?

这里我们要想实现这些涉及到几个插件

  dio: 3.0.8
  dio_cookie_manager: 1.0.0
  fluttertoast: ^3.1.3
  image_picker: ^0.6.3+1
  permission_handler: ^5.0.1+1

添加完这几个插件我们需要 pub get 一下。注意:fluttertoast这个插件是一个提示框,如果不使用,不用引用也可以

pub get

因为图片上传我们使用的地方有很多,所以我这里对这个图片上传类进行了封装,类名:HttpFileUtils

下面是实现我们用到的插件dio、?dio_cookie_manager

import 'package:dio/adapter.dart';
import 'package:dio/dio.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
import 'dart:convert';
import 'dart:io';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:nursery_school_gardener/constant/Url.dart';
import 'package:nursery_school_gardener/data/base_requst.dart';
import 'package:nursery_school_gardener/util/Variable.dart';

//要查网络请求的日志可以使用过滤<net>
class HttpFileUtils {
  static const String POST = "post";

  //post请求
  static void post(String url, Function callBack,
      {FormData formData, Function errorCallBack}) async {
    _request(url, callBack,
        formData: formData, method: POST, errorCallBack: errorCallBack);
  }

  //具体的还是要看返回数据的基本结构
  //公共代码部分
  static void _request(String url, Function callBack,
      {String method, FormData formData, Function errorCallBack}) async {
    String errorMsg = "";
    int statusCode;

//    params['token'] = DataBase.TOKEN;
    BaseOptions baseOptions;
    try {
      baseOptions = new BaseOptions(
          baseUrl: Url.BASE_URL,
          connectTimeout: 30000,
          receiveTimeout: 30000,
          responseType: ResponseType.plain,
          contentType: "multipart/form-data; boundary=" + formData.boundary,
          headers: {
            "X-Access-Token": Variable.share().GARDENER_TOKEN,
            "X-Request-Id": Variable.share().X_REQUEST_ID,
            HttpHeaders.contentTypeHeader:
                "multipart/form-data; boundary=" + formData.boundary,
          });
    } catch (exception) {
      print(exception);
    }

    Dio dio = new Dio(baseOptions);
    var cookieJar = CookieJar();
    dio.interceptors.add(CookieManager(cookieJar));
    //简单粗暴方式处理校验证书方法
    (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
        (client) {
      client.badCertificateCallback =
          (X509Certificate cert, String host, int port) {
        return true;
      };
    };

    Response response;
    try {
      if (method == POST) {
        if (formData != null) {
          response = await dio.post(
            url,
            data: formData,
          );
        } else {
          response = await dio.post(url);
        }
      }
      statusCode = response.statusCode;

      //处理错误部分
      if (statusCode < 0) {
        errorMsg = "网络请求错误,状态码:" + statusCode.toString();
        _handError(errorCallBack, errorMsg);
        return;
      }

      if (callBack != null) {
        var result = response.data.toString();
        print("返回数据:" + result);
        var data = json.decode(result);
        BaseRequst baseData = BaseRequst.fromJson(data);
        if (baseData.code == 200 || baseData.code == 0 ) {
          callBack(data);
        } else {
          _handError(errorCallBack, baseData.message);
        }
      }
    } catch (exception) {
      String code = exception.message.toString();
      String errorString = code.contains("timed out") ? "请求超时" : "服务异常";
      _handError(errorCallBack, errorString);
    }
  }

  //处理异常
  static void _handError(Function errorCallback, String errorMsg) {
    if (errorCallback != null) {
      errorCallback(errorMsg);
    }
    print("<net> errorMsg :" + errorMsg);
  }
}

到此图片上传类就完成了。

下面就是使用了,在使用之前我们需要获取相册的图片或者视频。这个时候我们就使用到了权限的申请permission_handler

这里我为了方便使用权限这里对使用进行了封装,类名:PermissionUtils

完整内容

import 'package:permission_handler/permission_handler.dart';

class PermissionUtils {

  /**
   * 所有
   */
  static Future requestAllPermission() async {
    Map<Permission, PermissionStatus> permission = await [
      Permission.camera,
      Permission.photos,
      Permission.speech,
      Permission.storage,
      Permission.location,
      Permission.phone,
      Permission.notification,
      Permission.contacts
    ].request();

    if (await Permission.camera.isGranted) {
      print("相机权限申请通过");
    } else {
      print("相机权限申请失败");
    }

    if (await Permission.photos.isGranted) {
      print("照片权限申请通过");
    } else {
      print("照片权限申请失败");
    }

    if (await Permission.speech.isGranted) {
      print("语音权限申请通过");
    } else {
      print("语音权限申请失败");
    }

    if (await Permission.storage.isGranted) {
      print("文件权限申请通过");
    } else {
      print("文件权限申请失败");
    }

    if (await Permission.location.isGranted) {
      print("定位权限申请通过");
    } else {
      print("定位权限申请失败");
    }

    if (await Permission.phone.isGranted) {
      print("手机权限申请通过");
    } else {
      print("手机权限申请失败");
    }

    if (await Permission.notification.isGranted) {
      print("通知权限申请通过");
    } else {
      print("通知权限申请失败");
    }
    if (await Permission.contacts.isGranted) {
      print("通讯录权限申请通过");
    } else {
      print("通讯录权限申请失败");
    }
  }

  static Future<bool> requestCameraPermission() async {
    Map<Permission, PermissionStatus> permission = await [
      Permission.camera,
    ].request();

    if (await Permission.camera.isGranted) {
      print("相机权限申请通过");
      return true;
    } else {
      print("相机权限申请失败");
      return false;
    }
  }

  static Future requestPhotosPermission() async {
    Map<Permission, PermissionStatus> permission = await [
      Permission.photos,
    ].request();

    if (await Permission.photos.isGranted) {
      print("照片权限申请通过");
    } else {
      print("照片权限申请失败");
    }

  }

  static Future requestSpeechPermission() async {
    Map<Permission, PermissionStatus> permission = await [
      Permission.speech,
    ].request();



    if (await Permission.speech.isGranted) {
      print("语音权限申请通过");
    } else {
      print("语音权限申请失败");
    }

  }

  static Future requestStoragePermission() async {
    Map<Permission, PermissionStatus> permission = await [
      Permission.storage,
    ].request();

    if (await Permission.storage.isGranted) {
      print("文件权限申请通过");
    } else {
      print("文件权限申请失败");
    }
  }

  static Future requestLocationPermission() async {
    Map<Permission, PermissionStatus> permission = await [

      Permission.location,
    ].request();

    if (await Permission.location.isGranted) {
      print("定位权限申请通过");
    } else {
      print("定位权限申请失败");
    }

  }

  static Future requestPhonePermission() async {
    Map<Permission, PermissionStatus> permission = await [

      Permission.phone,
    ].request();

    if (await Permission.phone.isGranted) {
      print("手机权限申请通过");
    } else {
      print("手机权限申请失败");
    }

  }

  static Future requestNotificationPermission() async {
    Map<Permission, PermissionStatus> permission = await [

      Permission.notification,
    ].request();

    if (await Permission.notification.isGranted) {
      print("通知权限申请通过");
    } else {
      print("通知权限申请失败");
    }
  }

  static Future requestContactsPermission() async {
    Map<Permission, PermissionStatus> permission = await [

      Permission.contacts,
    ].request();

    if (await Permission.contacts.isGranted) {
      print("通讯录权限申请通过");
    } else {
      print("通讯录权限申请失败");
    }
  }

}

到此就完成了app手机权限的封装,因为上传图片、视频要获取相册权限或者相机,所以我们要获取这几个权限。下面是使用

    //申请相机、相册等权限
    PermissionUtils.requestCameraPermission();
    PermissionUtils.requestPhotosPermission();
    PermissionUtils.requestStoragePermission();

这样就完成了获取

下面就是上传了,上传的过程中我们也要做一下权限的获取,如果未开启权限,要提示用户去打开权限。

if (!await Permission.camera.isGranted) {
      Fluttertoast.showToast(msg: "相机权限已关闭");
      return;
    }
    if (!await Permission.storage.isGranted) {
      Fluttertoast.showToast(msg: "文件权限已关闭");
      return;
    }
    if (!await Permission.photos.isGranted) {
      Fluttertoast.showToast(msg: "相册权限已关闭");
      return;
    }

如果上述都符合要求,下面就是获取图片了,获取图片我们要使用的插件就是image_picker

下面分别是图片和视频的获取方式

图片

    File image = await ImagePicker.pickImage(
        source: type == 0 ? ImageSource.camera : ImageSource.gallery); // 0 相机 1 相册

视频

    File video = await ImagePicker.pickVideo(
        source: type == 0 ? ImageSource.camera : ImageSource.gallery);// 1 相机 2 视频

其实图片和视频基本一致

这样子就完成了图片和视频的获取

下面就是上传了。下面是上传的所有代码

图片

/*
  * 点击上传头像
  * */
  void _takePhoto(int type) async {
    if (!await Permission.camera.isGranted) {
      Fluttertoast.showToast(msg: "相机权限已关闭");
      return;
    }
    if (!await Permission.storage.isGranted) {
      Fluttertoast.showToast(msg: "文件权限已关闭");
      return;
    }
    if (!await Permission.photos.isGranted) {
      Fluttertoast.showToast(msg: "相册权限已关闭");
      return;
    }

    File image = await ImagePicker.pickImage(
        source: type == 0 ? ImageSource.camera : ImageSource.gallery);
    if (image != null) {
      String path = image.path;
      var fileName = path.substring(path.lastIndexOf("/") + 1, path.length);
      MultipartFile multipartFile =
          MultipartFile.fromFileSync(path, filename: fileName);
      FormData data = new FormData.fromMap({
        "biz": "classReflect",// 和后台定一下上传的位置,不需要就为空
        "file": multipartFile, // 上传的文件
      });
      HttpFileUtils.post(
        Url.JF_API_FILE_UPLOAD,// 上传地址
        (data) {
          // 成功后返回的结果
        },
        formData: data,//上传的文件数据
        errorCallBack: (errorMsg) { // 失败的报错信息
          Fluttertoast.showToast(msg: errorMsg);
        },
      );
    }
  }

视频

void _takePhoto(int type) async {
    if (!await Permission.camera.isGranted) {
      Fluttertoast.showToast(msg: "相机权限已关闭");
      return;
    }
    if (!await Permission.storage.isGranted) {
      Fluttertoast.showToast(msg: "文件权限已关闭");
      return;
    }
    if (!await Permission.photos.isGranted) {
      Fluttertoast.showToast(msg: "相册权限已关闭");
      return;
    }
    File video = await ImagePicker.pickVideo(
        source: type == 0 ? ImageSource.camera : ImageSource.gallery);
    print(video.lengthSync());
    // 服务器要求图片最大为100M,所以这里app侧也要进行限制,不需要删除即可
    if (video.lengthSync() > 104857600) {
      Fluttertoast.showToast(msg: "当前视频文件过大,请编辑视频后再次上传");
      return;
    }

    if (video != null) {
      String path = video.path;
      var fileName = path.substring(path.lastIndexOf("/") + 1, path.length);
      MultipartFile multipartFile =
          MultipartFile.fromFileSync(path, filename: fileName);
      FormData data = new FormData.fromMap({
        "biz": "group/" +
            DateTime.now().year.toString() +
            DateTime.now().month.toString(),//和图片一样,
        "file": multipartFile,
      });
      HttpFileUtils.post(
        Url.JF_API_FILE_UPLOAD,//上传接口
        (data) {
             // 返回结果
        },
        formData: data, // 视频文件
        errorCallBack: (errorMsg) {
          Fluttertoast.showToast(msg: errorMsg);
        },
      );
    }
  }

到此就完成了图片的上传

?

?

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-08-27 11:58:42  更:2021-08-27 12:00:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 13:48:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码