矩信
矩信
  • 发布:2021-12-27 14:28
  • 更新:2021-12-28 14:48
  • 阅读:548

【报Bug】系统公共目的下的文件不支持移动和拷贝到沙盒目录?

分类:HTML5+

产品分类: HTML5+

HBuilderX版本号: 3.3.3

手机系统: Android

手机系统版本号: Android 11

手机厂商: 华为

手机机型: p30

打包方式: 云端

示例代码:
		moveCopyFileToDst: function(files, method, succCallback, errCallback) {  
			var _this = this,  
				result = [];  
  
			function copyfile(fileEntry, dstEntry, fileName, callback) {  
				fileEntry.copyTo(dstEntry, fileName, function(entry) {  
					callback(entry)  
				}, function(e) {  
					console.log(e.message + ' 有些文件路径不存在或无法复制')  
					errCallback(e.message)  
				})  
			}  
  
			function movefile(fileEntry, dstEntry, fileName, callback) {  
				console.log('movefile moveTo fileEntry.fullPath', fileEntry.fullPath)  
				console.log('movefile moveTo dstEntry.name', dstEntry.name)  
				console.log('movefile moveTo dstEntry.fullPath', dstEntry.fullPath)  
				console.log('movefile moveTo fileName', fileName)  
				fileEntry.moveTo(dstEntry, fileName, function(entry) {  
					callback(entry)  
				}, function(e) {  
					console.log(e.message)  
					errCallback(e.message)  
				})  
			}  
  
			/**  
			 * 递归生成文件名  
			 * @param {Object} fileName  
			 * @param {Object} index  
			 * @param {Object} callback  
			 */  
			function recursionCreateFileName(fileName, dstPath, index, callback) {  
				//目标文件存在,这行会与if (_this.fileExists(dstPath + newFileName)) {重复判断  
				// if (_this.fileExists(dstPath + fileName)) {  
				//生成一个新文件名: abc.txt abc(0).txt abc(1).txt  
				var split = fileName.split('.'),  
					newFileName = split[0] + '(' + index + ').' + split[1];  
				//再判断新生成的文件名是否存在,如果存在重新调用自己  
				if (_this.fileExists(dstPath + newFileName)) {  
					recursionCreateFileName(fileName, dstPath, index + 1, callback)  
				} else {  
					//不存在,返回新文件名  
					callback(newFileName)  
				}  
				// } else {  
				// 	callback(fileName)  
				// }  
			}  
  
			function recursion(files, index) {  
				if (index == files.length) {  
					return succCallback(result)  
				}  
				var originalFile = files[index],  
					fileSplit = originalFile.split('/'),  
					fileName = fileSplit[fileSplit.length - 1],  
					dstEntry = _this.getFileDirEntry(fileName);  
  
				console.log('原文件路径: ' + originalFile)  
				console.log('原文件名: ' + fileName)  
				console.log('目标文件目录: ' + dstEntry.fullPath + fileName)  
				console.log('目标文件路径: ' + dstEntry.name)  
  
				plus.io.resolveLocalFileSystemURL(dstEntry.fullPath + fileName, function(dstFileEntry) {  
					console.log('目标文件存在!' + dstFileEntry.fullPath)  
					plus.io.resolveLocalFileSystemURL(originalFile, function(fileEntry) {  
						if (method === 'move') {  
							recursionCreateFileName(fileName, dstEntry.fullPath, 0, function(filename) {  
								movefile(fileEntry, dstEntry, filename, function(ent) {  
									result.push(ent.fullPath);  
									recursion(index + 1)  
								})  
							})  
						}  
						if (method === 'copy') {  
							console.log('dstEntry copy path: ' + dstEntry.fullPath)  
							recursionCreateFileName(fileName, dstEntry.fullPath, 0, function(filename) {  
								copyfile(fileEntry, dstEntry, filename, function(ent) {  
									result.push(ent.fullPath);  
									recursion(index + 1)  
								})  
							})  
						}  
					})  
				}, function(e) {  
					console.log('目标文件不存在!')  
					plus.io.resolveLocalFileSystemURL(originalFile, function(fileEntry) {  
						if (method === 'move') {  
							console.log('dstEntry move path: ' + dstEntry.fullPath + fileName)  
							movefile(fileEntry, dstEntry, fileName, function(ent) {  
								result.push(ent.fullPath);  
								recursion(index + 1)  
							})  
						}  
						if (method === 'copy') {  
							console.log('dstEntry copy path: ' + dstEntry.fullPath + fileName)  
							copyfile(fileEntry, dstEntry, fileName, function(ent) {  
								result.push(ent.fullPath);  
								recursion(index + 1)  
							})  
						}  
					})  
				})  
			}  
			recursion(files, 0)  
  
		}  
  
			plus.gallery.pick(function(res) {  
					console.log('actionSheet pick files: ' + JSON.stringify(res))  
					_this.moveCopyFileToDst(res.files, 'move', function(res) {  
  
					}, function(err) {  
  
					})  
                        },  
				function(e) {  
					console.log(JSON.stringify(e));  
					plus.nativeUI.closeWaiting()  
				}, config)

操作步骤:

manifest.json targetSdkVersion 值为 30
1、pick 选择图片。
2、勾选最下面的“原图”。
3、选图片。
4、判断 _doc/images 下是否有该文件。如果不存在就移动到 _doc/images 下,存在就重新启个名字再移动到 _doc/images 下。

预期结果:

移动或复制成功

实际结果:

targetSdkVersion设置>=29后在Android10+系统设备不支持当前路径。请更改为应用运行路径!具体请看:https://ask.dcloud.net.cn/article/36199

bug描述:

系统公共目的下的文件 file:///storage/emulated/0/Download/1639293586409.jpg 不支持移动和拷贝到沙盒目录 /storage/emulated/0/Android/data/xx.xx.com/apps/H5AE01F30/doc/images/ 中?

2021-12-27 14:28 负责人:DCloud_Android_ST 分享
已邀请:
DCloud_Android_ST

DCloud_Android_ST

公共目的下的文件不支持移动到应用沙盒目录。正如错误信息提示

  • 矩信 (作者)

    您好,请问我怎么操作才行?压缩吗?


    2021-12-28 11:29

  • 矩信 (作者)

    复制可以吗?


    2021-12-28 11:44

  • DCloud_Android_ST

    回复 矩信: plus.io不支持 你可以尝试使用uni原生插件来实现。直接使用原生代码实现


    2021-12-28 11:56

  • 矩信 (作者)

    回复 DCloud_Android_ST: 我是 html plu5+ 开发的,也能用 uni 原生插件吗?请问怎么用?


    2021-12-28 14:16

  • 矩信 (作者)

    刚才试了一下,move 不可以,copy 可以


    2021-12-28 14:37

矩信

矩信 (作者)

换策略了,如果从相册返回的文件路径包含 uniapp_temp/compressed 说明不是原图是压缩后的,这个 moveTo() 支持,反之说明是原图,就用 copyTo(),uniapp_temp/compressed 用 moveTo 就对了,要不然会产生大量垃圾,除非自己专门写代码维护。

该问题目前已经被锁定, 无法添加新回复