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.
Related
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!
Can someone explain the permission of the app specific folder /Android/data/< package_name>/files/ as described here http://developer.android.com/guide/topics/data/data-storage.html#filesExternal
It is not clear when it is truly private to the app and when it is world-readable. Is it the case that when the USB mass storage is enabled the files in the external storage, including the app specific folder, are world readable?
I tried using a file manager app (ASTRO file manager) and I am able to see/open files in the app specific folders on the sdcard and this is irrespective of the setting Protect USB storage in the developer options under Settings. I am using Google Nexus 4 running 4.3 version of android.
So it's confusing when this folder /Android/data/appname/files/ is really private to the app.
thanks.
Let's talk some Android security, shall we?
You can not access an application's home directory, on an unrooted device. This would have been a MAJOR security hole.
Creating WORLD_READABLE files is deprecated, and judging by the text in the API, this is one of those cases where "decperacted" means "deprecated".
So - you wanna pass data between applications?
a. You can leave a file in a set place for the 2nd app to fetch. This is a bad idea though. It litters the user's storage space, there is NO SECURITY at all, the 2nd app is not notified about pending updates and you can not easily determine the state of affairs. I suggest you stear away from this approach. Even though, I've included some elaboration in the UPDATE section below.
b. For simple, small chunks of data, I suggest you go the Intent/BroadcastReceiver approach.
c. You can go the ContentProvider approach is you wanna do things the right way.
d. You can go the Intent/Service approach.
e. For true IPC - use AIDL.
UPDATE:
I suggest you begin by reading Google's article throughly. This article clearly deals with the case of transfering large files between apps. Also, as you can clearly witness, the terminology is quite confusing.
So let's review your question in light of Google's article on the subject.
Internal storage is private to your application and can not be accessed by other apps. You can access its directory structure via Context.html#getFilesDir().
Please mind that:
Files written here are deleted when the user uninstalls the app.
External storage can be physically internal (built in storage) or external (removable SD card). There is no security model here, files are visible and accessible to the world. You can access the external directory structure via Context.html#getExternalFilesDir(). Please mind that:
This direcory might become unaccessible (when the user connects the device to a computer or when he removes the SD card).
There might be a seperate directory per device user.
Files remain even when the user uninstalls the app.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Indra's point is correct. for reading EXTERNAL_STORAGE you need to put this uses-permission
try this permission
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
As far as I knew, the files on the external storage are public, but as Indra points out you do need the permission if you want your app to read them:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I think it is only the internal storage files that are private, requiring ROOT access to be read from outside your app (or an app signed with the same key as your app).
We are trying to create an app which will download eBook from server and store it locally on sdcard. We tried to DRM eBooks, after we download an eBook the DRM will take care of the security of the eBook. But later due to some reasons we left the DRM concept. Now I want to know whether we can store the eBook securely in the sdcard. The user cannot do any operations in the file other than viewing. Can we store the file in some other location where the user cannot view the file at all. In iOS we can download the file inside the Bundle itself, but for android???. We tried storing the pdf as a BLOB file in DB and tried to read it from there, in that case also we need to write the file and then read it. I am really confused on this Issue, can someone suggest me a good approach on how to proceed further. Any help would be really appreciable.
Personally I've avoid the SDcard given it's pretty much open to all apps, as #commonsWare mentions having it internal storage offers the Android app sandbox security.
Have you considered IOCipher from the excellent guys at the guardian project it's build on SQLCipher and it allow you to create a encrypted virtual disk. The part I love about it is that it's a clone of the java.io libraries so you should only have minimal code changes.
Files stored on the external storage are easy to read by other applications or from user's PC. You might need to encrypt your files if you don't want anybody else to get access. Well encrypted files can be places anywhere in the system without any risks of being read.
Storing files on the internal storage in your case does not sound good, because there are still too many devices out there with the limited amount of internal storage, where every megabyte counts.
Can we store the file in some other location where the user cannot view the file at all.
Not on external storage. You can put the book on internal storage, in which case only rooted device users would have access to it outside of your app.
i) keep the files encrypted which are important to you.
ii) decrypt the files and move to the internal storage during runtime.
iii) Access your files only from internal storage.
Following these things will keep your file and method calling safe as they are accessible only to internal storage.
Example:(access moved assets files from internal storage )
file:///android_asset/ => file:///data/data/com.test.exmple/files/"
You can also try tools like quixxi that do this for you transparently.
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 have a project consisting of four programs for different platforms; all of them use the same XML-based settings file format. I want to be able to manually modify/overwrite it outside of the application. On Windows, Windows Mobile and Linux I'm using "user.home", but on Android that alias isn't implemented. I'm thinking about simply putting it in the Downloads directory, however, that doesn't feel right.
I can't be the only one, who needs that kind of functionality. Or this isn't Android-way? Any suggestions are appreciated.
EDIT: I'm OK with the settings file not being available all the time (i.e. SD-card removed), it's used only on the start-up of the application.
Store it in getExternalFilesDir(). This would work only if the device has an external storage. The user would be able to access it.
However, take note of the following from the docs:
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.
According to Android data storage documentation you have 5 options:
Shared Preferences. By default this will use file /data/data/your.package.name/preferences/user_preferences.xml
Internal Storage. Here you can use something like /data/data/you.package.name/user.home
External Storage. Similar to internal storage /mnt/sdcard/Android/data/your.package.name/user.home, but if user removes memory card file will be inaccessible.
SQLiteDatabase. You can store the whole user.home file in a database blob.
NetworkConnection. Store user's config in a cloud.