最近写小程序,要求实现下载功能,和之前web的下载还是有些不同的。主要区别来自于图标的下载,非图片文件下载的时候,可以直接预览后,再决定是否转发到好友或者在其他app中打开,而图片下载的时候,无法直接在微信中预览,只能直接下载到系统相册。
- 具体代码:
js
async downloadHandler(file) {
// file: url 文件超链接地址, name 文件名, type 文件类型
if (!file.url) return;
uni.showLoading({
title: "请稍候",
mask: true
});
const { url:downloadPath, type, name:fileName } = file;
const that = this
const fileSavePath = `${wx.env.USER_DATA_PATH}/${fileName}`; // 组建文件存放的系统缓存临时地址
console.log('fileSavePath', fileSavePath);
console.log("file type", type);
uni.request({
url: downloadPath,
method: 'GET',
responseType: "arraybuffer",
timeout: 30000
}).then((res) => {
console.log('download', res); // 根据文件超链接地址,获取文件二进制数据
const fs = uni.getFileSystemManager(); // 获取系统文件管理对象 fs
fs.writeFile({
filePath: fileSavePath,
data: res[1]?.data,
encoding: 'binary',
success() { // 把文件二进制数据写入到系统缓存临时地址
if (type === 'image') {
// 如果是图片格式,无法直接在微信预览,只能把图片下载到系统相册中。
that.savaImage(fileSavePath);
} else {
// 如果是非图片格式,则可以在微信中直接预览文件,并后续转发和下载。
uni.openDocument({
filePath: fileSavePath,
showMenu: true
});
uni.hideLoading();
}
},
fail: (err) => {
console.log('writeFile err', err);
uni.showToast({
title: "保存文件出错",
icon: "none",
duration: 2000
});
uni.hideLoading();
}
})
}).catch((err) => {
console.log('download err', err);
uni.showToast({
title: "下载文件出错",
icon: "none",
duration: 2000
});
uni.hideLoading();
})
},
savaImage(imgaPath) {
//获取用户是否有相册权限
const that = this
uni.getSetting({
success: (res) => {
if (!res.authSetting["scope.writePhotosAlbum"]) {
// 无相册权限时 发起相册权限请求
uni.authorize({
scope: "scope.writePhotosAlbum",
success: () => {
// 授权成功保存图片到系统相册
that.savaSysImagePath(imgaPath)
},
fail: () => {
// 授权失败
uni.hideLoading();
uni.showModal({
title: '您已拒绝获取相册权限',
content: '是否进入权限管理,调整授权?',
success: (res) => {
if (res.confirm) {
uni.openSetting({
success: (res) => {
console.log(res.authSetting);
}
})
} else if (res.cancel) {
uni.showToast({
title: "已取消获取相册权限",
icon: "none",
duration: 2000
});
}
}
})
}
})
} else {
// 有相册权限直接保存
that.savaSysImagePath(imgaPath)
}
},
fail: (err) => {
console.log('fail', err);
uni.showToast({
title: "获取相册权限出错",
icon: "none",
duration: 2000
});
uni.hideLoading();
}
})
},
savaSysImagePath(imgaPath) {
uni.saveImageToPhotosAlbum({
filePath: imgaPath, // 保存图片到系统相册,只能接受图片的系统缓存临时保存地址,而不是图片的超链接地址。
success: () => {
uni.hideLoading();
uni.showToast({
title: "已保存图片到相册中!",
icon: "none",
duration: 2000
});
},
fail: (err) => {
console.log('fail', err);
uni.hideLoading();
uni.showToast({
title: err.errMsg,
icon: "none",
duration: 2000
})
},
complete: () => {
uni.hideLoading();
}
})
}
以上就是下载图片和其他文件的方法。但是实际使用中发现,如果下载图片到系统相册,再转发朋友的时候,还得从相册中寻找图片,非常不方便,而且其实图片更多是为了
转发给好友,其次才是保存到系统相册
,并不需要总是下载到相册,这样还特别占用相册内存,非常不友好,如果图片也能像其他文件一样可以预览,然后再决定转发好友还是下载到相册
就好了,于是发现uni 还提供了,一个图片预览的功能,uni.previewImage
。
- 代码改造为:
js
onImgPreview(url) {
console.log('onImgPreview start', url)
uni.previewImage({
urls: [url], // 可以直接接受图片的超链接地址。
longPressActions: {
itemList: ['发送给朋友', '保存图片', '收藏'],
success: (data) => {
console.log('success', data);
},
fail: (err) => {
console.log('fail', err);
}
}
})
},
async downloadHandler(file) {
// file: url 文件超链接地址, name 文件名, type 文件类型
if (!file.url) return;
uni.showLoading({
title: "请稍候",
mask: true
});
const { url:downloadPath, type, name:fileName } = file;
const fileSavePath = `${wx.env.USER_DATA_PATH}/${fileName}`; // 组建文件存放的系统缓存临时地址
console.log('fileSavePath', fileSavePath);
console.log("file type", type);
if (type === 'image') {
// 如果是图片可以直接预览,然后长按下载/转发/收藏,无需再设置一个下载按钮,把图片下载到系统相册。
this.onImgPreview(downloadPath); // 无需把超链接转化为二进制数据,而是可以直接使用超链接地址,进行预览。
return;
}
uni.request({
url: downloadPath,
method: 'GET',
responseType: "arraybuffer",
timeout: 30000
}).then((res) => {
console.log('download', res); // 根据文件超链接地址,获取文件二进制数据
const fs = uni.getFileSystemManager(); // 获取系统文件管理对象 fs
fs.writeFile({
filePath: fileSavePath,
data: res[1]?.data,
encoding: 'binary',
success() { // 把文件二进制数据写入到系统缓存临时地址
// 如果是非图片格式,则可以在微信中直接预览文件,并后续转发和下载。
uni.openDocument({
filePath: fileSavePath,
showMenu: true
});
uni.hideLoading();
},
fail: (err) => {
console.log('writeFile err', err);
uni.showToast({
title: "保存文件出错",
icon: "none",
duration: 2000
});
uni.hideLoading();
}
})
}).catch((err) => {
console.log('download err', err);
uni.showToast({
title: "下载文件出错",
icon: "none",
duration: 2000
});
uni.hideLoading();
})
}
并且
uni.previewImage
,这个预览功能,可以直接接受超链接地址,都无需缓存到本地系统临时文件中,这样既可以直接转发好友,也可以保存到相册,无需先下载到系统相册,然后再进入相册转发给好友,效果非常好。