Labas rytas Deividas,
on Android you CAN NOT write to the [data] directory. So this is why the call
- saveStrings("myfile_which_i_want_to_save_in_data_directory.txt", myStringar);
will not work.
If you look under the hood, then on Android there's no such thing as [data] directory in the way we're used to think of directories. If you run your sketch on Android mode, then all of your files from sketches [data] directory are
packaged with the app AS RESOURCES. You can still run
- loadStrings("my_file_which_i_had_in_my_sketches_data_directory.txt");
and it will work. But under the hood
android mode for processing is not taking this file from [data] directory, but fetches it from the
apps resources. The main limitation is that
apps resources are Read Only. You can load them, but you can't write.
If you try in
android mode calling
- String absolutePath = dataPath("my_file_which_i_believe_is_in_data_folder_on_android.txt");
you will get string similar to this:
/data/data/processing.test.mysketch/files/data/my_file_which_i_believe_is_in_data_folder_on_android.txt
But despite there would be no error messages thrown, this path is actually rubbish path. Because on Android this directory never existed.
Even further, if you INCLUDE into your sketches [data] folder file
data.txt and try to load it (in
android mode) via:
- String[] data = loadStrings("data.txt");
- // this will work
but if you try this:
- String absolutePath = dataPath("data.txt");
- String[] data = loadStrings(absolutePath);
- // this will fail with IOException
The reason why red works and blue doesn't can be easily understood if you look from
android mode perspective. The code will be changed into:
- String[] data = loadStringsFromResourceNamed("data.txt");
- // will work 'cos when you exported your app, all files from data folder were packaged as resoruces
and the blue code will be chagned to:
- String absolutePath = dataPath("data.txt");
- String[] data = loadStringsFromAbsolutePath(absolutePath);
- // this will fail with IOException because there's no such absolute path.
The easiest solution for you would be to write to sd card, but do that you need to get absolute path of the sd card, this can be done on
android mode via:
- /**
- * This sketch shows how to
- * get writable filepath pointing
- * to external storage directory (SDCARD) in android mode.
- * REMEMBER:
- * For this sketch to be able to write to SD card, you need to
- * go in PDE to menu Android /Sketch Permissions and
- * enable WRITE_EXTERNAL_STORAGE permission.
- *
- * @author Dimitry Kireyenkov
- */
- import android.os.Environment;
- String msgToDraw = "no message set";
- void setup(){
-
-
- String dataFile = getSdWritableFilePathOrNull("strings.txt");
- if ( dataFile == null ){
- String errorMsg = "There was error getting SD card path. Maybe your device doesn't have SD card mounted at the moment";
- println(errorMsg);
- msgToDraw = errorMsg;
- }
- else{
- // now we can use save strings.
- String[] strings = split("This will become strings write into file", ' ');
- println("Now we're goign to attempt to save strings to file [" + dataFile + "]");
- saveStrings(dataFile, strings);
-
- msgToDraw = "looks like we've managed to save strings to file: [" + dataFile + "]";
- }
- }
- /**
- * This method works in a similar way as dataPath() method, except
- * but it provides writeable path on sd card.
- * So if you call it like this:
- *
- getSdWritableFilePathOrNull("strings.txt");
-
- it will return string similar to this:
-
- /mnt/sdcard/androidGetExternalStorage/strings.txt
-
- where 'androidGetExternalStorage' will be the name of your sketch.
- */
- String getSdWritableFilePathOrNull(String relativeFilename){
- File externalDir = Environment.getExternalStorageDirectory();
- if ( externalDir == null ){
- return null;
- }
- String sketchName= this.getClass().getSimpleName();
- //println("simple class (sketch) name is : " + sketchName );
- File sketchSdDir = new File(externalDir, sketchName);
-
- File finalDir = new File(sketchSdDir, relativeFilename);
- return finalDir.getAbsolutePath();
- }
- void draw(){
- drawMessageInScreenCenter(msgToDraw);
- drawRandomCircle();
-
- }
- void drawMessageInScreenCenter(String m){
- textAlign(CENTER, CENTER);
- fill(0);
- text(m, width/2, height/2);
- }
- void drawRandomCircle(){
- fill(random(128,255)); // light color filling for circles
- ellipse(random(width),
- random(height),
- 30, 30);
-
- }
...
You will get this exception in case you don't set WRITE_EXTERNAL_STORAGE permission
java.io.FileNotFoundException: /mnt/sdcard/mysketch/strings.txt: open failed: ENOENT (No such file or directory)
at libcore.io.IoBridge.open(IoBridge.java:448)
at java.io.FileOutputStream.<init>(FileOutputStream.java:88)
at java.io.FileOutputStream.<init>(FileOutputStream.java:128)
at java.io.FileOutputStream.<init>(FileOutputStream.java:117)
at processing.core.PApplet.saveStrings(Unknown Source)
at processing.core.PApplet.saveStrings(Unknown Source)
at processing.test.androidgetexternalstorage.androidGetExternalStorage.setup(androidGetExternalStorage.java:35)
at processing.core.PApplet.handleDraw(Unknown Source)
at processing.core.PGraphicsAndroid2D.requestDraw(Unknown Source)
at processing.core.PApplet.run(Unknown Source)
at java.lang.Thread.run(Thread.java:856)
Caused by: libcore.io.ErrnoException: open failed: ENOENT (No such file or directory)
at libcore.io.Posix.open(Native Method)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
at libcore.io.IoBridge.open(IoBridge.java:432)
... 10 more
So you have to set it from Android / Permisions menu
...