Flutter下载文件并使用原生打开
下载文件
想要在Flutter下载文件,可以使用Dio网络请求库,Dio中有download函数, 定义如下:
Future<Response> download(
String urlPath,
savePath, {
ProgressCallback? onReceiveProgress,
Map<String, dynamic>? queryParameters,
CancelToken? cancelToken,
bool deleteOnError = true,
String lengthHeader = Headers.contentLengthHeader,
data,
Options? options,
});
-
urlPath
:网络资源的url
; -
savePath
:dynamic
类型,可以是下载后存储文件路径的字符串,也可以是一个返回字符串的回调方法(Dio 会把headers
参数携带过去,方便针对下载返回内容构建文件路径); -
onReceiveProgress
:文件接收进度,是一个void Function(int count, int total)
回调函数,调用者可以通过该回调方法监测下载进度。 -
deleteOnError
:发生错误时候是否删除已下载的文件,默认是 true。 -
lengthHeader
:源文件的实际大小(未压缩前)。默认是header
的content-length
。如果文件压缩了,而没有指定该值的话,那进度回调里的total
会是-1
;如果使用自定义的header
指定了文件的大小,那么total
会是自定义的header
对应的文件大小。 -
其他参数和普通的请求差不多,这里不再赘述。
使用此函数即可进行下载文件
获取保存文件路径
可以使用path_provider库获取保存文件的路径,path_provider
提供了如下方法:
getTemporaryDirectory
:应用临时目录(可能被清除)getApplicationDocumentsDirectory
:应用文档目录(不会被系统清除,主要用户数据存储目录),对于安卓推荐使用外部存储getExternalStorageDirectory。getApplicationSupportDirectory
:应用支持目录,一般放置与用户无关的数据。getLibraryDirectory
:指向应用可以持久存储数据的目录,不支持安卓平台。getExternalStorageDirectory
:获取外部存储目录,不支持 iOS 平台。getExternalCacheDirectories
:获取外部缓存目录,,不支持 iOS 平台。getExternalStorageDirectories
:获取外部可以的目录列表,不支持 iOS 平台。getDownloadsDirectory
:获取下载目录,用于 Web 端,不支持安卓和 iOS平台。
通过 path_provider
拿到Directory
对象后,就可以通过 Directory
的 path
属性获取到完整的目录路径。本例我们是在 initialState 里获取文件存储路径的,使用的是应用文档目录。
void initState() {
getApplicationDocumentsDirectory()
.then((tempDir) => {_destPath = tempDir.path + '/zakiFlutter.docx'});
super.initState();
}
下载文件时安卓需要获取写入的权限
我使用的是permission_handler
权限管理库,代码如下
/// 申请写文件权限
final status = await Permission.storage.request();
switch (status) {
case PermissionStatus.granted:
break;
case PermissionStatus.denied:
HUDTools.showMessage('拒绝访问存储权限');
break;
case PermissionStatus.permanentlyDenied:
showXmDialog(
title: '提示',
content: '存储投稿模版需要打开存储权限,是否进入设置界面开启?',
cancelText: '取消',
confirmText: '去开启',
onConfirmTap: () => AppSettings.openAppSettings(),
);
break;
default:
break;
}
需要注意的是,要在.android -> app -> src -> main -> AndroidManifest.xml
中增加读写权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
下载本地后在iOS预览或者使用其他应用打开
Flutter有第三方库 open_filex
可以进行上述操作,但是安卓同事在运行过程中异常,所以暂时先用flutter传递消息后,在原生进行处理的方式进行。
在iOSApp中预览文件时需要使用到UIDocumentInteractionController
这个控制器,官方释义如下
A view controller that previews, opens, or prints files whose file format cannot be handled directly by your app.
一个view controller可以用来预览,打开或者打印,不能被你的app直接处理的文件
将需要打开文件的信息发送至原生后的处理,代码如下
let ctr = UIDocumentInteractionController()
func openFile() {
let url = Bundle.main.path(forResource: "zakiFlutter", ofType: "docx")
ctr.url = URL(fileURLWithPath: enterURL)
ctr.delegate = self
///预览方法
ctr.presentPreview(animated: true)
///分享方法
ctr.presentOptionsMenu(from: self.view.bounds, in: self.view, animated: true)
}
extension zakiFlutterViewController: UIDocumentInteractionControllerDelegate {
func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
return self
}
}
注意:使用分享方法分享文件时,需要将controller放到class里持有,否则分享时会为空或者报错
总结
需要在iOS原生文件app中展示时,在Info.plist
中 新增 Supports Document Browser
为 YES。
需要在iTunes中分享时展示,在Info.plist
新增 Application supports iTunes file
sharing 为YES
转载自:https://juejin.cn/post/7184732401158291511