Ok. trying to understand how Android handles downloaded images. So a few questions:
1) Is it possible to download and save an image to the getCacheDir()?
2) Can this image be viewed from the cache directory?
3) If yes to 2), what is the action that will clear up the cache?
4) Must I download the image to somewhere before I can use the ACTION_VIEW intent to view the image?
5) If it is in the cache, how do I "save" it? Meaning put it in a more permanent directory and not the cache.
In summary, I'm trying to achieve user downloads an image from somwhere, sees it in the image viewer and chooses to save it or not.
Currently my understanding on this is I have to download and save it regardless before viewing it on an imageviewer with no choice to save it or not.
If I am wrong what is the approcah to achieve download, view, choose to save?
Ok, from your questions..
1) Yes
2) Yes (I think only for your application.. May be)
3) You have to do it manually, using delete files form getCacheDir() or either by navigate
to settings/Manage application clear cache data option..
4) This never tried, but I think you have to do it, (Bco'z I think cacheDir is private for your application)
5) Using File operation copy to another internal / external storage location...
Note:
getCacheDir ()
Returns the absolute path to the application specific cache directory on the filesystem.
These files will be ones that get deleted first when the device runs low on storage. There is no guarantee when these files will be deleted. Note: you should not rely on the system deleting these files for you; you should always have a reasonable maximum, such as 1 MB, for the amount of space you consume with cache files, and prune those files when exceeding that space.
Related
My Android app creates a folder on the users device's external storage on launch:
File images = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + File.separator + "rapical" + File.separator);
images.mkdirs();
I have around 16 image icons (.png) that I would like to place in this folder the first time the user opens the app.
What is the best practice to do this? Should I place them in the drawable folder initially and then copy them over to the newly created images folder? Not sure what approach to take!
There are two separate issues here:
What to do with images that the user adds to your app?
What to do with your starter images, for your default foods?
Using external storage for the user-added images has some implications:
Your app can survive that image no longer existing, since the user, or other apps, can delete that file at any point
Your user does not mind that the image will get picked up by other apps, such as photo galleries
Unless you specifically want these images to be user-manipulable outside of your app, I suggest that you use internal storage for the "re-sized, compressed and stored" user-supplied images. The original image might be on external storage (I assume that you are using ACTION_GET_CONTENT and/or ACTION_OPEN_DOCUMENT to get the image), but your modified copy would be private to your app.
I sincerely hope that you are using an image-loading library, like Picasso, for loading these images, since they will handle things like background threads and ListView/RecyclerView image recycling and stuff for you.
In that case, what you store in the SQLite database for your default foods needs to be something that the image-loading library can interpret, to bring in the image that you want.
In that case, I would suggest using assets/ to ship the images and file:///android_asset/... values in the database. file:///android_asset/ points to what amounts to assets/ in your project, so if you have assets/chicken_pad_thai.jpg in the project, Picasso (and any decent image-loading library) would be able to interpret file:///android_asset/chicken_pad_thai.jpg) and load the image.
This saves you from making duplicate copies of the images, saving the user disk space and time on first launch. It also means that if you replace the images in your app (e.g., you get a better photo representing chicken pad thai), the user will start seeing the updated image, without you having to do some extra work to realize that you shipped a new image and have to copy that image out to a file somewhere.
Now, suppose that you really do want the user-supplied images to be on external storage. In that case:
Probably rather than the directory that you chose, I would go with getExternalFilesDir() (a method on Context), as on API Level 19+, you do not need WRITE_EXTERNAL_STORAGE as a permission
If you want the user to be able to manipulate the images of the default foods, then copy those out to that location on first run
I am reading through the Android developer docs on saving data and they mention that when saving a file to internal storage you can use either getFilesDir() or getCacheDir(). When would it be appropriate to save to the cache directory, and what type of data is best saved here?
The getCacheDir() should only be used for data that is not essential for the running of the app. In other words, you can store data which if unavailable, can be fetched from the server. The reason for this is that the system may delete all the files in the cache dir to reclaim storage space.
http://developer.android.com/training/basics/data-storage/files.html
Use the cache directory to save temporary files. For example, if you're writing a social app (like instagram) and during runtime the app loads user's pictures, you can store those pictures on the cache directory, so if the user resumes the app while offline, he will still be able to see the last pics.
Make sure to delete each file once it is no longer needed and implement a reasonable size limit for the amount of memory you use at any given time, such as 1MB.
I have to do some stuff. I'm downloading images using web-service, after successful download of each image, I'm using "AES" encryption algorithm to encrypt that images. I'have done encryption successfully. But whenever I'm going to open Gallery of device, I am able to seen that downloaded images encrypted by me. I don't want that. I wanna secure that images that can prevent access from Gallery.
I understood the whole process here.When I am storing each image after download Gallery capture that image and store into its cache so before my encryption process may be Gallery populate that images.
-> My Encryption process : Download Image - > Store into SDCARD - > Encrypting Image - > Delete the real Image
But this is not deleting from Gallery also.
So in short I wanna secure that images that can prevent access from Gallery. Let me know your best suggestion about my process is right or wrong? May I have to do a few changes on it? or have you nice idea instead of my process ?
Thanks for your best suggestions.
You must add an empty file to your images folder called .nomedia. This will prevent the MediaScanner from indexes images in that folder.
However, there is a bug on ICS that makes this slightly harder. On ICS, your folder must have the .nomedia present before you add images to it, or else the images will be indexed.
Another, slightly less compliant option is to begin your folder name with a dot (something like .foldername). As Android is UNIX based, this will make it a hidden folder, and hence not have the MediaScanner scan it.
I have got a proper solution. That will also work with higher versions.
You can keep it private with your application's private folder using following directory :
String mDirectory = getPackageManager().getPackageInfo("com.example.myapp", 0).applicationInfo.dataDir;
You can store your private data into this package. It will prevent access as well as prevent indexing from Gallery. So you don't need to worry about it's encryption process also :) . May be this folder will not provide much space. But atleast it will be help us.
Sounds like below solution might work for all versions -
(Storing videos, images and audio files that can not be accesses by others)
For this you have to store your data in External Storage with creating a folder name starting with the .(dot) then this folder is hidden from the FileExplorer.In this folder you need to create a .nomedia file and place your Images and video then images and videos are can not be visible to User in the Gallery.nomedia folder files can not be read by the gallery.
I want to do this. my app has many screens and in each of them, on the top, I display an imageView as a logo. So I have 20 screens and that means (20*3) images in my drawable which makes my app be many Mb's. Because this image is static and never changes I want to do this: Getting it from the web (I know how to do it, I am not asking this) only for the first time this screen is ever launched, then this image be stored somewhere in user's device and then use that path as a source. (I mean not download it again, because it will be annoying for the user waiting every time). So is it possible? Will it make my app go slower (not the first time, but the rest) because I am retrieving data from SD?
Yes, you can do this fairly easily. You also do not have to store the data on the SD card necessarily. You can store the image in the internal storage.
Basically, set up a cache directory. When you need the image, check the cache directory, and if the file is not there, download it over http and store the file in the cache directory.
It will change how you get the resource (e.g., you won't be able to use R.drawable.imagename), but you can just load the drawable programmatically.
Okay so I've noticed that even though I use the correct path for the cache folder Android doesn't register the content in the folder so the user can't delete the cache content by going into settings -> programs -> administrate -> select program -> clear cache. The folder is deleted properly on uninstal but not if the user actively try to clear the cache. This is not a major issue but its still a minor problem because the user don't get a proper idea of how much space the application uses at the SD card.
Is there anything I as developer can do to update these values or am I doing something wrong somewhere else?
From the docs:
Saving cache files
If you'd like to cache some data, rather than store it persistently,
you should use getCacheDir() to open a File that represents the
internal directory where your application should save temporary cache
files.
When the device is low on internal storage space, Android may delete
these cache files to recover space. However, you should not rely on
the system to clean up these files for you. You should always maintain
the cache files yourself and stay within a reasonable limit of space
consumed, such as 1MB. When the user uninstalls your application,
these files are removed.
I guess you should handle the removal of yourself. If you want to remove the content if the user cleans the app data create a sharedPreference and clean the cache when the app starts and that preference is not defined.