Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issues with build.phonegap write to file

I'm trying to build a PhoneGap application through the online build service that should run on both iOS and Android, but this question focuses on the Android part.

The main target of the application is to be able to access and modify the filesystem. Inspired from Raymond Camden's blog post, I ended up writing a sample application very similar to his, that accesses the filesystem with read/write privileges. The main difference is that my application is built online without any SDK installed and without caring about any androidManifes.xml file.

My problem is that I am able to access the filesystem (list directories, read files), but I am not able to write anything on it.

I have included the necessary <feature /> tag in the confix.xml in order to have file access permissions:

<feature name="http://api.phonegap.com/1.0/file"/>

Here is some sample code used in my application:

Read file code:

// Request fileSystem
fileSystem.root.getFile(fileName, {create:true}, readFile, onError);

// Function that reads a file
function readFile(file){
    var reader = new FileReader();
    reader.onloadend = function(e) {
        console.log("contents: ", e.target.result);
    }
    reader.readAsText(file);
}

Write/append file code:

fileSystem.root.getFile(fileName, {create:true}, function(file){
    file.createWriter(function(writer) {
        writer.onwrite = function() {
            console.log('writing', arguments);
        }

        writer.onerror = function(e) {
            console.error('error', e);
        }

        writer.onwriteend = function() {
            console.log('writeend', arguments);
        }

        //Go to the end of the file...
        writer.seek(writer.length);

        // Append a timestamp
        writerOb.write("Test at "+new Date().toString() + "\n");
    })
}, onError);

The second code sample doesn't write anything in the targeted file and the onerror handlers shows that it's because of a NOT_FOUND_ERR. And this just doesn't make sense, because I am able to read that same file (and it can be found).

In the same manner, when I try to create a new file (with the same code from write/append file code, but where the targeted file doesn't exist), I get a INVALID_MODIFICATION_ERR error.

I have also tried the example in the official documentation and I got the same result (read and no write).

Note that since PhoneGap is using the HTML5 file API, I've tried to write the contents through blobs as suggested in this Stack Overflow answer (and in other sites) without any luck.

What am I missing? Do I need a separate plugin for writing files or is this something that can't be done via the online build tool and I have to download the SDK and compile the application the old fashioned way?

P.S.: My PhoneGap version is 2.3.0.

like image 341
gion_13 Avatar asked Apr 03 '13 09:04

gion_13


2 Answers

I've created an app with PG build that writes to the file system, so I'm certain it can be done and doesn't require a plugin. The main conspicuous difference I'm seeing in my code is that I'm explicitly setting the exclusive flag in the getFile options to false.

If you're testing with iOS another shot in the dark solution would be to check that you're setting your app id correctly in the config.xml

EDIT: In the app I mentioned, there file system writing code is here

like image 151
Nathan Breit Avatar answered Sep 28 '22 14:09

Nathan Breit


Here's the Java method I'm using for writing to a file:

public void writeMyFile(String fileName, String data) throws IOException {

    File root = Environment.getExternalStorageDirectory();
    System.out.println(root);
    File gpxfile = new File(root, fileName);

    FileWriter writer = new FileWriter(gpxfile);
    String[][] recordvalue = new String[100][100];
    System.out.println("fetched value" + data);
    String[] line = data.split("#");

    // I had multiple lines of data, all split by the # symbol in a single string.
    System.out.println("row length "+line.length);

        for (int i=1; i<line.length; i++)
        {
            writer.append("#");
            recordvalue[i] = line[i].split(",");
            for(int j=0; j<recordvalue[i].length; j++) {
                System.out.println(recordvalue[i][j]);
                writer.append(recordvalue[i][j]);
                writer.append(",");
            }
            writer.append("\n");
        }

    Uri uri = Uri.fromFile(gpxfile);
    System.out.println(uri);

    writer.flush();
    writer.close();

    try {
        // Do something
    }
    catch (Exception e) {
        // If there is nothing that can send a text/html MIME type
        e.printStackTrace();
    }
}

The imports for the class/method are as follows:

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import org.apache.cordova.api.PluginResult;
import org.json.JSONArray;

import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;

import com.phonegap.api.Plugin;

And the main execute class for the plugin is as follows:

public PluginResult execute(String arg0, JSONArray arg1, String arg2) {
    try {
         String fileName = arg1.getString(0);
         String data = arg1.getString(1);
         writeMyFile(fileName, data);
    }
    catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}
like image 43
SashaZd Avatar answered Sep 28 '22 14:09

SashaZd