1.注册storage读写权限
在AndroidManifest.xml注册文件中注册权限如下:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

2.使用的插件
cached_network_image: ^2.0.0
image_gallery_saver: ^1.2.2
permission_handler: '^4.2.0+hotfix.2'
- cached_network_image是我用于缓存网络图片的插件(也可以不使用这个插件,则下面获取图片文件时需要修改);
- image_gallery_saver用于保存图片或文件;
- permission_handler用于向系统申请权限(之前注册过的权限)。
3.请求权限
import 'package:permission_handler/permission_handler.dart';
// ...
// 检查并请求权限
PermissionStatus status = await PermissionHandler().checkPermissionStatus(PermissionGroup.storage);
if (PermissionStatus.granted != status) {
PermissionHandler().requestPermissions(<PermissionGroup>[
PermissionGroup.storage,
]);
}
可以使用如上代码检查并请求权限,这段代码可以放在widget的initState方法中,也可以放在点击保存按钮的onPress方法中。放在不同的位置,向系统申请权限弹框出现的实际不同,前者在打开图片页面就申请,后者是在保存图片时申请。

4.获取文件并保存
import 'dart:io';
import 'dart:typed_data';
import 'dart:convert' as convert;
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter_app/widget/Utils.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
// ...
final Image img;
// ...
IconButton(
icon: Icon(Icons.file_download),
onPressed: () {
saveImage(img.image);
},
),
// ...
saveImage(CachedNetworkImageProvider provider) async {
// 检查并请求权限
PermissionStatus status = await PermissionHandler().checkPermissionStatus(PermissionGroup.storage);
if (PermissionStatus.granted != status) {
PermissionHandler().requestPermissions(<PermissionGroup>[
PermissionGroup.storage,
]);
}
// 获取文件或图片
DefaultCacheManager mngr = provider.cacheManager ?? DefaultCacheManager();
String url = provider.url;
Map<String, String> headers = provider.headers;
File file = await mngr.getSingleFile(url, headers: headers);
// 获取图片,无法保存git等格式
// Uint8List uint8list = await file.readAsBytes();
// final result = await ImageGallerySaver.saveImage(uint8list);
// 直接使用file,可以报仇呢git格式
final result = await ImageGallerySaver.saveFile(file.path);
if(result != null && result != "") {
String str = Uri.decodeComponent(result);
Utils.showToast("成功保存到$str");
} else {
Utils.showToast("保存失败");
}
}
