需求场景描述:接口获取到服务器的文件地址,然后在小程序中下载文件到本地手机上。根据文件格式,下载类型分为下面四种情况:
1、下载图片到本地
onSavePic() {
// #ifdef MP-WEIXIN
uni.getImageInfo({
src: _this.imageUrl, // 图片下载网络地址
success: function(e) {
// e.type=png/jpg 扩展名
// filePathNew: 指定文件下载后存储的路径 (本地路径)
var filePathNew = wx.env.USER_DATA_PATH + "/" + new Date().valueOf() +'.'+e.type;
uni.downloadFile({
url: _this.imageUrl,
filePath: filePathNew,
success: (res) => {
if (res.statusCode === 200) {
uni.saveImageToPhotosAlbum({
filePath: filePathNew,
success: function() {
uni.showToast({title: '保存到相册成功'});
},
fail: function(err){}
});
}
}
});
},
complete: function(e) {}
});
// #endif
},
2、下载视频到本地
实现方法同下载图片,只不过保存视频需要使用saveVideoToPhotosAlbum()方法。
onSaveVideo() {
// #ifdef MP-WEIXIN
uni.downloadFile({
url: this.videoUrl,
success: (data) => {
if (data.statusCode === 200) {
uni.saveFile({
tempFilePath: data.tempFilePath, //临时路径
success: function(res) {
uni.saveVideoToPhotosAlbum({
filePath: res.savedFilePath,
success:function(){
uni.hideLoading()
uni.showToast({title:"保存到相册成功"})
}
})
}
});
}
},
fail: (err) => {
uni.showToast({title: '失败请重新下载'});
},
});
// #endif
},
3、打开文档,支持格式:doc, xls, ppt, pdf, docx, xlsx, pptx
onOpenDocment() {
uni.downloadFile({
url: this.fileUrl,// 网络文档地址
success: (data) => {
if (data.statusCode === 200) {
uni.saveFile({
tempFilePath: data.tempFilePath, //临时路径
success: function(res) {
// 保存路径
uni.showToast({ title: "文件已保存:"+res.savedFilePath,duration:3000 })
setTimeout(()=>{
//打开文档查看
uni.openDocument({
filePath:res.savedFilePath,
success:function(res){
console.log('打开文档成功')
}
})
}, 3000);
}
});
}
},
fail: (err) => {
uni.showToast({
title: '失败请重新下载'
});
},
});
},
4、下载音频。
因微信平台限制,除了视频、图片支持下载文件到本地,以及部分文档格式支持直接打开,其他格式的文件不支持下载文件到本地。
微信小程序官网中,提到可以使用FileSystemManager文件管理器下载音频等其他格式文件。
使用FileSystemManager文件管理器下载文件,
文件主要分为两大类:
- 代码包文件:代码包文件指的是在项目目录中添加的文件。
- 本地文件:通过调用接口本地产生,或通过网络下载下来,存储到本地的文件。
其中本地文件又分为三种:
- 本地临时文件:临时产生,随时会被回收的文件。运行时最多存储 4GB,结束运行后,如果已使用超过 2GB,会以文件为维度按照最近使用时间从远到近进行清理至少于2GB。
- 本地缓存文件:小程序通过接口把本地临时文件缓存后产生的文件,不能自定义目录和文件名。跟本地用户文件共计,小程序(含小游戏)最多可存储 200MB。
- 本地用户文件:小程序通过接口把本地临时文件缓存后产生的文件,允许自定义目录和文件名。跟本地缓存文件共计,小程序(含小游戏)最多可存储 200MB。
本地用户文件:提供了一个用户文件目录给开发者,开发者对这个目录有完全自由的读写权限。通过 wx.env.USER_DATA_PATH
可以获取到这个目录的路径。解析到手机上的路径为,wxfile://usr/,真实路径:手机/内部存储/tencent/MicroMsg/wxanewfiles/xxxx/abc.mp3。
xxxx:是一个很长的由英文数字组成的文件夹,这个文件夹的明明规则,尚不清楚。所以保存后的文件具体在什么路径,并不知道。而且苹果手机,无法获取到微信内部的文件路径。因此这种方式pass。
要想实现下载音频的功能,就只能找替代方案。
方案1:下载文件保存为图片格式,保存成功后,更改扩展名。实现步骤如下:
①使用wx.downloadFile下载mp3文件后,使用FileSystemManager.save保存mp3文件为图片格式。
②保存成功后,再使用wx.saveImageToPhotosAlbum保存到相册,最后路径为:手机/内部存储/tencent/MicroMsg/WeiXin/mmexport1xxxxxx.jpg。1xxxxxx为时间戳,只能根据文件生成时间判断是哪个文件了。
这种方式比较繁琐,对于用户不适用。pass
方案2:复制音频网络地址,打开系统浏览器,在浏览器中下载音频。亲测有效。
苹果手机:
①、使用safari浏览器下载时,点击下方tab中的分享按钮,选择:‘存储到“文件”’选项,即可保存到手机的“文件”管理中。不支持重命名。
②、使用QQ浏览器,只可以在浏览器中播放音频,无法下载音频。
安卓手机:
①、浏览器中打开链接,可直接进行下载,并支持重命名。
复制网络地址到剪切板方法如下:
// 下载音频到本地
onSaveAudio() {
uniCopy({
content:this.audioUrl,// 音频下载链接
success:(res)=>{
uni.showToast({title: res})
},
error:(e)=>{
uni.showToast({title: e,})
}
})
},
uniCopy({content,success,error}) {
if(!content) return error('复制的内容不能为空 !')
content = typeof content === 'string' ? content : content.toString() // 复制内容,必须字符串,数字需要转换为字符串
/**
* 小程序端 和 app端的复制逻辑
*/
//#ifndef H5
uni.setClipboardData({
data: content,
success: function() {success("复制成功~")},
fail:function(){success("复制失败~")}
});
//#endif
/**
* H5端的复制逻辑
*/
// #ifdef H5
if (!document.queryCommandSupported('copy')) { //为了兼容有些浏览器 queryCommandSupported 的判断
// 不支持
error('浏览器不支持')
}
let textarea = document.createElement("textarea")
textarea.value = content
textarea.readOnly = "readOnly"
document.body.appendChild(textarea)
textarea.select() // 选择对象
textarea.setSelectionRange(0, content.length) //核心
let result = document.execCommand("copy") // 执行浏览器复制命令
if(result){
success("复制成功~")
}else{
error("复制失败,请检查h5中调用该方法的方式,是不是用户点击的方式调用的,如果不是请改为用户点击的方式触发该方法,因为h5中安全性,不能js直接调用!")
}
textarea.remove()
// #endif
},
5、下载其他格式文件。与下载音频类似,具体有时间再补充。
注意:
下载资源的地址,下载之前必须设置微信公众平台开发设置中的服务器域名的downloadFile合法域名。资源地址必须来自合法域名才可以请求。
PS:图片、视频保存到相册需要获取权限方可保存,获取权限流程
PS:保存图片到相册出现*.unknown错误及saveImageToPhotosAlbum:fail invalid file type错误