I have to store a lot of images that have to be downloaded from the web server. The size of the images might be 80Mb. So I want a guidance where to store them, whether in internal or external storage. Both create some problems for me. Internal storage is as every one knows is very limited but the problem with external storage is that images can be accessed by user. I don't wanna my application images to be exposed to user and changed or deleted. So is there any alternative or is there any technique to safely put data into external storage?
Unfortunately no, external storage has FAT file system, which does not support access restriction. And you simply must not store such large chunks of data in internal memory (or otherwise users will not like you, to put it mildly).
So the only way to go, is to use external storage. If you need some protection, then you may either encrypt/decrypt data. Or just obfuscate data, like changing file extensions, or adding 10 bytes at the beginning of each file. Obfuscation is more efficient resource-wise, but much less protected. Though encryption key can still be extracted from your application, so both of this approaches have their flows.
I would advice to store them in the external storage. If you don't want the user to be able to read it, protect it with an encryption. I think it's a bad idea to impose large data to the user. If the user wants to remove it, you shouldn't want to prevent it. Perhaps consider the possibility of re-download the pictures from the web if it has been deleted.
Use encryption for file content:
i found nice and lightweight sample code on http://www.androidsnippets.com/encryptdecrypt-strings
I recommend saving to external. Preventing the user from deleting his data is not recommended. Also user can format the sdcard to delete it. so you cannot stop the user. You can hide it from him. Just prefix a dot to the folder name to make it hidden.
If you are using Android 2.3, OBB is your choice.
http://developer.android.com/reference/android/os/storage/StorageManager.html
OBBs contain a filesystem that maybe be encrypted on disk and mounted on-demand from an application. OBBs are a good way of providing large amounts of binary assets without packaging them into APKs as they may be multiple gigabytes in size. However, due to their size, they're most likely stored in a shared storage pool accessible from all programs. The system does not guarantee the security of the OBB file itself: if any program modifies the OBB, there is no guarantee that a read from that OBB will produce the expected output.
Related
What is OBB(Opaque Binary Blob) in Android develop site?
Related
I would like to make video/audio/pdf files hidden inside Internal/External storage in Android. Our requirement is making the files visible only in our Android application but not any other apps like Es File Explorer and not even when connecting the device to Desktop/Laptop.
I have googled it a lot and found the following ways but with few disadvantages.
Creating folder/file with prefix "." - It has the disadvantages that we cannot prevent it to be visible in some File explorer apps with the option "Show hidden files" and we cannot prevent the files from getting displayed when connected to Desktop/Laptop.
Storing the files inside App specific folder - Storing large memory files in the path returned by android.Content.Context.getFilesDir() will lead to the poor performance of the device and most of the devices will not have large internal memory size.
How to overcome the disadvantages and make our application to meet the requirement ?
Well hiding files to user accessable storage is not recommend without encryption.
Youtube,Gaana, saavan, hotstar all these media related apps used to encrypt their data and stores in data location which is visible to users but they can't share or use in other ways as the data is encrypted.
You can use CipherOutputStream and CipherInputStream for encryption and decryption of file in android.
There are two ways through which you can achieve your goal
Download a file and encrypt it, when you want to play that file decry-pt it in a temporary file and play it which I not recommend as it can increase the chances of data grabbing.
if you want to play encrypted file on the fly (not decrypting it in a temp file) then you can use Libmedia library. It streams encrypted file on local host and play it from there
Original answer : https://stackoverflow.com/a/35426842/9565955
Your first proposed solution won't work since it would make files accessible to anyone.
Second solution is perfect if you have limited file sizes. In case of large memory files it is always better to store them in External storage. But this would make it publicly accessible. To prevent that you can encrypt the files and store them in external storage.
Some suggestions while doing so :
Randomise the filenames so won't be easy to guess.
Refer this for simple file encryption.
Do not use static key for encryption as it can be reverse
engineered. Use different key for every file.
Do not store the original key in db/shared preference. Store the
hash of it instead.
You can even hash the key n times and then store in db. This would
make procedure a bit slow but provides more security as one has to
know the exact value of n to get the original key.
For added security you can even consider using Android's KeyStore to
derive the IV.
The question is how can I store a big amount of data (several hundreds of Mb and more) and simultaneously keep it available only for my application?
Internal storage as I found out is limited and its size depends on device model. Could it be sufficient for large data volume storage? Could I store 500Mb and more in internal storage?
The alternative is to use external storage. As I know, external storage doesn't limit an application and it can use the whole external storage. However, data become available for user and other applications and it is unacceptable in my case. Is there a way to make data, which stores in external storage, private as if it stores in internal one?
Internal storage as I found out is limited and its size depends on device model
Only on Android 1.x/2.x. On the vast majority of Android 3.0+ devices, internal and external storage are on the same partition and therefore have the same amount of space.
Could I store 500Mb and more in internal storage?
On Android 3.0+, probably. The user may not have 500MB free, but that's not a limitation of internal storage, but just a limitation of "storage" in general.
Is there a way to make data, which stores in external storage, private as if it stores in internal one?
Not really. You cannot prevent the user or other apps from deleting those files, for example. You can use Facebook's Conceal library to encrypt the files on external storage, with a generated encryption key stored on internal storage, to prevent users or other apps from changing the contents of the files (other than by simply corrupting them). However, again, this would only be relevant if you are still supporting Android 1.x/2.x; on Android 3.0+, just use internal storage.
considering the constrains you up you really up with two possible approaches.
use the internal storage but make sure to keep check on free memory and whenever the device can't handle it's a matter of letting your users know their device can't run your app.
use the external memory and build a nice encryption on it so even if someone else get the files, the actual data on them will be meaningless without the proper decryption mechanism.
which option to choose is a product decision.
You can use getExternalFilesDir() to restrict the media store content provider from reading your app specific files from an external storage. But I think any other application with the same permission of READ_EXTERNAL_STORAGE can access the files. Only way is to use the internal memory.
Im not sure what type of files you wish to store. If the files are less in number you can give a thought of using database, although this shall violate ACID principle. Alternatively you can think about restricting by using content providers.
My app needs to download and save a big number of images and mp3s.
These will make sense only for the app, only my app will be able to use them in an meaningful way. The user or other apps won't know what to do with them.
Where should I keep them, in external or internal storage?
I'd like to keep them in internal memory because they are only meaningful to the app, and they will be wiped out when the app is deleted.
However, for old devices the internal memory is very limited, and I think it would be a hassle for the user to keep these files here.
So, I was thinking about external memory, but I don't like the idea of keeping those files there after the app has been deleted.
What would be the best practice for this?
Thank you.
Use the path returned by 'getExternalFilesDir(String type)'
From the documentation:
"Returns the absolute path to the directory on the primary external filesystem (that is somewhere on Environment.getExternalStorageDirectory()) where the application can place persistent files it owns. 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:
External files are not always available: they will disappear if the user mounts the external storage on a computer or removes it. See the APIs on Environment for information in the storage state.There is no security enforced with these files. For example, any application holding WRITE_EXTERNAL_STORAGE can write to these files."
For further details: http://developer.android.com/reference/android/content/Context.html#getExternalFilesDir(java.lang.String)
So yes, you can use external storage and have the files deleted when the app is uninstalled (as long as you are happy with the lack of security).
This is pretty close to an opinion question and will likely get closed.
Short answer: Use external storage. Users will get mad if you're filling up their internal storage with tons of files.
Recommendation: Give the users a toggle option to store it wherever they want!
The idea is that.
My application allows user to listen to music and watch videos from the social network. User can save these files in cache to be able to play them offline. This data is saved to SD-card and can be accessed by file managers e t.c.
I want to limit access to these files to other application. The most obvious solution is data encryption.
Can you please recommend me some libraries or frameworks for quick file encryption/decription? It is very desirable to encrypt files "on the fly" during the are loading.
Would this procedure be too slow and resource intensive?
May be there exist some other ways - protected folder in the SD filesystem or something like that?
Yes there is a more standard way to do this.
By using openFileInput on your Context and setting the MODE_PRIVATE flag, you will be able to create files and even folders within your application. Also, these resources will be completely private to your application.
EDIT :
Most of the time, these files will be stored in /data/data/<app_package_name>/files. That is, on the phone memory most of the time, although this is implementation specific.
Regarding the comment of #Carlos mentionning file spamming, yeah you can flood the NAND with multiple files, but /data will be in most cases mounted on a dedicated partition. So you'll be hitting the virtual size of the partition at some point. Please look at this post, the accepted answer gives more details about this.
In fewer words, this is implementation specific (depends on the manufacturer).
Your only option would be to use Encryption, if you want to keep using the external storage. SpongyCastle can help with that. It is an android version of the BouncyCastle APIs.
Apart from that, you could move your files to the internal storage, which may not be feasible in your case as media files tend to be big, and internal storage on most devices is very limited. Even if you do move them to internal storage, any rooted user can access them (or any app with root privileges).
Protecting the folder isn't an option, as anything on the external storage is available to any app with permission to access the external storage. There is nothing you can do about that.
I am downloading files from a remote server to be saved for use on an android device. These files are mostly images and audio but I would like it so that a user cannot access this data using methods other than the app.
The issue is that these files could be large and that's why I use external storage. The problem here is that users can access the data stored on external storage by hooking the phone up to a computer.
Apart from using internal storage, do I have any options to secure the files written to disk?
If I do have to use internal storage, are there any other disadvantages other than the fact that some users might have a small amount of internal storage?
Thanks for your time! Any help will be much appreciated! :)
EDIT 1 :
The data being downloaded is paid content (via In App Billing). This is why I'm concerned about restricting access.
EDIT 2 :
I am already adding a "." before the folder I'm saving my data to. I'm more concerned about 'power' users who would know to look in hidden folders.
Seems like you are populating app's cache from web. It is always recommended to use external storage for such purposes because some users may not have enough internal memory to accommodate this.
Since you downloading includes images and audios, i wouldn't suggest you to use encryption/decryption as it will slow down the app's processing. So there's nothing much you can do to secure your data if you want to put on external memory and skip its encryption.
I personally don't think any harm/disadvantage to leave such data as it is (not encrypted). But if you have some of the files important, perhaps you may perform encryption on those particular files only.