我在Android中保存文件时遇到了很多麻烦 该项目是使用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"
Android平台版本为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) {});
&#13;
我从{"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){});
&#13;
发生两件不同的事情
如果config.xml
中未指定配置选项,则应用会在/ storage / emulated / 0 / Android / media / {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的版本吗?
答案 0 :(得分:9)
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);
});
});
}
&#13;
似乎:
<preference name="AndroidPersistentFileLocation" value="Internal" />
这是默认配置,无法允许应用程序写入外部磁盘(无论是物理磁盘还是模拟磁盘)。相反,只允许应用写入/data/data/{myApp}/files
答案 1 :(得分:1)
好的,这就是如何保存文件的全部说明。使用文件插件cordova:
假设您必须在内部存储器的 .txt 中保存文本为“ Hello Mr. Vaibhav Mojidra” 的文件。
因此,如果您在HTML中单击按钮,如下所示: 现在在SaveFile函数中:
var textt=""; function SaveFile(text) { textt=text; /* initialize global variable with text to be written in file */ window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,onFileSystemSuccess, fail); /* This will check permission for storage read and write, and if got permission then function send parameter will be called else if not granted then third parameter ie fail function will be called */ } function onFileSystemSuccess(fileSystem) { fileSystem.root.getFile("Demo.txt",{create: true, exclusive: false},gotFileEntry,fail); /* This will create a file with name Demo.txt in internal storage . and similarly on sucessfully create it will call second parameter function i.e. gotFileEntry */ } function gotFileEntry(fileEntry) { fileEntry.createWriter(gotFileWriter, fail); /* This will get a file object with path call createWriter in which 1st parameter is use to write content in file and second parameter of fail to create writer */ } function gotFileWriter(writer) { writer.write(textt);/* passing parameter of the textt which is global and initialize at first called function*/ writer.onwriteend = function(evt) { alert("File Saved"); }; /*This function will be called once file is written with text and saved */ } function fail(error) { alert("Error","There was some problem\nError:"+error.code,"Ok"); }
答案 2 :(得分:0)
使用此功能编写和创建新文件夹
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) })
});
答案 3 :(得分:-1)
使用FileTransfer插件:https://github.com/apache/cordova-plugin-file-transfer进行下载,使用https://github.com/pwlin/cordova-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);
}
);
}