Skip to content

Should dataPath be deprecated? #450

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
kfrajer opened this issue Mar 18, 2018 · 6 comments
Closed

Should dataPath be deprecated? #450

kfrajer opened this issue Mar 18, 2018 · 6 comments

Comments

@kfrajer
Copy link
Contributor

kfrajer commented Mar 18, 2018

The code below produces the next output:

ALL files in data Path: /data/user/0/processing.test.sketch_180318d/files/data
Folder data is Empty/NULL

ALL files in / Path: /data/user/0/processing.test.sketch_180318d/files
img1.png img2.png img3.png img4.png img1.jpg img2.jpg img3.jpg img4.jpg data

ALL files in dataPath Path: /data/user/0/processing.test.sketch_180318d/files/data
Folder dataPath is Empty/NULL

ALL files in sketchPath Path: /data/user/0/processing.test.sketch_180318d/files
img1.png img2.png img3.png img4.png img1.jpg img2.jpg img3.jpg img4.jpg data

ALL files in assets Path:
images pskc_schema.xsd shaders sounds webkit

ALL files in assets/images Path: images
Evil_Calvin.jpg android-logo-mask.png android-logo-shine.png clock64.png horse-stand-512x512.png hummingbird.jpg james-dean-rebel-stencil-256x256.png

Notice I have about 6 files in data/images and I am also creating about 8 images using PImage.save(); before calling the functions above. From this I conclude:

All images are saved in a folder at the level of sketchPath(). Hence, they can be accessed with surface.getFileStreamPath("") or sketchPath(""). Files stored in data/images can only be accessed with surface.assets("images"). This shows that dataPath() is of not use for Android mode. Am I correct? Or should dataPath() somehow point to assets? My understanding from Android docs, the assets (obtained via AssetsManager) is read-only which means dataPath could point to assets only to read resources. My suggestion is to make dataPath to point to sketchPath as one can read and write there. For instance:

String filename="image.png";
PImage img=createImage(100,100,RGB);
img.save(filename);
img.save(dataPath(filename));  //Should be same as before

then the next should all be equivalent:

PImage image2=null;
image2=loadImage(filename);
image2=loadImage(dataPath(filename));
image2=loadImage(sketchPath(filename));

Currently dataPath() is not clear of what it should be. I might be wrong and using not in the proper way. Reflecting on the behavior in Processing Java, dataPath should allow access to a content where data can be written or read, so it should not point to assets but to to the sketchFolder.

Any changes made to dataPath should be re-consider to make sure it does not affect current external resources. That is, if any change of dataPath is implemented at all.

Lastly, notice that image1.save("data/image1.png"); throws an error:

java.lang.IllegalArgumentException: File contains a path separator

Hopefully here I get to document resource management based on Processing and Android guidelines.

Kf

P.S. Not tested but there seems to be other access point: path = this.getActivity().getFilesDir(); as shown here in this post.

//===========================================================================
// IMPORTS:

import android.app.Activity;
import android.content.Context;
import android.widget.FrameLayout;
//import android.app.Fragment;

import android.os.Environment;
import android.graphics.Color;
import android.widget.Toast;
import android.os.Looper;
import android.view.WindowManager;
import android.os.Bundle;
import android.view.ViewParent;
import android.view.ViewGroup;
import android.view.View;
import android.widget.RelativeLayout;
import android.view.LayoutInflater;
import android.R.string;


//===========================================================================
// FINAL FIELDS:


//===========================================================================
// GLOBAL VARIABLES:

Activity act;
Context mC;

String[] filenames;
PImage[] img;
File folder;


//===========================================================================
// PROCESSING DEFAULT FUNCTIONS:

void setup() {
  //size(400,600);
  fullScreen();
  orientation(PORTRAIT);
  //orientation(LANDSCAPE;)

  act = this.getActivity();
  Looper.prepare();

  textAlign(CENTER, CENTER);
  rectMode(CENTER);

  fill(255);
  strokeWeight(2);
  textSize(32);
  
  String[] con=null;


  //Create a sample of fake images in current folder
  String imagepath = surface.getFileStreamPath("").getAbsolutePath()+"/data";
  folder = new File(imagepath);
  folder.mkdirs();

  PImage img1=createImage(50, 50, RGB);
  img1.save("img1.png");
  img1.save("img2.png");
  img1.save("img3.png");
  img1.save("img4.png");
  img1.save("img1.jpg");
  img1.save("img2.jpg");
  img1.save("img3.jpg");
  img1.save("img4.jpg");

  delay(2000);

  printContent("data", folder );
  printContent("/", surface.getFileStreamPath(""));
  printContent("dataPath", new File(dataPath("")));
  printContent("sketchPath", new File(sketchPath("")));
  printContent("assets", "");
  con=printContent("assets/images", "images");

}

