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).
Related
I was wondering, when we download an app which is very cool but before you install it ask to give permission for almost everything you have on the phone. Even that app can make call without your permission to your contacts. Given this scenario, how do we say an unrooted device where app data is secured from other app access? if I have an app which stores data on the device memory then would that be accessed by one of those app which takes all permission before installed?
Thanks in advance for your response.
Apps are still sandboxed, they can't access each others internal storage even with requested permissions.
I'm not sure this is the correct forum for your question though as it's not related to developing. This isn't the right site for IT support.
Edit
As mentioned in the comments - anything put somewhere insecure location such as the SD card would be readable, but the default file storage is a bit more secure.
From the android docs (http://developer.android.com/training/basics/data-storage/files.html)
Note: Your app's internal storage directory is specified by your app's
package name in a special location of the Android file system.
Technically, another app can read your internal files if you set the
file mode to be readable. However, the other app would also need to
know your app package name and file names. Other apps cannot browse your internal directories and do not have read or write access unless you explicitly set the files to be readable or writable.
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.
My code logic needs an SD card installed in the device. I have added a check for this case in the application's splash screen, but would like to inform users before they download/install this app. Is there a way to achieve this ?
Thanks !
There is no way to do this before the app installs, as the only way to limit such things is by using the <uses-feature> tag. However, that tag has no options for storage requirements. The best warning you can give is to prominently include it in your app description.
On the other hand, every device I've ever heard of an encountered has some form of external storage, be it a SD Card or inbuilt memory mounted as external storage. What you're doing by using the Splash Screen to check for the external storage is the best way to do this, as there is no other option.
There's no way to do that. Your app have to be installed to be able to check user's environment. You could try to to enforce SD card installation of your app, so if there's none Google Play might (not tested) simply not allow app installation at all, but it will not solve your problem as user will still do not know why. Solution is to clearly state in product description that SD card is mandatory. But note, that requiring SD card is risky as many devices does not have any while still offer external storage. My suggestion - just add note about storage requirements and let system deal with it.
I think it is NOT POSSIBLE . You are checking the sdcard on splash screen and prevent user for next process is the right solution or Use android:installLocation for install android application on sdcard.
Beginning with API Level 8, you can allow your application to be
installed on the external storage (for example, the device's SD card).
This is an optional feature you can declare for your application with
the android:installLocation manifest attribute.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:installLocation="preferExternal"
... >
If you declare "preferExternal", you request that your application be
installed on the external storage, but the system does not guarantee
that your application will be installed on the external storage. If
the external storage is full, the system will install it on the
internal storage. The user can also move your application between the
two locations.
When your application is installed on the external storage:
There is no effect on the application performance so long as the
external storage is mounted on the device.
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.
The unique container in which your application is stored is encrypted
with a randomly generated key that can be decrypted only by the
device that originally installed it. Thus, an application installed
on an SD card works for only one device.
The user can move your application to the internal storage through
the system settings.
Look Here for more details .
I'm writing an Android app which uses wi-fi, so I can't easily debug to emulator (no wi-fi support... ;-), so I go with my real device (a Samsung Galaxy S).
I would like to be able to read data files my app writes, to debug and test.
If I use, say:
new File(getFilesDir(), "myfile.xml");
I get my data file written to /data/data/MYPACKAGE/files/, but that directory is non accessible via adb (nor via Eclipse's DDMS).
My device is not rooted (and I'd prefer to avoid rooting it, if possible... ;-)
Where should I write my data file to?
It probably makes sense to put the files on the sdcard during development, formally you should call getExternalStorageDirectory() to find it and of course will need external storage permission.
Alternatively, you could give public access to your private files in the debug version; just don't forget to turn that off before you ship (as a certain Internet telephony company reportedly did). However, this will not make the private files browsable as the intervening directories are not, you would only be able to adb pull them via their exact path name.
A third choice would be to leave the data internal and private, but have a debug function to copy it over to the sdcard for analysis. You could even do this in a separate .apk establishing a shared user id with the first, meaning no changes at all to your application.
Simply use external storage!
You can write to your SDcard. You should use getExternalStorageDirectory() to get your SDcard's path. You will have to include the <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> in your Manifest to do that.
The answer differs depending on your API level. Review the section in the documentation on external storage to get the answer for this.
http://developer.android.com/guide/topics/data/data-storage.html#filesExternal
For a somewhat generic answer, the sdcard directory that you should be storing files in is the directory returned from getExternalStorageDirectory() (which should be the root of your sdcard or possibly internal expanded storage as with my Captivate), with subdirectories of /Android/data/your.package.name/files
Oh yes, and as another poster mentioned, don't forget the WRITE_EXTERNAL_STORAGE permission in your manifest.
Is it possible to provide application specific security to the files?. I want the file could only be accessed by the desired application and not by the others.
I assume that you have files stored on the sd-card in mind, since files stored in the internal file system is protected by default.
The only way you can protect your data from other applications is to use some sort of encryption.
Android gives each application its own user id and then the standard Linux file system access rights take care of protecting data stored on the internal file system. There is nothing you need to do to take advantage of this feature, as it is central to the whole security model in Android.
But for external storage, like the sd-card, Android is using the FAT file system to make the cards compatible with Windows. It's a good thought, but since the FAT file system lack any access rights features, everything stored on the sd-card is available to all apps. (An app that needs access to the sd-card will need to ask for permission to do so.)
(This is a huge integrity problem with Android. Sensitive information should not be stored on the sd-card, yet all photos taken are stored there. An app with access to the sd-card and the internet could easily upload all your photos to a server somewhere without you knowing it.)
you can play with the permission by declaring in your AndroidManifest.xml file. As stated in Android developer permission guide:.
For example, an application that wants to control who can start one of its activities could declare a permission for this operation as follows:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.me.app.myapp" >
<permission android:name="com.me.app.myapp.permission.DEADLY_ACTIVITY"
android:label="#string/permlab_deadlyActivity"
android:description="#string/permdesc_deadlyActivity"
android:permissionGroup="android.permission-group.COST_MONEY"
android:protectionLevel="dangerous" />
...
</manifest>
Can you check the webpage and if you are not clear we can discuss here, i have to go over before giving the exact answer.
Edit: Also check this post in so.
Yes. A simple solution is to generate a random cryptographic key using /dev/urandom when the app is installed, store the key in local storage (not on the SD card), and then encrypt the files you store on the SD card using this key. This will prevent other apps from reading the files.
Of course, one consequence of this approach is that the user will not be able to remove the SD card, put it into their PC, and copy those files onto their PC.