I actually want to access the files on android system. I manage to read the files and directories in the external storage of android.
My questions are :
How can I access the directories and files of the internal storage(Specially videos, pics all of the applications which runs in android).
Where are stored the data of each application which installed in internal storage?
Is it possible to transfer data which exists in the internal storage (from internal memory to external storage?
I read that external storage is world-readable? what does that mean?(if a create an application then this application can access all the files that installed in external storage?)
By default, an app cannot access data stored by another app. Permissions are applied to internal storage that make data written by an application not accessible outside of that application (your app cannot read anything written by another app). This can be changed, where an application can specify different permissions for ITS OWN data; basically, an app can allow others to read its data. However, if an app does not specifically set its permissions to allow this, other apps cannot access its data. This is a fundamental principle of the Android security/isolation model and is done at the Linux/kernel level, as each app runs under its own Linux UID and permissions are set within the filesystem only allowing that UID access to the app's directory structure (group and world permissions are set to 0 by default).
This all goes out the window if you have access to root on the device (rooted phone and your app runs with root permissions), but we should consider that out-of-scope for your question.
External (SD card) storage is different in that it is considered free-for-all and permissions are not applied there (this is originally due to the filesystem typically used in SD not supporting permissions). Any app can usually read anything written to the SD card by any other app, unless the original app does something to protect it (encrypt, etc).
This is all explained in great detail in Application Security for the Android Platform, just published by O'Reilly.
You have to write FileProvider to access the app specific files with another app.
Related
I was wondering, what is a good way, to prevent my app files from being read/ write to other apps, in non-root devices
Currently, I'm storing my data (images, audio, ...) in getExternalFilesDir
But, some of my users complain that, they are still able to see images in 3rd party gallery app.
I am not sure whether they are using root phone. So far, I cannot access my app getExternalFilesDir from Google Photo app.
Based on https://developer.android.com/training/data-storage, it seems that only getFilesDir will prevent other apps from accessing the files.
But, is it appropriate for an app to store user data file in getFilesDir? (My app is a note taking app which needs to store user attachment images, audio, ...)
From discussion of Android getExternalFilesDir vs getFilesDir() for big files , it seems like getFilesDir is not designed to store user data files?
I was wondering, what is a good way, to prevent my app files from being read/ write to other apps, in non-root devices
Store your data in internal storage (mostly getFilesDir() and getCacheDir()).
Currently, I'm storing my data (images, audio, ...) in getExternalFilesDir
The only reason to use that location is if you want the user to be able to use your content from outside of your app, whether via other apps or via an attached desktop computer.
In the long term, getExternalFilesDir() and getExternalCacheDir() will be off-limits to other apps — you will start seeing this on Android 11 in particular. However, it will take years for Android 11+ to dominate the Android device ecosystem.
But, some of my users complain that, they are still able to see images in 3rd party gallery app.
Such apps might be augmenting the MediaStore by scanning external storage for images.
But, is it appropriate for an app to store user data file in getFilesDir?
Yes. Everything should be in internal storage, unless there is a specific need for the user to be able to use the content outside of your app. Internal storage should be your default choice, with external storage or the Storage Access Framework being explicit choices made to go against that default.
From discussion of Android getExternalFilesDir vs getFilesDir() for big files , it seems like getFilesDir is not designed to store user data files?
Um, no.
A decade ago, internal storage and external storage were separate partitions, in part because external storage typically was implemented as removable storage (micro SD card). Since Android 3.0 in 2011, though, internal storage and external storage are almost always separate directories on the same partition. The primary distinction between the two is what processes could access the files, with your portion of internal storage being locked down to just your app, and external storage being accessible by anything.
I need to download files on my mobile device and make them accessible for other apps (using Android and iOS).
I managed to download a file to the SD card (cordova.file.externalDataDirectory), but this only exists on Android and even then I cannot rely on every device having an SD card.
When I download to the device storage (cordova.file.dataDirectory), the file is private to my app and therefore not accessible for other apps. The file can be opened in the InAppBrowser, but I would prefer to use the respective default app.
Is there a way to get a path to a directory publicly available on all devices?
The paths returned by the solution suggested in https://stackoverflow.com/a/21375812/3432305 are both private on Android...
EDIT:
I think I should describe my use case so it's clearer what I'm trying to achieve: I want to open files from my in app chat using the respective default app (pdf viewer, image viewer etc.). Because the Cordova File Opener plugin only accepts files from the local file system, I need to save them first. But they don't necessarily need to be accessible from outside my app afterwards...
On Android, external storage directories always exist; if the device doesn't have a physical SD card, Android will emulate it. see getExternalStorageDirectory :
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.
Therefore cordova.file.externalDataDirectory will always resolve. However, for sharing data between apps, you probably want to use cordova.file.externalRootDirectory - External storage (SD card) root. See cordova-plugin-file.
This way you can store files in a place that's easier to access from another app e.g. /sdcard/my_shared_data/
On iOS, it's more difficult to share files because apps are intentionally isolated from each other due to security policy, as Apple's Inter-App Communication Guide says:
Apps communicate only indirectly with other apps on a device
You best bet on iOS is to share the data by synching it via iCloud. See the section Configuring a Common Ubiquity Container for Multiple Apps in iCloud Design Guide, which says:
... perhaps you provide two apps that interoperate and need
access to each other’s files. In both of these examples, you obtain
the needed access by specifying a common ubiquity container and then
requesting access to it from each app.
Is it possible to read/write/delete the data present in files or folders created by other applications? I am 99% sure that Android OS does not give such permission but to be 100% sure, I want to know this. The whole context is that if I download an Android app from an external source, what kind of security threats I may have?
Is it possible to read/write/delete the data present in files or folders created by other applications?
That depends on where the "files or folders created by other applications" reside.
Files written by an app to its portion of internal storage are not accessible by third-party apps in general. Users who root their devices can arrange to access those files.
Files written by an app to external storage are accessible by other apps and by the user, though the apps will need READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE permissions.
Files written by an app to its portion of removable storage, on Android 4.4+, are not accessible by third-party apps in general. Users will have access to these files, if not through Android apps, then by moving the media to some other hardware (e.g., notebook PC).
Files written by an app to removable media prior to Android 4.4 -- through undocumented and unsupported means -- are accessible by other apps, in addition to being accessible by the user.
When using Eclipse file explorer to navigate my android directories, I saw mnt/sdcard and mnt/sdcard2, see below image:
When callingEnvironment.getExternalStorageDirectory() it returns mnt/sdcard, so I think the mnt/sdcad is the external storage , and mnt/sdcard2 is my actual SD card, is that true? And how can I use code to access files under mnt/sdcard2 ?
P.S.
It seems that I can access the external sd card directly:
File extStorageDir = Environment.getExternalStorageDirectory();
String parent = extStorageDir.getParent();
File extSdCardDir = new File(parent+"/sdcard2");
File file = new File(extSdCardDir, "DemoFile.jpg");
But I wonder the extra sd card will change name in other cases.
You are correct, getExternalStorage will return your built-in external storage. Unfortunately, as of Jelly Bean applications are no longer able to utilize the SD card if the device also has built-in storage as well as an SD card. You can try working around it through shell commands or hardcoding paths, but without root there is no reliable way to access it anymore.
This was just recently added the Android CTS, which all OEMs must comply with in order to use the Play store.
Compatibility Program Overview | Android Developers
Section 9.5 (pg. 34) of Android 4.3 Compatibility Definition
Device implementations that include multiple external storage paths
MUST NOT allow Android applications to write to the secondary external
storage.
Storage Options | Android Developers
It's possible that a device using a partition of the internal storage
for the external storage may also offer an SD card slot. In this case,
the SD card is not part of the external storage and your app cannot
access it (the extra storage is intended only for user-provided media
that the system scans).
Android 4.2 APIs | Android Developers
Saving data in a multi-user environment
Whenever your app saves user preferences, creates a database, or
writes a file to the user’s internal or external storage space, that
data is accessible only while running as that user.
To be certain that your app behaves properly in a multi-user
environment, do not refer to your internal app directory or external
storage location using hard-coded paths and instead always use the
appropriate APIs:
For access to internal storage, use getFilesDir(), getCacheDir(), or openFileOutput().
For access to external storage, use getExternalFilesDir() or getExternalStoragePublicDirectory().
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.
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 .