Slashes removed from calls to File.mkdirs() - android

As the title suggests, I am trying to create a folder on Android, but all of the slashes have been removed from it.
For some more background information:
Specifically, I am trying to create a directory to store my application's users' files. These files must be accessible to the user from a file manager (such as File Manager HD) because the application does not support full file management. Using the standard from API level 8+, I reference the root of the publicly accessible folder with Environment.getExternalStoragePublicDirectory(). I then try to create a folder located at DCIM > Sketchbook > [the name of the sketch] using File.mkdirs(). For more information, see the code below.
I have already:
checked to make sure that the SD card is mounted, readable, and writable
enabled the permission WRITE_EXTERNAL_STORAGE
tried using File.mkdir() for every file in the hierarchy up to the folder location
tried using /, \\, File.separatorChar, and File.separator as folder separators
Code:
boolean success = true;
//The public directory
File publicDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
//The location of the sketchbook
File sketchbookLoc = new File(publicDir + "Sketchbook" + File.separator);
//The location of the sketch
//getGlobalState().getSketchName() returns the name of the sketch: "sketch"
File sketchLoc = new File(sketchbookLoc + getGlobalState().getSketchName() + File.separator);
if(!sketchLoc.mkdirs()) success = false;
//Notify the user of whether or not the sketch has been saved properly
if(success)
((TextView) findViewById(R.id.message)).setText(getResources().getText(R.string.sketch_saved));
else
((TextView) findViewById(R.id.message)).setText(getResources().getText(R.string.sketch_save_failure));
With various incarnations of the aforementioned tests (the ones that actually worked), I have received a consistent result: I get a new folder in DCIM whose name corresponds to the combination of all of the folders that should have been hierarchical parents of it. In other words, I have created a new directory, but all of the folder separators have been removed from it.
Now, I ask you:
Am I attempting to save the user data in the correct location? Is there another way that I should be doing this?
Is it even possible to create new folders in the DCIM folder? Does Android prevent it?
Is this problem specific to me? Is anyone else able to create a folder in the DCIM folder?
Am I using the right folder separators?
Is there something else that I am absolutely, completely, and utterly missing?
Now that I am done typing, and you are done reading my (excessively long) question, I hope that I can find some sort of answer. If you need clarification or more information, please say so.
EDIT: An example of the created folder is "DCIMSketchbooksketch", where it should be "DCIM/Sketchbook/sketch".

don't use
File sketchbookLoc = new File(publicDir + "Sketchbook" + File.separator);
but
File sketchbookLoc = new File(publicDir , "Sketchbook");
because publicDir.toString() will not end with a file separator (even if you declared it that way). toString() gives the canonical name of the file.
So your source becomes :
//The location of the sketchbook
File sketchbookLoc = new File(publicDir , "Sketchbook" );
//The location of the sketch
File sketchLoc = new File(sketchbookLoc , getGlobalState().getSketchName() );

Related

How can I rename a folder I created in the shared storage?

My app creates folders in the shared storage (DCIM/ and Pictures/ directories), which I want to be able to rename afterwards.
I save the images using MediaStore, the folders are created automatically.
Android Q (and above) already takes care of creating the folders if
they don’t exist. The example is hard-coded to output into the
DCIM folder. If you need a sub-folder then append the sub-folder name as next:
final String relativeLocation = Environment.DIRECTORY_DCIM + File.separator + “YourSubforderName”;
https://stackoverflow.com/a/56990305/10226383
I just can't seem to figure out how to do it, is that even possible with scoped storage, do I need to use MediaStore or SAF?
I know before the change to scoped storage you could do it this way:
File oldfolder = new File("path of the old folder","old name");
File newfolder = new File("path of the new folder","new name");
oldfolder.renameTo(newfolder);
If someone could point me in the right direction I would be really grateful!

Error creating directory with specific name android

I need to create 2 directories in my android application,
I can use this code to create a directory just fine
File m_Dir = new File(getFilesDir() + "/randomDir");
m_Dir.mkdir();
if (m_Dir.isDirectory()) {
Log.w("tag","randomDir dir is a directory");
}
however I cannot use this because it does not create a directory, no errors, but it just isn't a directory for some reason, even though the only thing that changed is the name of the file
File m_Dir = new File(getFilesDir() + "/dict");
m_Dir.mkdir();
if (m_Dir.isDirectory()) {
Log.w("tag","dict dir is a directory");
}
note they must be named "dict and "dbfiles", Using them for JWI wordnet, and thats how it locates the files it needs.
I have tried this many times with different names, and the only reason that this m_Dir.isDirectory returns false is because of the name, this doesn't make sense to me. The only reason I can think of, that this might fail is because I have file directories in my Assets folder with the same name.(I am copying these into my new directory so i can use them). I can change the name of the Asset folders (Probably what I'm going to do). However I created another folder in assets using a different name, I tried that name and it worked creating the directory using the same code as before. So that may not even be the problem. I was wondering wondering why this problem is occurring (No errors but no directory) and if there is any better way around it?

Where should I choose to save text file in android?

I hope to export my data as a text file and save it to disk in Android, so I need to choose which folder I will save the file to.
I hope that a normal user can find the folder easily and the app does not need special permission to create the folder.
I have read some document, it seems that there are 3 ways: Context.getFilesDir().getAbsolutePath(), Environment.getExternalStorageDirectory().getAbsolutePath() and Context.getExternalFilesDir(null).
You know some android users don't install SD card, so it seems that Environment.getExternalStorageDirectory().getAbsolutePath() and Context.getExternalFilesDir(null) are be excluded.
Am I only to choose Context.getFilesDir().getAbsolutePath()? or is there a better way? Thanks!
BTW, From the document Android - Where to save text files to?
Save it in internal phone storage, here no users and applications can access these files(unless if phone is rooted). But these files will be deleted one's the user selectes clear data from Settings -> Apps -> .
It seems that normal users can't access the saved text files if I use Context.getFilesDir().getAbsolutePath(), is it right?
Use this if you want a path that the user can modify and can have access
getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath();
More documentation here.
EDIT:
This is how use in case error in some devices:
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
String fname = "TEXT.txt";
File file = new File(path, fname);
if (!path.exists()) {
//noinspection ResultOfMethodCallIgnored
path.mkdir();
}
// YOUR CODE FOR COPY OR CREATE THE FILE TXT in PATH WITH THE VARIABLE file ABOVE

Get preloaded file in android

I'm new to android development and I am working on a little project. What I am having some issue with is getting access to preloaded files.
In my app, I have an XML file that I preloaded (I just simply put it in my src folder in a package). How do I access them in my classes? I need to get a File object pointing to this file so that I can use it as I would I/O files. It seems like this should be trivial, but alas I am stuck.
Lets say the file is located under: com.app.preloadedFiles/file1.XML
I've tried something along the lines of this, but have had no success:
URL dir_url = ClassLoader.getSystemResource("preloadedFiles/file1.XML");
FIle file = new File(dir_url.toURI());
I solved this in my app by getting an InputStream to the file -- something like:
myContext.getAssets().open(fileName);
//read the data and store it in a variable
Then, if you truly need to do File related opterations with it, you can write it to a private (or public) directory and do your operations from you newly written file. Something like:
File storageDir = myContext.getDir(directoryName, Context.MODE_PRIVATE);
File myFile = new File(storageDir + File.separator + fileName);
//then, write the data to the file and manipulate it -- store the name for access via File later

android data save directories

My application is mostly c++ (using NDK) so I use fopen, fwrite, etc. standard functions to create and game save files and write into them.
When I use fopen("game.sav", "wb"), it appears that it's being created at path
/data/user/10/com.my.game/files/game.sav.
My app is multi-user. So I want to have a separated folders where users store their save-files. And instead of the path above I'd like to have paths like
/data/user/10/com.my.game/files/user0/game.sav,
/data/user/10/com.my.game/files/user1/game.sav, etc
My app's frontend is in Java, and when new user is being registered, I want to create a folder /data/user/10/com.my.game/files/user0/. But I don't know how to do it, because
final File newDir = context.getDir("user0", Context.MODE_PRIVATE);
results in path being created at /data/user/10/com.my.game/app_user0 that's a different path.
It is possible to create folders at /data/user/10/com.my.game/files/ and how ?
Simple way to do it, this code you can change it suit many conditions. If you know that your path is different from what getFilesDir() gets you then you can create a File first of all by using a path that you know and the last 2 lines of code will still be same.
File file = this.getFilesDir(); // this will get you internal directory path
Log.d("BLA BLA", file.getAbsolutePath());
File newfile = new File(file.getAbsolutePath() + "/foo"); // foo is the directory 2 create
newfile.mkdir();
And if you know the path to "files" directory:
File newfile2 = new File("/data/data/com.example.stackoverflow/files" + "/foo2");
newfile2.mkdir();
Both code works.
Proof of Working:

Categories

Resources