我在安卓系统中保存文件时遇到了很多麻烦。该项目是用Ionic与这些插件开发的混合应用。
com.phonegap.plugins.fileopener 1.0.0 "File Opener"
com.telerik.plugins.nativepagetransitions 0.4.2 "Native Page Transitions"
cordova-plugin-compat 1.0.0 "Compat"
cordova-plugin-crosswalk-webview 2.0.0 "Crosswalk WebView Engine"
cordova-plugin-file 4.2.0 "File"
cordova-plugin-network-information 1.2.2-dev "Network Information"
cordova-plugin-whitelist 1.2.3-dev "Whitelist"
cordova-plugin-wkwebview-engine 1.0.4-dev "Cordova WKWebView Engine"
ionic-plugin-keyboard 2.2.1 "Keyboard"
安卓平台版本是 5.2.1
我使用的设备是一个 Samsung A7
这是一个摘要,来自 AndroidManifest.xml
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
如果我尝试用这个代码段(实际上是在另一个项目上)。
var storagePath = "/storage/emulated/0";
var fileDir = cordova.file.externalDataDirectory.replace(cordova.file.externalRootDirectory, '');
var fileName = $scope.ngDocument.documentId + ".pdf"
var filePath = storagePath + "/" + fileDir + fileName;
$cordovaFile.writeFile(filePath, BINARY_ARR, {'append': false}).then(function(result) {}, function(err) {});
我得到 {"code":5,"message":"ENCODING_ERR"}
作为回调从 $cordovaFile.writeFile
无论我使用绝对路径、相对路径,只用文件名,都不会创建任何文件。
有了这个片段
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {
console.log('file system open: ' + fs.name);
fs.root.getFile(fileName, { create: true, exclusive: false }, function (fileEntry) {
console.log("fileEntry:" + JSON.stringify(fileEntry));
writeFile(fileEntry, BINARY_ARR);
}, function(data){});
}, function(data){});
两码事
如果没有在 config.xml
应用程序创建一个空文件夹到存储emulated0Androidmedia{myAPP}。
有了这两种偏好
<preference name="AndroidPersistentFileLocation" value="Compatibility" />
<preference name="AndroidExtraFilesystems" value="cache" />
载入 /storage/emulated/0
(外部SSD)被创建并在 logcat
错误是。
E/Vold ( 2280): Failed to find mounted volume for /storage/extSdCard/Android/data/{myApp}/files/
W/Vold ( 2280): Returning OperationFailed - no handler for errno 0
W/ContextImpl(13364): Failed to ensure directory: /storage/extSdCard/Android/data/{myApp}/files
E/Vold ( 2280): Failed to find mounted volume for /storage/extSdCard/Android/data/{myApp}/files/
W/Vold ( 2280): Returning OperationFailed - no handler for errno 0
W/ContextImpl(13364): Failed to ensure directory: /storage/extSdCard/Android/data/{myApp}/files
E/Vold ( 2280): Failed to find mounted volume for /storage/extSdCard/Android/data/{myApp}/cache/
W/Vold ( 2280): Returning OperationFailed - no handler for errno 0
W/ContextImpl(13364): Failed to ensure directory: /storage/extSdCard/Android/data/{myApp}/cache
奇怪的是 /storage/extSdCard
(象征性的联系) /mnt/extSdCard
)没有安装,而外置固态硬盘安装在 /mnt/sdcard
请帮帮我吧 我头晕目眩 第一个片段在另一个项目中工作得如鱼得水。难道是ngCordova的版本问题?
经过几次尝试,我用这种方式解决了问题。
在 config.xml
:
<preference name="AndroidPersistentFileLocation" value="Compatibility" />
<preference name="AndroidExtraFilesystems" value="files,cache, sdcard, cache-external, files-external" />
和主要职能。
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {
//var absPath = "file:///storage/emulated/0/";
var absPath = cordova.file.externalRootDirectory;
var fileDir = cordova.file.externalDataDirectory.replace(cordova.file.externalRootDirectory, '');
var fileName = "somename.txt";
var filePath = fileDir + fileName;
fs.root.getFile(filePath, { create: true, exclusive: false }, function (fileEntry) {
writeFile(fileEntry, BINARY_ARR).then(function(){
//do something here
});
}, function(err) {});
}, function(err) {});
function writeFile(fileEntry, dataObj) {
return $q(function (resolve, reject) {
fileEntry.createWriter(function (fileWriter) {
fileWriter.onwriteend = function () {
resolve();
};
fileWriter.onerror = function (e) {
reject(e);
};
fileWriter.write(dataObj);
});
});
}
似乎..:
<preference name="AndroidPersistentFileLocation" value="Internal" />
这是默认配置,不能允许应用程序写入外部磁盘(无论是物理磁盘还是模拟磁盘)。相反,只允许应用程序写入 /data/data/{myApp}/files
好了,这里是整个如何保存文件的解释。使用文件插件cordova。
假设你要保存一个带文本的文件。"你好,Vaibhav Mojidra先生" 在...中 .txt 在内部存储。
如果你在HTML中点击了按钮,那么就会这样:现在在SaveFile函数中。
var textt=""; function SaveFile(text) { textt=text; * 初始化全局变量,将文本写入文件 * window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,onFileSystemSuccess, fail); * 这将检查存储的读写权限,如果获得了权限,那么函数发送参数将被调用,否则如果没有获得权限,第三个参数即失败函数将被调用 * } function onFileSystemSuccess(fileSystem) { fileSystem. root.getFile("Demo.txt",{create: true, exclusive: false},gotFileEntry,fail); * 这将在内部存储中创建一个名为Demo.txt的文件。 函数 gotFileEntry(fileEntry) { fileEntry.createWriter(gotFileWriter, fail); * 这将得到一个文件对象,并调用 createWriter 的路径,其中第 1 个参数用于在文件中写入内容,而第 2 个参数失败则用于创建 writer * } 函数 gotFileWriter(writer) { writer. write(textt);* 传递全局的textt参数,并在第一次调用函数时初始化* writer.onwriteend = function(evt) { alert("File Saved"); }; *当文件被写入文本并保存后,该函数将被调用* } function fail(error) { alert("Error", "There was some problem/nError: "+error.code, "Ok"); }。
使用这个函数来编写和创建新的文件夹
function writeFile(path, filename, blob) {
return new Promise((resolve, reject) => {
window.resolveLocalFileSystemURL(cordova.file.externalRootDirectory, function (dirpar) {
dirpar.getDirectory(path, { create: true }, function (dir) {
dir.getFile(filename, { create: true, exclusive: false }, function (fileEntry) {
fileEntry.createWriter(function (fileWriter) {
fileWriter.onwriteend = resolve
fileWriter.onerror = reject
fileWriter.write(blob);
});
}, reject);
}, reject);
}, reject);
});
}
如何调用函数
writeFile("AppFolder", 'file.name', blob)
样本下载图片并保存在文件夹中
var url = "image url"
fetch(url).then(res => res.blob()).then(blob => {
writeFile("pictures/myapp", url.substring(url.lastIndexOf("/") + 1), blob)
.then(function () { console.log("file donwloaded.") })
.catch(function (e) { console.error("error:", e) })
});
使用FileTransfer插件。https:/github.comapachecordova-plugin-file-transfer。 供下载和 https:/github.compwlincordova-plugin-pdialog。 显示 "进度 "对话框。
function saveFileDownloaded(url, nameFile) {
var uri = url;
var test = isEncoded(url)
if (test == false) {
uri = encodeURI(url)
}
var fileTransfer = new window.FileTransfer();
var fileURL = cordova.file.externalRootDirectory + "Direct/" + nameFile;
cordova.plugin.pDialog.init({
theme : 'DEVICE_LIGHT',
progressStyle : 'HORIZONTAL',
cancelable : false,
message : 'Téléchargement en cours...'
});
fileTransfer.onprogress = function(result) {
var percent = result.loaded / result.total * 100;
percent = Math.round(percent);
cordova.plugin.pDialog.setProgress(percent);
};
fileTransfer.download(
uri,
fileURL,
function(entry) {
cordova.plugin.pDialog.dismiss();
navigator.notification.confirm(
'Voulez vous ouvrir le fichier', // message
function(buttonIndex) {
onConfirm(buttonIndex, fileURL);
}, // callback to invoke
'Téléchargement terminé', // title
['Ok', 'Exit'] // buttonLabels
);
},
function(error) {
cordova.plugin.pDialog.dismiss();
console.log(error)
alert("Erreur lors du téléchargement, vérifier votre connexion!");
console.log("download error source " + error.source);
console.log("download error target " + error.target);
console.log("upload error code" + error.code);
}
);
}