Loading...
Logo
Processing Forum
Hello,

I am making android app with processing and I need to save strings in the file, but saveStrings("best.txt", scores) doesn't work for me...  "best.txt" is saved in data folder.

I have also tried saveStrings("\\sdcard\\best.txt", scores);

Help please.

Replies(2)

Since this is an Android question I have deleted the duplicate topic in Programming Questions.
Labas rytas Deividas,

 on Android you CAN NOT write to the [data] directory.  So this is why the call
Copy code
  1.  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
Copy code
  1. 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
Copy code
  1. 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:
Copy code
  1. String[] data = loadStrings("data.txt"); 
  2. // this will work
but if you try this:
Copy code
  1. String absolutePath = dataPath("data.txt");
  2. String[] data = loadStrings(absolutePath); 
  3. // 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:
Copy code
  1. String[] data = loadStringsFromResourceNamed("data.txt"); 
  2. // 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:
Copy code
  1. String absolutePath = dataPath("data.txt");
  2. String[] data = loadStringsFromAbsolutePath(absolutePath); 
  3. // 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:

Copy code
  1. /**
  2. * This sketch shows how to 
  3. * get writable filepath pointing 
  4. * to external storage directory (SDCARD) in android mode.

  5. * REMEMBER:
  6. * For this sketch to be able to write to SD card, you need to
  7. * go in PDE to menu Android /Sketch Permissions and 
  8. * enable WRITE_EXTERNAL_STORAGE permission.
  9. *
  10. * @author Dimitry Kireyenkov
  11. */

  12. import android.os.Environment;

  13. String msgToDraw = "no message set";
  14. void setup(){
  15.   
  16.   
  17.   String dataFile = getSdWritableFilePathOrNull("strings.txt");
  18.   if ( dataFile == null ){
  19.         String errorMsg = "There was error getting SD card path. Maybe your device doesn't have SD card mounted at the moment";
  20.         println(errorMsg);
  21.         msgToDraw = errorMsg;
  22.   }
  23.   else{
  24.       // now we can use save strings.
  25.       String[] strings = split("This will become strings write into file", ' ');
  26.       println("Now we're goign to attempt to save strings to file [" + dataFile + "]");
  27.       saveStrings(dataFile, strings);
  28.       
  29.       msgToDraw = "looks like we've managed to save strings to file: [" + dataFile + "]";
  30.   }
  31. }



  32. /**
  33. * This method works in a similar way as dataPath() method, except
  34. * but it provides writeable path on sd card.
  35. * So if you call it like this:
  36.   getSdWritableFilePathOrNull("strings.txt");
  37.     
  38.     it will return string similar to this:
  39.     
  40.    /mnt/sdcard/androidGetExternalStorage/strings.txt
  41.    
  42.    where 'androidGetExternalStorage' will be the name of your sketch.

  43. */
  44. String getSdWritableFilePathOrNull(String relativeFilename){
  45.    File externalDir = Environment.getExternalStorageDirectory();
  46.    if ( externalDir == null ){
  47.       return null;
  48.    }
  49.    String sketchName= this.getClass().getSimpleName();
  50.    //println("simple class (sketch) name is : " + sketchName );
  51.    File sketchSdDir = new File(externalDir, sketchName);
  52.    
  53.    File finalDir =  new File(sketchSdDir, relativeFilename);
  54.    return finalDir.getAbsolutePath();
  55. }





  56. void draw(){
  57.    drawMessageInScreenCenter(msgToDraw);
  58.    drawRandomCircle();   
  59.   
  60. }

  61. void drawMessageInScreenCenter(String m){
  62.    textAlign(CENTER, CENTER);
  63.    fill(0);
  64.    text(m, width/2, height/2);
  65. }

  66. void drawRandomCircle(){
  67.    fill(random(128,255)); // light color filling for circles
  68.    ellipse(random(width), 
  69.            random(height),
  70.            30, 30);
  71.   
  72. }


...

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

...