I am trying to create a app specific directory (Internal) to store some images.I have tried many SO answers, but still nothing works.
I've tried this from here.
File mydir = getApplicationContext.getDir("mydir", Context.MODE_PRIVATE); //Creating an internal dir;
But still this directory is not created - Android/data/com.packagename/....
But when I run this-
File mediaDir = new File("/sdcard/Android/data/com.packagename");
if (!mediaDir.exists()){
mediaDir.mkdir();
}
This though creates the directory in the internal storage but is this the right way to do it ?
And yes I've added the internal read write permissions
getApplicationContext().getDir() will not create a folder named Android/data/com.packagename/.
If you log/print the path for the returned File you will see it is "/data/data/<packagename>/app_mydir/". This is the way it should be for internal storage.
If you want to create a directory on the sd card (usually referred to as external storage, even when the /sdcard path resides in internal flash storage) then use Context.getExternalFilesDir(). This will create a folder like "/sdcard/Android/data/<packagename>/files/"
Internal Storage:
To find locations on internal storage for your app, use getFilesDir(), called on any Context (such as your Activity, to get a File object.
There's getDir,
http://developer.android.com/reference/android/content/Context.html#getDir(java.lang.String,int)
Please have a look at:
http://developer.android.com/guide/topics/data/data-storage.html#filesInternal
For your purpose, instead of what you did with the path of sdCard, you can use
getExternalFilesDir
http://developer.android.com/reference/android/content/Context.html#getExternalFilesDir(java.lang.String)
It returns the path to files folder inside
Android/data/data/your_package/ on your SD card. It is used to store
any required files for your app (e.g. images downloaded from web or
cache files). Once the app is uninstalled, any data stored in this
folder is gone too.
Also,
Starting in KITKAT, no permissions are required to read or write to
the returned path; it's always accessible to the calling app. This
only applies to paths generated for package name of the calling
application. To access paths belonging to other packages,
WRITE_EXTERNAL_STORAGE and/or READ_EXTERNAL_STORAGE are required.
Can check more:
http://www.mysamplecode.com/2012/06/android-internal-external-storage.html
http://www.vogella.com/code/ApiDemos/src/com/example/android/apis/content/ExternalStorage.html
For API 8 and above that would work fine.
In case you want to a similar implementation for API 7 and below also,
getExternalStorageDirectory()
It returns the root path to your SD card (e.g mnt/sdcard/). If you
save data on this path and uninstall the app, that data won't be lost.
Related
I'm developing an app that has the functionality to upload all video and photo files to an external server, and I would like to offer the user the possibility to empty their photo and video directory...soon there is some easy way to do that? erasing everything at once
I assume your app already has a way to get access to the path to the directory you want to clear, and a permission to access the storage. Now having the path to the directory you could simply
File(pathToDirectory).list().forEach{ it.delete() }
Customize the behavior based on your needs. For example, you could recursively call the function containing the code above to clear a directory and all included subdirectories, or you could leave folders untouched and just delete files. For that, there are fields isFile and isDirectory
Not sure if there are new constraints and this is no longer possible in Marshmallow.
I have been launching the associated app for a given file extension type with an Intent.ACTION_VIEW. The problem I have is that the following code returns false, where in Android 5 and earlier it returns true (simplified):
String _HOMEFOLDER = "/storage/sdcard0";
String fileName = _HOMEFOLDER + "/FolderCreatedByUser/filename.ext";
File file = new File(fileName);
if (file.exists()) { }
Our app is pre-loaded by our team on only specific model tablets, so the _HOMEFOLDER part of the path was modified as one of the input files in the app and read at launch per device or if data was loaded on an external SD card.
I have been looking at alternative solutions, such as using:
context.getFilesDir().getAbsolutePath();
//returns: /data/user/0/com.mycompany.myapp/files
or
String strSDCardPath = System.getenv("SECONDARY_STORAGE");
if ((null == strSDCardPath) || (strSDCardPath.length() == 0)) {
strSDCardPath = System.getenv("EXTERNAL_SDCARD_STORAGE");
}
//strSDCardPath: /storage/sdcard1
The second option would be great, except there is no path for internal SD storage and EMULATED_STORAGE_TARGET doesn't come up on my Android 6 devices when executing on a cmd prompt:
adb shell
printenv
Is the first option my only choice, to move our file storage folder to be inside a special folder accessible only to our app such as:
/data/user/0/com.mycompany.myapp/files.
Does the Android SDK provide a method to create this folder and apply permissions? What if I would like this folder to exist on the External SD card? What about separate users?
Update: We have a lot of devices out in 'the wild' now which are going to break when users upgrade to Android 6 because the hard-coded path breaks in file.exists(); Is there a way to access /storage/... and the users home path with a hard-coded string, or is access to the users home folders now blocked? The app manifest includes permission to read/write to storage.
Our devices contain up to 100GB in this folder of documents which are single-time loaded to this folder before being given to customers. Moving the folder is a brutal option if we need to 'recall' ALL of the hundreds of tablets to manually update them.
Try this
String fileName = Environment.getExternalStorageDiretory() + "/FolderCreatedByUser/filename.ext";
The problem I have is that the following code returns false, where in Android 5 and earlier it returns true
That code shouldn't work on Android 4.4+, except perhaps on devices that were upgraded from older versions of Android. You do not have access to arbitrary paths on removable storage, short of rooting the tablet and mucking around with permissions. Devices that do not ship with the Play Store might allow access to arbitrary paths, though, as the no-removable-storage-access rule is enforced as part of compatibility testing by Google for Play ecosystem devices.
Is the first option my only choice, to move our file storage folder to be inside a special folder accessible only to our app such as /data/user/0/com.mycompany.myapp/files
Your choices are internal storage, external storage, and select locations on removable storage.
Does the Android SDK provide a method to create this folder and apply permissions?
Android will automatically create all necessary directories, at least once you stop hardcoding directory names and use methods to access them (e.g., getFilesDir(), getExternalFilesDir(), getExternalFilesDirs()).
What if I would like this folder to exist on the External SD card?
You are welcome to use getExternalFilesDirs() (note the plural). If that method returns 2+ entries, the second and subsequent ones are supposed to be on removable storage.
What about separate users?
Each user has separate internal and external storage. Off the cuff, I forget the rules for multiple users and removable storage, though I presume each user has unique space on there too.
UPDATE based on updated question:
Is there a way to access /storage/...
If you mean the stuff in your original code snippet, no.
and the users home path
There is no "users home path" in Android.
is access to the users home folders now blocked?
There is no "users home folders" in Android.
The app manifest includes permission to read/write to storage.
There are permissions for external storage. You are not using external storage, based upon your question.
In my Android App I save some files with some data file using
FileOutputStream savedList = new FileOutputStream(Path);
in a folder named myApp located in the SD storage
Unfortunately I have noticed that some cleaner Apps, not well implemented, also very popular (e.g. CleanMaster) wrongly remove the files every time the user perform a temp\trash file cleaning causing problems.
Is there a way to protect (and unprotect for writing) the file programmatically to avoid this?
How to change file permissions?
Since aren't used the file extensions to recognize the file format, how could I change the metadata of the file that are used to determine the file format so that these file are see as documents by these apps? I suppose that the scan of these Cleaners use some strategy based on Linux file format recognition and remove all object files.
Android allows to have private directory on SD card for the app.
you can get the path for private directory for your app as follows.
File myDir = getExternalFilesDir(null);
The null parameter indicates that you are going to store any type of files in the directory
myDir.mkdirs();
Log.d("info", myDir.getPath());
These files are internal to the applications, and not typically visible to the user as media.
This is like getFilesDir() in that these files will be deleted when the application is uninstalled, however there are some important differences:
Shared storage may not always be available, since removable media can be ejected by the user. Media state can be checked using getExternalStorageState(File).
There is no security enforced with these files. For example, any application holding WRITE_EXTERNAL_STORAGE can write to these files.
This solution worked for me as cleaning apps on devices don’t clean these folders considering them as private folders for the respective apps.
Checkout following link from android docs. Context.getExternalFilesDir(java.lang.String)
Write it to your private internal drive, so they don't have permission to touch it. SD cards are just FAT32 drives, so they don't support file permissions or access lists.
On 4.4 phones you may be ok, as Google basically prevents any writes to the SD card outside of a private directory. Cleaner type apps won't work on it at all, for better or worse.
First, you should read the first answer of this question. The thing to remember :
No, Environment.getExternalStorageDirectory() refers to whatever the device manufacturer considered to be "external storage". On some devices, this is removable media, like an SD card. On some devices, this is a portion of on-device flash.
The SD card is a vague notion, it's quite impossible to be 100% sure you are writting on the SD card.
That thing said, you should use the Android API to write your file on the private directory of the app, located in /path/to/external/storage/whatever/it/is/on/the/device/Android/data/com.package.yourapp/files
Use getExternalFilesDir to get the above File and write your file on the private directory of your app, this way, no one will be able to delete it.
Im trying to implement a small file Explore within my app in order to give to the user the ability to select new path (to store X) instead of the default path, also i want the user to be able to create and delete file.
So far my code is working however there is something really weird, im able to delete only file that i created myself within the app.
I have read a lot of file deletion tutorial example, here and there and i last time i check i have both read/write permission in my app manifest but still i cant delete files others than the one i created. here is the latest deletion code:
File file = new File(customAdapter.getItem(position).getFile().getAbsolutePath());
boolean isDeleted = file.delete();
if(!isDeleted){
Log.e("File manager: ",customAdapter.getItem(position).getFile().getName()+" deletion Fail");
} else {
fileHolderList.remove(position);
customAdapter.notifyDataSetChanged();
}
I have also read somewhere that for some security purposes android allow you to delete only file that your package created, ok but what about those file Explorer app in the play store which allow you a full control of your sd card or internal storage files. How do they did that? So that mean there is a way.
Please anyone can help with that?
Edit: i mean by file here Folder.
You can only modify files located on SDCard type, public storage. Whether real or emulated. Are you trying to modify files from the Internal storage? You need root permissions for changing anything outside your app's default data directories on the Internal Storage.
Since I now know that you are attempting to delete directories I assume that you are trying to delete directories that contain files. You should recursively delete the directory's contents before deleting the directory itself. See this question for how to go about that: https://stackoverflow.com/a/4026761/1590950
Something very strange is happenning in my app. I am creating 2 folders in the SD card if they not exist, and downloading some images from a URL if they not exist in the SD card.
Sometimes, when I run the application, the program checks if the folders exists and also the images, as they are exists, it continues and there's nothing wrong.
But often when I run the application, it alerts me that the folders not exists and that it didn't even managed to create those folders, and afterwards I'm getting a "File not found exception" when it tries to download the images who already exists in my SD card.
P.S: I tried it with 2 devices and the same happens, sometimes works, sometimes doesn't.
What could be the problem here?
Actually before accessing files from external storage you have to check whether External storage is present (Available) or not on device (It possible if device's sdcard is mounted on System). For this You have to check the sate of External Storage as Mounted or Not.
Look at this Link for more info..
http://developer.android.com/guide/topics/data/data-storage.html#filesExternal
Now solution:
If you find external storage is not available then you can store your files at Internal Storage on temporary basis (Then you can move these files to External Storage when it present).
So My link also help you in how to access Internal Storage in Android.