I have a scenario which I am not sure which type of storage to use. I have a viewpager where each pages required to save a bitmap in local device which user have drawn on the page. If I used application cache, the file in the cache will get deleted if low. If that happened, the user swiped to previous screen will be gone at some point.
If I used application directory itself, I have to manually remove all the files in that directory.
Is the second option a way to go?
You can use the application directory and on your activity/fragment destruction event where you have your ViewPager, , you can write the code to delete those files.
Use Picasso library which will manage images caching automatically,
It will restore the deleted image from the disk into the memory again when you slide back to the previous page , so you don't have to save the images on the application directory.
http://square.github.io/picasso/
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'm using Universal Image loader to retrieve a lot of images from a server and showing it inside a listview.
Now when cache is full, library remove automatically some "old" images for free space to keep new on, so when i scroll "back" for see previous images (that was deleted from cache), library download it again.
This is a very big problem if library recover picture using a 3g connection.
What i want to do is:
-recover picture from link
-save pic in cache (library already do this)
-save pic into a folder on storage too
so when library need to show again an old picutre that is not still into chache, it could recover it from storage, and not from web.
It's possible to do it?
I think the batter way is you use UrlImageViewHelper you can download from https://github.com/koush/UrlImageViewHelper
it will handle automatically store the image in cash memory it's a better way to use this lib to load image.
Yes you Can First you have to store images in specific folder while doing activity for first time later you can put small piece of code to check that requested file is present on local storage folder ..... thats will solve your Problem
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.
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.
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.