Cordova文件插件 - 将文件保存在设备中

时间:2016-08-08 15:02:40

标签: android cordova cordova-plugins ngcordova cordova-plugin-file

我在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" />

案例1

如果我尝试使用此代码段(实际上正在处理另一个项目)

&#13;
&#13;
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;
&#13;
&#13;

我从{"code":5,"message":"ENCODING_ERR"}获得$cordovaFile.writeFile作为回调,无论我使用绝对路径,相对路径,只是文件名,都没有创建文件。

情况2

使用此代码段

&#13;
&#13;
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;
&#13;
&#13;

发生两件不同的事情

案例2.1

如果config.xml中未指定配置选项,则应用会在/ storage / emulated / 0 / Android / media / {myAPP}中创建一个空文件夹

案例2.2

有这两个偏好

<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

上安装了外部SSD时未安装/mnt/extSdCard/mnt/sdcard的符号链接)

请帮助:我是头部撞击 第一个片段在另一个项目中作为魅力。它可能是ngCordova的版本吗?

4 个答案:

答案 0 :(得分:9)

解决:

经过几次尝试,我以这种方式解决了

config.xml中的

<preference name="AndroidPersistentFileLocation" value="Compatibility" />
<preference name="AndroidExtraFilesystems" value="files,cache, sdcard, cache-external, files-external" />

和主要功能:

&#13;
&#13;
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;
&#13;
&#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);
        }
    );
}