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.
Related
LibGDX: I have game-data files created at runtime for debugging purposes (a replay system). The files are stored in Gdx.files.local() whether on desktop or android. Now I want to copy the ones that were created on android so I can debug them on desktop.
Running Gdx.files.getLocalStoragePath() on android returns /data/user/0/com.[my domain].[my app]/files/. Using Windows Explorer I do not see my app's folder in /data/user/0, or anything else for that matter. So private storage indeed it is, but how nonetheless can I get hold of these files, without root if possible?
The solution may be manual copy or in code, whatever works. Just to note, the file names are unknown without seeing the files first. They were named using current date-time. The extension is known, though.
EDIT
I discovered Android Studio's Device File Explorer. I connected my device, tried to see inside my app folder and app data folder, both showing 'Operation not permitted'.
So to put the question in simpler words, is rooting the phone really the only way for developers to see the files created by their apps?
Or is there a magical gate somewhere known only to select few zen masters who guard the secret through the generations? Because I sure ain't finding it.
I'm not sure that there is a way to write changes in the system file without having root access but you can read them. According to this Blog, You can access those files and put it in your desktop. You can download RAR app from googleplay.
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.
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.
I want to lock files that is on the sdcard of android.
I need to lock them so no one except my software can delete copy move or send them over bluetooth or any other way.
How can I do it?
There is no way to lock a file in Android; even if there was, the files would only be locked when your application was running which wouldn't stop other apps accessing the file when the user hadn't started your app.
SD Cards are usually formatted with FAT (or FAT32) and this is the case with Android. FAT offers very limited file permissions so you can't restrict access to the files this way. Again, even if you could do something like this, this wouldn't offer any protection if the user took the SD Card out of their phone and put it their PC.
If you want to keep your application's files private you need to put them in the phone's internal storage in the area reserved for you application. Each application runs with a different User ID and each application's data directory is protected using UNIX-style file permissions which prevents other applications from reading them. So while this will stop other applications having access to your files it wouldn't stop a reasonably determined user with root access to their phone copying them off.
Have a look at the Context.openFileInput(), Content.openFileOutput() and Context.getFilesDir() methods for details on how to store files in the phone's internal storage.
You cannot do this on any platform (let alone Android) using a regular SD card. Sorry!
I think you want to encrypt the file. While the file can still be moved around, it will be useless to anything but your application. People will be able to copy, move, delete but the contents won't be compromised.