uniapp 22 下载图片到本地相册

一、保存图片到系统相册接口

uni.saveImageToPhotosAlbum(OBJECT)


平台差异说明

H5不支持,所以单独处理

App H5 微信小程序 支付宝小程序 百度小程序 抖音小程序、飞书小程序 QQ小程序 快手小程序 京东小程序 元服务 小红书小程序
√ x √ √ √ √ √ √ √ √ √

OBJECT 参数说明

注意:url不支持网络图片,所以类似于https://xxxx.com/img/img1.png 这样的网络图片无法访问下载。所以可以通过uni.getImageInfo获取一个临时文件路径,并把这个临时文件路径传递给uni.saveImageToPhotosAlbum的参数

参数名 类型 必填 说明
filePath String 是 图片文件路径,可以是临时文件路径也可以是永久文件路径,不支持网络图片路径

ImageUtil.js

/**
 * 下载网络图片
 * @param {Object} url 图片网络url:( https://xxx.com/a.jpg )
 */
export function downloadWebImg(url) {
	if (!url) {
		return
	}
	// #ifdef H5
		uni.showModal({
			content: "请长按图片保存",
			showCancel: false
		})
		
	// #endif
	
	// #ifndef H5
	try {
	uni.showLoading({
		title: "下载中...",
		mask: true,
		fail: () => {uni.hideLoading()}
	})
	
	//调用后端接口保存此次下载图片的记录
	/*
	let { classid, _id: wallId } = currentInfo.value
	let res = await apiWriteDownload({
		classid, wallId
	})
	
	if (errCode != 0) throw res
	*/
	
	uni.getImageInfo({
		src: url,
		success: function (res) {
			if (res.errMsg == "getImageInfo:ok") {
				const imgPath = res.path
				uni.saveImageToPhotosAlbum({
					filePath: imgPath,
					success: function (res) {
						console.log("保存成功", res)
						uni.showToast({
							title: "保存成功",
							icon: 'none'
						})
					}, fail(err) {
						//没有授权的话,会进导到这里;未保存成功(比如点击取消,也会进到这里, 所以这里就不方便在再弹窗提示了)
						console.error('图片下载失败', err);
						
						//微信小程序开发工具保存图片时图片后缀.jpg时或取消时报错,.png时正常报错
						if (err.errMsg === "saveImageToPhotosAlbum:fail cancel"
						//下载图片时点击了图片弹窗的【取消】按钮
						|| err.errMsg === "saveImageToPhotosAlbum:fail:The user selected Disable saving"
						) {
							uni.showToast({
								title: "保存失败,请重新点击下载",
								icon: 'none'
							})
							return
						}
						
						//用户未同意平台隐私协议,
						//{errMsg: "saveImageToPhotosAlbum:fail privacy permission is not authorized", errno: 104}
						//{errno: 103, errMsg: "saveImageToPhotosAlbum:fail:auth deny", }
						//{"errno": 103, "errMsg": "saveImageToPhotosAlbum:fail:jsapi user authorize denied"}
						//其他授权错误......,都走下面的授权弹窗
						
						uni.showModal({
							title: "授权提示",
							content: "需要授权保存相册",
							success: (res) => {
								console.log('弹窗提示窗success', res);
								if (res.confirm) {
									console.log("确认授权了")
									uni.openSetting({
										success: (setting) => {
											console.log("openSetting", setting)
											if (setting.authSetting["scope.writePhotosAlbum"]) {
												uni.showToast({
													title: "获取授权成功",
													icon: 'none'
												})
											} else {
												uni.showToast({
													title: "获取授权失败",
													icon: 'none'
												})
											}
											
										}
									})
								}
							},
							fail: (err) => {
								console.error('弹窗提示窗fail', err);
							},
							complete: (res) => {
								console.log('弹窗提示窗complete', res);
							}
						})
					}, complete(res) {
						
					}
				});
			}
		}, fail(err) {
			uni.hideLoading()
		}, complete(res) {
			
		}
	})
	
	// } catch (err) {
		//此处是为了应对await 调用后端代码时报错,或者返回信息为失败(eg: 5秒内禁止重复下载),然后调用代码直接跑出了异常,然后此处catch后做的处理
		//也可以不走throw + catch处理 ,而是直接在finally中处理
		// uni.hideLoading()
	// }
	} finally {
		uni.hideLoading()
	}
	//#endif
}

授权弹窗不再弹怎么办?

  1. 授权弹窗当点击确定授权后,以后都可以下载图片。但是当弹窗中若选择“拒绝”,那么以后再点击调用下载接口时,则不会再继续弹窗。
  2. 在小程序开发工具里,可以通过【清除模拟器缓存】 --> 【清除授权数据】的方式,来清除掉之前无论是同意还是拒绝的授权操作,然后强制下次还会调用此弹窗。
  3. 手机里没有清除授权缓存,可以在代码里的fail中做个补救。

image

posted @ 2026-10-21 21:35  超轶绝尘  阅读(10)  评论(0)    收藏  举报