I have two questions:
1 . Does the "android:installLocation" tag in the Android manifest affect updates as well as fresh installs?
I have a published app on the market with no "android:installLocation" at all, I am thinking of adding one of the following to the manifest:
android:installLocation="auto"
OR
android:installLocation="preferExternal"
Could this affect users who simply update their app? Could their app be transferred to external storage?
My second question follows on assuming the answer is "yes".
2 . If an app is moved during an update, could the data associated with the app be affected? E.g. databases or shared preference files.
The documentation says "The .apk file is saved on the external storage, but all private user data, databases, optimized .dex files, and extracted native code are saved on the internal device memory."
But I am worried that instead of the normal update, the system may perform a full uninstall/install cycle which would wipe the data. This is unacceptable in my situation.
I'm sorry that I cannot answer this question myself through experimentation however I don't have access to any devices that have external storage. Hopefully someone has done the above and can confirm the result, one way or another.
Extra info:
minSDK = 10
targetSDK = 17
Thanks for your help:
Tim
To answer your first question. Yes. It will affect updates for existing users.
But I am worried that instead of the normal update, the system may
perform a full uninstall/install cycle which would wipe the data. This
is unacceptable in my situation.
The only time this wold happen is if you changed your signing key. It is the key that identiifies your app as unique on Google Play.
Seriously you have nothing to worry about as far as that is concerned.
Your data will stay on internal storage. This is important for security.
Problems will only really occur if you store your data on the sd card and your app on internal storage. You have to account for the fact that the data might not be available. But like I say. for your scenario. You really don't have to worry.
Related
I have an old drawing app on Android, which stores drawings (.PNG files) out on a specific folder on external storage. With Scoped Storage in Android 11, I need to find a way to save files, but I can't seem to find a solution that meets my needs. My app has its own gallery UI, like many drawing apps, so that I can control the selection/view UX.
I've tried:
MediaStore: I inserted files with MediaStore. The issue I ran into here is that I couldn't figure out a way to query just the files that my app created. Querying mediastore always returns a bunch of stuff I don't want.
Storage Access Framework. My intuition with this framework, is that I would probably spend a lot of time and potentially regret going down that road. I don't like the idea of not controlling the file selector (gallery). I also don't like relying on intents for a critical part of my app.
MANAGE_EXTERNAL_FILES. Based on the criteria defined by Google, my app wouldn't qualify to use this, though it would be great (since I could keep my old code).
Use internal file storage. I coded this up, and it's really clean, but I hesitate to roll this out, because uninstalling would mean that users lose their documents. Note that i have a Share intent, so users can "export" files one at a time.
What I want:
To write files where they aren't removed when the user uninstalls my app.
To write my files somewhere that the user can back them up one way or another.
Simplicity. I don't want to confuse existing users by changing things drastically.
Am I missing something regarding my options here? Can Mediastore effectively partition my files so that I can show them in the gallery? Does internal storage seem like the best option for me?
Just create your files in the old fashioned way in your apps sub folder in public Documents directory.
No special permissions needed.
After analyzing my Android application with a security tool, it has detected a high level vulnerability "File unsafe delete check". I have investigated about this, and it seems that the problem is that the application uses "file.delete()".
That function is considered unsafe because data could theoretically be retrieved with a tool that scans all the storage device. So, if that way of deleting is "unsafe"... what is the "safe" way to delete files in Android? (to avoid getting that "security error" that is supposedly a "high level" one). What is the proper way to delete files in Android Development?
I am getting the same security warning in 2 different applications, one made with native Java and the other one with Xamarin Forms. Thank you very much!
what is the "safe" way to delete files in Android?
There is none for the vast majority of Android devices. You use delete() on File.
That function is considered unsafe because data could theoretically be retrieved with a tool that scans all the storage device
If the Android device happens to use a classic hard drive (spinning magnetic media), you can overwrite the data before deleting it. On any sort of flash media, that will be ineffective, as the physical location where the data is written can vary with each write operation ("wear leveling").
So, this really boils down to your objective:
If you feel that the user will be harmed if this data is available to be read, store it encrypted with a user-supplied passphrase.
If you are simply trying to avoid this warning, ask the developers of this "security tool" what they are expecting you to do. Or, find a better tool.
This is not an Android specific issue.
It has to do with how file systems work, and the physical storage media it self.
When you delete a file, regardless of API, what is actually deleted is the record in the files table.
The actual data on disk or flash storage remains.
There is a method for secure deletion:
Before deleting the file, overwrite its contents with garbage or zeros several times.
But, this method only works for magnetic media such as hard disks.
Android devices use NAND flash for storage.
Because the number of writes a NAND chip can take before it fails is a lot less than that of magnetic memory, these chips usually come with a mechanism that spreads out the write commands.
What this means is that even if you try to write random data or zeros over your file, there is no guarantee the actual data will be overwritten.
The writes may go to a different sector to avoid wear.
So, on one hand, for flash storage it is enough to overwrite the file once, but on the other hand, it is impossible to do correctly at application level.
If you want to make your application secure, you must make sure to store sensitive data encrypted.
Then, even if someone tries to read the raw storage, they wouldn't be able to recover the data.
Don't store user credentials (like passwords) in regular files on Android.
Use Android accounts API and let the OS manage security.
If you still need file storage but want to protect the data, encrypt it in memory and then write to file.
As said by the other answers the first thing to consider under a theoretical point of view is if there is really a need to store any sensitive information in files to be kept on customer side
If this is really the case, encryption is the real way to guarantee proper security. Files would be protected not only against the recovery after deletion but also during their known life on the device
That said, in the case of a vulnerability assessment - i.e. a static analysis of the code - it would not be immediate to detect that you are calling for a deletion [via file.delete()] of encrypted files. Or maybe you are just calling the deletion of files with nothing to hide
In both these cases the found vulnerability would just be a false positive. Which is part of the game because you can guess that it's quite complicated for an automated tool to understand if something really "deserves" protection or not
What you can do to get rid of the vulnerability is adding the logic to empty the files before calling file.delete(). You have a sample here for this purpose. This will solve the vulnerability detection you are experiencing
4.2 Jellybean now supports multiple users. However as per the docs, all calls to all the APIs to get storage location return locations private to the current user (eg: getExternalStorageDirectory()).
I cache plenty of content from servers and store this to external storage, but with a multi user enviornment, this data will need to be duplicated for all users. This is wasting a lot of space.
Is there any way to store files to a common area for all users to make use of?
Apparently not, according to the release notes:
No matter which of these APIs you use to save data for a given user,
the data will not be accessible while running as a different user.
From your app’s point of view, each user is running on a completely
separate device.
I hope I'm wrong because I have the same problem as you.
I appreciate that it would have been a potential security hole, but if I saved files in the folder returned by getExternalStoragePublicDirectory, I would have only myself to blame.
I'm currently developing an Android game which saves data into a SQLite database. This is not really "sensitive" data, but I don't want users to be able to modify it (for obvious reasons of game balance, as it would be cheating). And it's quite easy to access and modify a SQLite db when your phone is rooted (there are plenty of applications for that in the market).
So should I even worry about that, or consider users with a rooted phone can do whatever they want including cheating and that's their choice? Or could I somehow encrypt the data I don't want them to modify, or add a MD5 checksum or something similar?
Another approach would be to abandon SQLite altogether and use some kind of binary files with game data.
Please let me know if some of you already encountered similar issues, and what are the approaches you followed, as well as the "good practices" in the Android gaming development community.
Thanks.
Root access for everybody and security are mutually exclusive.
Any application or user with root permissions can read and modify each and every file on your system, as well as all of the main memory. That doesn't leave many places to store a potential encryption key for the database.
You could hide parts of the key in the executables, configuration files etc, but everything you could come up with would be nothing more than obfuscation and security by obscurity.
If a user opts to grant root access to everybody, that's their decision, and it's not your job as an app developer to prevent any harm that might be caused.
Update:
Storing API keys in Android, is obfustication enough? is a pretty similar issue - it's about protecting API keys, but it's the same situation with regards to your options.
sqlcipher for Android might help here.
https://guardianproject.info/code/sqlcipher/
I think based on your requirement the best method is using consistency of data,
for example MD5 the score and time, then put score and time and MD5 in to the table, then every time wanting to use that row of DB check the MD5 of the score and time if the one in DB and the one which calculated are same, the row is consistent otherwise it was hacked!
You may find your happiness on Preferences Files Look here
I want to maintain data on an android device even if my app is uninstalled.
I want to maintain the data (some key) in android device even when the app is uninstalled or removed i want to retain this data when my app is re-installed in the same device.
A similar question passed by on Google Groups quite a while ago and as far as I understood, there's not a single method that will fully prevent a user from deleting the data stored. If you think about it, it actually wouldn't make sense to provide a way to fill up a device's (internal) storage without the user being able to free up that space again.
That being said, your options for storing semi-persistant data that does not get wiped out when an app is being uninstalled seem to be limited to either the SD card, some web-based location or a seperate content provider - each with its own limitations.
You might also want to read through Google's documentation on this.
You can save it to a folder and if app is reinstalled, load it from there.