I have an application that saves files downloaded from a server. These files are not private to my application and should be accessible to other applications as well. I want to know what would be the correct path to save these files when the SD card is ABSENT. For the SD card, there is the well known API -
getExternalStorageDirectory()
For the application's private data in the internal memory there is -
Context.getFilesDir()
On some devices, the internal memory is represented by /emmc/.
It will be really helpful if someone could elaborate on /emmc/. I know it stands for embedded Memory card and is not present in all the devices. But is it really representative of the internal memory? Or is it the third memory?
Should I save the files using openFileOutput() with MODE_WORLD_READABLE?
I realize this is old and has an accepted answer, but I think the question is still relevant and that there is a way to achieve what the asker wants.
To paraphrase, I believe the asker wants to save a file, and make it accessible (e.g. for viewing) by other apps, without having to think about external storage (e.g. an additional permission and the possibility that the external storage is not present).
It turns out that you can make your own files readable by other apps.
File file = new File( ctx.getCacheDir(), "picture" );
...
file.setReadable( true, false );
// makes file readable to other apps
// Get another app to view my picture
Uri uri = Uri.fromFile(file);
Intent intent = new Intent( Intent.ACTION_VIEW );
intent.setDataAndType( uri, "image/*" );
ctx.startActivity( intent );
The setReadable made the above code work for me - without that line the viewer app couldn't read the file. Note that setReadable operates on the whole directory, so the best solution is probably to create a sub-directory name 'public' and put your files in there.
On some devices, the internal memory is represented by /emmc/.
/emmc/ may exist on some devices, and it may be internal, but it may not be accessible to applications, and it certainly is not part of the Android SDK unless that happens to be what getExternalStorageDirectory() returns.
But is it really representative of the internal memory?
No.
Or is it the third memory?
Ask your device manufacturer.
Should I save the files using openFileOutput() with MODE_WORLD_READABLE ?
That is impossible to answer in the abstract. You say that your files "should be accessible to other applications as well", but you have not indicated why you expect any other application to care one bit about your files. Other applications will not be scanning your directories for files -- at best, they will allow users to browse external storage. The only reason to have a file that is MODE_WORLD_READABLE is if your application will be triggering another application to do something with the file (e.g., ACTION_VIEW Intent).
Related
I'm playing around with Android's MediaStore classes and was attempting to create a very simple photo gallery app when I noticed that were two image content URIs: EXTERNAL_CONTENT_URI and INTERNAL_CONTENT_URI. At first I thought it was referring to the location of storage (external SD or internal memory) but after a bit of testing this was clearly not the case. I read more about it here, and it seemed to indicate that the internal content uri is actually content that are internal to each of the apps on the device. However I am not entirely sure and wanted opinions from more experienced developers who are more familiar with the MediaStore classes.
So my main question is, would just querying the EXTERNAL_CONTENT_URI be enough to get all of the important photos? And if possible to answer, what exactly is the INTERNAL_CONTENT_URI and what is it supposed to be used for?
External vs Internal storage doesn't refer to the location of the memory, but the privacy policy regarding it. Internal storage means only the app or system/super user processes can access the contents.
External storage can be read by every app, it's what appears when you plug in your phone to your computer, so you can think of it as what is shown to everyone else, hence "external."
I have a Samsung S5 for instance, and it puts both internal and external storage on the same 'internal' flash memory, they are in fact just separate partitions on the same stick of ram.
When I add a SD card, it adds another (secondary) external storage location.
Every android device must ship with internal and external storage, so devices that ship without an SD Card for instance are guaranteed to have partitioned 'internal' memory, for internal and external storage.
As for how the External_Content_URI relates, it will return images that are located in external storage -- reading the docs more closely, it says it returns only for the "primary" external storage volume. I just noticed that last part in quotes myself, so it's something I'll test in the next few days if secondary external storage is also indexed or retrieved by the mediastore, if someone else doesn't help answer that first.
http://developer.android.com/reference/android/provider/MediaStore.Images.Media.html
I would like to send a file by email. The app writes a csv file, and then shares this file via the usual ACTION_SEND Intent.
For this to work, the file must be readable by other apps (the email app).
I have tried getExternalStorageDirectory() but it doesn't work. /sdcard works but I feel it is clumsy to use a path like that
What's the best alternative ?
It returns null
Perhaps you are running on an emulator for which you did not configure external storage (erroneously referred to as "SD card" in the AVD Manager). I can think of no reason for getExternalStorageDirectory() to return null on a production device.
What's the best alternative ?
Use FileProvider to share the file from your app's internal storage.
I have to persist 2 strings for my application even after the application is uninstalled. Regarding that the end users don't have SD cards for their devices and they don't have internet connection, how could I persist those 2 strings even after the app is uninstalled?
I would highly appreciate any response.
Thanks
Unless you're targeting VERY old phones, you don't need to worry about not having external storage. As long as you use Environment.getExternalStorageDirectory() as your reference, you shouldn't have a problem, though if you're absolutely concerned about this you can check if the external storage doesn't exist and then opt to go to internal storage. Check out this link from the developer docs for a little more insight.
If External truly isn't available, you could then save to Internal memory, but you will have to declare a new permission for that, which may ward off some people.
You have to write it to an SD card/internal storage, and hope the user does not remove that. However, this is a very fragile approach. There is no other solution, as far as I know.
Phones internal storage is also treated as an "SD card". If you create a folder and save it in a text file, it should be safe given user does not manually delete folders after uninstall.
Please check out a section "Saving files that should be shared" in the following web page. Making a file that persists after uninstall entails making it available to other apps/user to read and modify. If those file options aren't intended, you should consider an alternative app design.
http://developer.android.com/guide/topics/data/data-storage.html#filesInternal
After re-install, your app can access the created public directory by using the following function:
public static File getExternalStorageDirectory ()
Regarding the function above, per Google:
Note: don't be confused by the word "external" here. This directory can better be thought as media/shared storage. It is a filesystem that can hold a relatively large amount of data and that is shared across all applications (does not enforce permissions). Traditionally this is an SD card, but it may also be implemented as built-in storage in a device that is distinct from the protected internal storage and can be mounted as a filesystem on a computer.
Also, Google recomments placing shared files into a an existing public directory as to not pollute user's root namespace.
Are the strings unique to each user or are they app specific? In either case, the right thing to do would be to save it in some kind of remote server. Firebase is what I use for something like this. Check for its existence in your Application class and download and save it to SQLite if it doesn't exist. For user specific data however, you are going to need some kind of authentication so you know which user is getting what.Firebase does this perfectly well too.
Going by the requirements (no internet, no SD card) of the OP however,I don't see any other way besides one that isn't unethical.
I used to use the path="/sdcard/myapp" to save data.
However,the compiler suggests me to use Environment.getExternalStorageDirectory() instead of hardcode "/sdcard"
My Question is:
If I do this, would the users of myapp lost their data when they updates?
AND, if true , how to prevent?
Sometimes, certain device manufacturers might use a different path for the external storage. Some devices might not have external storage at all and consider a part of their onboard storage as external storage. At other times, "/sdcard" might be mapped to another storage area as well.
So it is generally not considered wise to use "/sdcard".
On the other hand, Environment.getExternalStorageDirectory() is a system API and will always be supported by all device manufacturers. It will always correctly map to the storage area which is meant to be used as external storage for that particular device. So you can use this safely whenever you need a reference to the external storage directory.
Not all devices have sdcard. Some have build in storage like tablets. Therefore you should using the external storage directory.
Could be that it is directory mapped to /sdcard but could be some other directory/mount.
To answer your question: no, they will not loose there data.
how can I get the path for the folder where my app can save large JPG files?. getExternalStorageDirectory() works fine only when SD Card is present, but what happens when SD is removed or the harware don't have SD Card slot.
thanks
You can use the getFilesDir() method of a Context. From a context you can also use methods to get the cache directory, external cache directory, and the external files directory. An Activity is also a context, so you can use these methods from inside one.
The getFilesDir() method gives you the folder where your files will be accessible only from your application and will be always available. However, you should use the cache directory instead, when possible. This way you will avoid making the system run out of space.
EDIT:
My answer: Almost always a device will either have an SD card or built-in external storage. When it's built-in, it's still called external storage. To check whether the external storage is removable (SD card) or built-in you can use isExternalStorageRemovable() in Environment.
Basically, you shouldn't place large files on the internal memory. There is no public folder in the internal memory. If a device doesn't have external storage, it's simply not capable of doing certain things. Simple as that. So one option you have when there is no external storage is to inform the user about it and ask them to insert a card. You don't have to handle this case, let the user handle it.
The answer you asked for: Try using getDir(String name, int mode) and/or openFileOutput(String name, int mode) of a Context object, and for mode use MODE_WORLD_READABLE or MODE_WORLD_WRITEABLE. Also check Using the Internal Storage.
You are facing intended limitations of the platform that are there for the good of everyone.
You could either require external directory to exist, or you can store to the internal directory. If you choose to permit both, I suggest you store a flag in internal space to indicate that you've stored something externally, so that if external storage is not present you can take appropriate action.
As you are Saving Large JPG files, its is better to save it in external storage because Phone has very small internal memory and its all effect the performance of phone.