void draw() {
  background(0);
}

void printContent(String label, File f) {
  println("\n====================");
  println("ALL files in "+label+" Path: "+f.getAbsolutePath());
  String[] conFolder=f.list();
  if (conFolder!=null && conFolder.length!=0)   println(conFolder);
  else                                          println("Folder "+ label +" is Empty/NULL");
}


String[] printContent(String label, String pathStr) {
  String[] con2=null;
  try {
    con2=surface.getAssets().list(pathStr);
    println("\n====================");
    println("ALL files in "+label+" Path: "+pathStr);
    if (con2!=null && con2.length!=0)  println(con2);
    else                             println("NOTHING in current assets");
  }
  catch(IOException e) {
    e.printStackTrace();
  }

  return con2;
}

//===========================================================================
// ANDROID ACTIVITY LIFECYCLE'S FUNCTIONS:


//  @@@@@@@@@@@@
@Override 
  public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
}

//  @@@@@@@@@@@@
@Override 
  public void onStart() {
  super.onStart();
}

//  @@@@@@@@@@@@
@Override 
  public void onResume() {
  super.onResume();

  act = this.getActivity();
  mC= act.getApplicationContext();
}

//  @@@@@@@@@@@@
@Override 
  public void onPause() {
  super.onPause();
}

//  @@@@@@@@@@@@
@Override 
  public void onStop() {
  super.onStop();
}

//  @@@@@@@@@@@@
@Override 
  public void onDestroy() {
  super.onDestroy();
}

@codeanticode
Copy link
Contributor

@kfrajer I agree that dataPath() is problematic on Android, although I would not remove or deprecate it in order to keep the API consistency with Java.

If I'm not mistaken, the files originally in the sketch's data folder get packed as assets in the apk, so does not really make sense to get a data path to those. For files created by the running sketch, their correct path is sketchPath(), so dataPath() in that case should return the same.

So maybe the following is a possible behavior for dataPath():

  • Check if the file is an asset, if so, just return the original filename and print a warning.
  • If the file is not an asset, create a full path by prepending sketchPath. If the resulting file exists, return its absolute path. Otherwise throw an error.

What do you think?

@kfrajer
Copy link
Contributor Author

kfrajer commented May 28, 2018

Hi Andres,
I think that is a great idea. So, there should be an algorithm that , for every [Step 1] dataPath() type of request, it checks the content of the asset folder and return this resource if found. Could you explain what would one need a warning? To tell people this resource cannot be modified? If dataPath() retrieves files from assets, then ppl should be aware that these resources cannot be modified as described by the Android API documentation. Maybe you have another vision that I am missing. Maybe the warning is to say the file was not found in assets and next is to check in the sketchPath() directory?

If not found in asset, then [step2] attempt sketchPath. Sounds great!

Do you want me to implement this concept?

Is there a name for sketchPath directory level in android? I mean, I am sure people can save data on their applications. Beside using external storage and Android API resources for short term/small data set storage, is there another are where user can store larger sets of data without requiring writing permissions?

Kf

@kfrajer
Copy link
Contributor Author

kfrajer commented Jun 3, 2018

I did more testing today to capture file IO access here: https://discourse.processing.org/t/tracking-high-score-for-android/678

Kf

@codeanticode
Copy link
Contributor

@kfrajer I implemented the proposed changes with this commit: 896a76c

Let me know if you think this solves the issue.

Regarding your comments:

  • I agree with you that there is no need for warning if file is an asset
  • From reading Android docs it sounds like what sketchPath() is returning is the path to the internal storage. I don't know if there is another way to store application data that does not use either the internal or the external storage, as described in the docs.

@codeanticode
Copy link
Contributor

Releasing v4.0.2, which includes the fix we discussed before. So I'm closing this issue, but feel free to reopen if you think dataPath() should be handled differently. Thank you!

@kfrajer
Copy link
Contributor Author

kfrajer commented Jun 19, 2018

Hi Andres,
I haven't had time to review your changes. However, I will get to do it sooner or later. Related to sketchPath and the "private internal" storage, I think it makes sense the way you had it setup (I am not referring to your latest changes). At the end, the only issue was documentation and examples related to datapath usage in Processing in android mode. Even when I tried to answer some questions in the forum, I was scratching my head sometimes. Right now I have a better understanding and I have to run some extra tests to capture the most common usage. I am looking forward to test your changes. I will get back to you in few days.

Kf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants