I'm goig to be mad with a strange issue. If i create a folder inside my code as
directory_path = Environment.getExternalStorageDirectory()
+ "/" + context.getResources().getString(R.string.app_name);
directory = new File(directory_path);
if (!directory.exists()) {
directory.mkdirs();
}
a new folder is created inside /sdcard/ . If i try to print on logcat directory_path variable, the path is different: /storage/emulated/0/
and if i go to that path, i found another folder with the same name of the one created on /sdcard/ . This is a problem for me because when i try to write some data into that folder, everithing goes in the one on /storage/emulated/0 , and the other one (that is the folder i want use) remain empty.
Why?
Have you tried reading back the data? /storage/emulated/0/ is the new path introduced in JB to support multiple users on tablet. But as long as you access external files using Environment.getExternalStorageDirectory() it doesn't really matter where they really reside.
Here's some additional info: https://android.stackexchange.com/questions/35541/why-did-sdcard-turn-into-sdcard-0-with-4-2
/storage/emulated/0/: to my knowledge, this refers to the "emulated
MMC" ("owner part"). Usually this is the internal one. The "0" stands
for the user here, "0" is the first user aka device-owner. If you
create additional users, this number will increment for each.
/storage/emulated/legacy/ as before, but pointing to the part of the
currently working user (for the owner, this would be a symlink to
/storage/emulated/0/). So this path should bring every user to his
"part".
/sdcard/: According to a comment by Shywim, this is a symlink to...
/mnt/sdcard (Android < 4.0)
/storage/sdcard0 (Android 4.0+)
For more detail you can visit stackexchange
Related
How can I save a file locally on an Android device,
using Delphi (XE5, Firemonkey)?
Something as simple as
Memo.Lines.SaveToFile('test.txt')
does not seem to work.
It results in the following error message:
"Cannot create file "/test.txt". Not a directory."
According to the document Creating an Android App, get the documents path like this:
System.IOUtils.TPath.GetDocumentsPath + System.SysUtils.PathDelim + 'myfile';
Instead of using System.SysUtils.PathDelim, you may use
System.IOUtils.TPath.Combine(System.IOUtils.tpath.getdocumentspath,'test.txt');
Combine chooses between the windows \ and the Linux /
System.IOUtils must be used in this line instead of setup in the uses clause because there are probably more Tpath initials.
GetHomePath, return a string with the path.
-> 'data/data//files'
You can to use:
Memo.Lines.SaveToFile(format('%s/test.txt', [GetHomePath]));
Or this form
Memo.Lines.SaveToFile(GetHomePath + '/test.txt');
on my device (and presumably all android devices?) GetHomePath incorrectly gives me /storage/emulated/0/... whereas I need /storage/sdcard0/... to get to the storage visible in Windows Explorer via USB.
so the full path to my files may be
'/storage/sdcard0/Android/data/com.embarcadero.(my app name)/files/'
Presumably if you have a plug in SD card this might be sdcard1 or whatever.
You can list the contents of your device storage folder with code like this
P := '/storage/';
if (FindFirst(P + '*', faAnyFile, Sr) = 0) then
repeat
Memo1.Lines.Add(Sr.Name);
until (FindNext(Sr) <> 0);
FindClose(Sr);
On my device this gives me:
sdcard0
usb
emulated
then change S when you want to explore subfolders
Note that the files folder gets emptied each time you recompile and deploy.
Is there any code to check whether or not the file's path is the filesytems ("/storage" or "/storage/emulated/0" or "/") in Android 7 ? Because when I call below code, it returns null in case the path of "folder" relates to filesystems in Android 7. I want to check to show some message like "This is the File System of Android" before calling below code.
File[] childFiles = folder.listFiles();
Use folder.exists(). Or folder.canRead().
But in Android 7 its impossible to list the "/" directory. And some other directories as you have seen.
Check childFiles for null and return if so.
Bad times ;-).
How can I save a file locally on an Android device,
using Delphi (XE5, Firemonkey)?
Something as simple as
Memo.Lines.SaveToFile('test.txt')
does not seem to work.
It results in the following error message:
"Cannot create file "/test.txt". Not a directory."
According to the document Creating an Android App, get the documents path like this:
System.IOUtils.TPath.GetDocumentsPath + System.SysUtils.PathDelim + 'myfile';
Instead of using System.SysUtils.PathDelim, you may use
System.IOUtils.TPath.Combine(System.IOUtils.tpath.getdocumentspath,'test.txt');
Combine chooses between the windows \ and the Linux /
System.IOUtils must be used in this line instead of setup in the uses clause because there are probably more Tpath initials.
GetHomePath, return a string with the path.
-> 'data/data//files'
You can to use:
Memo.Lines.SaveToFile(format('%s/test.txt', [GetHomePath]));
Or this form
Memo.Lines.SaveToFile(GetHomePath + '/test.txt');
on my device (and presumably all android devices?) GetHomePath incorrectly gives me /storage/emulated/0/... whereas I need /storage/sdcard0/... to get to the storage visible in Windows Explorer via USB.
so the full path to my files may be
'/storage/sdcard0/Android/data/com.embarcadero.(my app name)/files/'
Presumably if you have a plug in SD card this might be sdcard1 or whatever.
You can list the contents of your device storage folder with code like this
P := '/storage/';
if (FindFirst(P + '*', faAnyFile, Sr) = 0) then
repeat
Memo1.Lines.Add(Sr.Name);
until (FindNext(Sr) <> 0);
FindClose(Sr);
On my device this gives me:
sdcard0
usb
emulated
then change S when you want to explore subfolders
Note that the files folder gets emptied each time you recompile and deploy.
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() );
I have an issue with directory creation in Android. I use this code to create a directory if doesn't exist and then create a file under it.
dir=new File(Constants.TASK_DIRECTORY);
if(!dir.exists())
dir.mkdirs();
file=new File(dir, FILENAME);
file.createNewFile();
Sometimes it works fine, but sometimes when I check the folder from adb shell I see directories ending with 3 or more "|" characters. My directory name format is
"Abc_123-10.10.2000 ". What I see sometimes is exactly the same, but sometimes "Abc_123-10.10.2000|||" . I need to access the files under directories with the help of their name format but this situation makes it hard, any help would be appreciated.
I set TASK directory in this code
Constants.TASK_DIRECTORY=getFilesDir()+"/"+app.getUserName()+"-"+dt;
app is my application object
Edit: Solved this problem, it was because TASK_DIRECTORY was not properly set and contains "|" characters. But how can this be possible?
File can't store or save with some special character as below.
/\:?*"<>|