天天看點

flutter阿裡雲OSS圖檔上傳

一、選擇圖檔:

使用插件 image_picker: “^0.5.0+3”

使用image_picker選擇圖檔,代碼如下:

// 相機拍照或者從圖庫選擇圖檔
  pickImage(ctx) {
    // 如果已添加了1張圖檔,則提示不允許添加更多
    num size = fileList.length;
    if (size >= 1) {
      Scaffold.of(ctx).showSnackBar(new SnackBar(
        content: new Text("最多隻能添加1張圖檔!"),
      ));
      return;
    }
    showModalBottomSheet<void>(context: context, builder: _bottomSheetBuilder);
  }
  _renderBottomMenuItem(title, ImageSource source) {
    var item = new Container(
      height: 60.0,
      child: new Center(child: new Text(title)),
    );
    return new InkWell(
      child: item,
      onTap: () async {
        Navigator.of(context).pop();
        setState(() {
          _imageFile = ImagePicker.pickImage(source: source);
        });
      },
    );
  }
  Widget _bottomSheetBuilder(BuildContext context) {
    return new Container(
        height: 182.0,
        child: new Padding(
          padding: const EdgeInsets.fromLTRB(0.0, 30.0, 0.0, 30.0),
          child: new Column(
            children: <Widget>[
              _renderBottomMenuItem("相機拍照", ImageSource.camera),
              new Divider(
                height: 2.0,
              ),
              _renderBottomMenuItem("圖庫選擇照片", ImageSource.gallery)
            ],
          ),
        ));
  }
           

選擇圖檔後回調,代碼如下

List<File> fileList = new List();
Future<File> _imageFile;
 
Widget build(BuildContext context) {
    return new Scaffold(
      body: new FutureBuilder(
        future: _imageFile,
        builder: (BuildContext context, AsyncSnapshot<File> snapshot) {
          if (snapshot.connectionState == ConnectionState.done && snapshot.data != null && _imageFile != null) {
            // 選擇了圖檔(拍照或圖庫選擇),添加到List中
            fileList.add(snapshot.data);
            // 阿裡雲OSS上傳圖檔
            uploadImage(snapshot.data);
            _imageFile = null;
          }
          // 傳回的widget
          return listView();
        },
      ),
    );
  }
           

二、上傳圖檔

使用插件dio: “^2.0.0”

使用dio網絡通路架構進行上傳,代碼如下

//上傳圖檔
  uploadImage(File file) {
    //簽名
    String url = Constants.BASE_URL + "/ossSignature";
    print("ossSignatureUrl: $url");
    NetUtils.get(url).then((obj) async {
      if (obj != null) {
        if (obj['code'] == 0) {
          var _sign = obj['data'];
          //建立dio對象
          Dio dio = new Dio();
          //dio的請求配置
          dio.options.responseType = ResponseType.plain;
          dio.options.contentType = ContentType.parse("multipart/form-data");
          //檔案名
          String path = file.path;
          String chuo = DateTime.now().millisecondsSinceEpoch.toString() + path.substring(path.lastIndexOf('.'));
          String fileName = path.lastIndexOf('/') > -1 ? path.substring(path.lastIndexOf('/') + 1) : path;
          //建立一個FormData,作為dio的參數
          FormData formData = new FormData.from({
            'chunk': '0',
            'OSSAccessKeyId': _sign['accessid'].toString(),
            'policy': _sign['policy'].toString(),
            'Signature': _sign['signature'].toString(),
            'Expires': _sign['expire'].toString(),
            'key': _sign['dir'] + chuo,
            'success_action_status': '200',
            'Access-Control-Allow-Origin': '*',
            'file': new UploadFileInfo(new File(path), fileName)
          });
          try {
            Response response = await dio.post(_sign['host'], data: formData);
            if (response.statusCode == 200) {
              setState(() {
                imgUrl = _sign['host'] + '/' + _sign['dir'] + chuo;
              });
            } else {
              Toast.show(context, '圖檔上傳失敗');
            }
          } on DioError catch (e) {
            Toast.show(context, '上傳失敗');
            print("get uploadImage error: $e");
          }
        }
      }
    }).catchError((e) {
      print("get uploadImage error: $e");
    });
  }