I'm confused with Android emulators. Either emulator for Android KitKat or Lollipop doesn't emulate external disk writing properly.
Both of the Android versions are supposed to prevent applications to make modification on external disk (writing or modifying), even though the app has defined
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I tried in Android official emulator and also in Genymotion.
When you create a new AVD and set up an SD Card, you add a primary external storage to the emulator. Android from version 4.4 prevents the modification of secondary external storage as you can see here:
The WRITE_EXTERNAL_STORAGE permission must only grant write access to
the primary external storage on a device. Apps must not be allowed to
write to secondary external storage devices, except in their
package-specific directories as allowed by synthesized permissions.
Restricting writes in this way ensures the system can clean up files
when applications are uninstalled.
For this reason your app can write to the external storage in the emulator.
Unfortunately the default emulator cannot emulate secondary external storage.
Related
I've got an application which writes large files to an external USB drive. The directory to write these files to comes from context.getExternalMediaDirs(), so it normally ends up being something like /storage/<UUID>/Android/media/com.app.package/.
My problem is that on all devices I've tested so far, this works. However, on a Sony Bravia TV (running Android 8.0) I am able to create files in the external media directory, but if I call mkdirs() to create a directory it always returns false.
My application targets API 28, declares the READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions, and requests them both from the user at runtime.
It also seems that this problem goes away if I allow the Sony TV to "format the device as external storage", however this formats it to FAT32 which imposes file size limits that are unacceptable for my application.
Formatting the drive to NTFS via a PC allows files to be created, but not directories.
I suspect this is indicative of a bug in Sony's implementation, but I'd like some feedback from the community.
Has anyone encountered this on other devices? Is there a potential work around?
It doesn't make sense to me that I'd be allowed to create a file, but not a directory.
I want to know,
What happens to app data/database files/ etc while moving app from internal storage to SD card and vice versa?
Also I have an app which is installed in external storage. Im upgrading the app. The latest version of the app has flag to restrict install only in internal storage.
Will this latest app get installed in internal storage? Will the system automatically move the app data from external to internal or the data from previous installation is lost?
Actually this does not seem a programatic question is more an Android OS question.
First. As developer you don't choose HOW your app is installed, but since Android 2.2 you can choose WHERE:
Existing applications that were built prior to API Level 8 will always install on the internal storage and cannot be moved to the external storage
Since android API 8:
android:installLocation
internalOnly: Install the application on internal storage only. This will result in storage errors if the device runs low on internal storage.
preferExternal: The android system tries to install the application on external storage. If that is full, the application is installed on internal storage.
auto: Let the Android system decide the best install location for the application. The default system policy is to install the application on internal storage first. If the system is running low on storage, the application is then installed on external storage.
As long as you programatically don't define the installation / moving process, Android operating system will take care of moving (if possible) from internal to external and viceversa. But as programmer you must be carefull with the type of app you are developing to know if you should or not allow this option
Warning: When the user enables USB mass storage to share files with a computer or unmounts the SD card via the system settings, the external storage is unmounted from the device and all applications running on the external storage are immediately killed.
What happens: As long as you don't decide, let's explain in a simple way.
All files of the app are moved to sd card except one little pointer in the internal storage that tells the system where the app is located. (imagine if you format your SD card manually, then your phone won't know app has dissapeared) but if you unmount it phone won allow you to access.
Second Application updates will by default try to retain their install location, but application developers may change the installLocation field in an update. Installing an application with this new attribute on older devices will not break compatibility and these applications will be installed on internal storage only. That means, older data will be moved as long as the app remains with same identifier (and signature if market app).
Source / Source
ADVANTAGES / DISAVANTAGES
To keep / update your database files / configuration when upgrading your app check here and here
I get a warning from android lint:
Do not hardcode "/sdcard/"; use Environment.getExternalStorageDirectory().getPath() instead
I will fix this, but still would need to know:
On which (example) devices is this a problem, what other (example) paths can you get from this call? If this is not related to specific devices, to what is it specific or when would it happen?
Under what circumstances is there no /sdcard/ directory that my app could write to?
The app has the rights
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
what other (example) paths can you get from this call?
Partly, it is whatever the manufacturer wants.
Partly, it will vary based on the user account that is running your app. Please bear in mind that for a few years (since the release of Android 4.2), Android devices can have multiple user accounts (tablets starting with 4.2, phones starting with 5.0). Each user gets a distinct location for internal and external storage, and there is no guarantee as to what actual filesystem paths those will point to.
NEVER HARDCODE ROOT PATHS to internal or external storage. Always use an appropriate method for getting a root location, then use the appropriate File constructor to point to whatever you want within there.
The app has the rights
Since there is no WRITE_INTERNAL_STORAGE permission in Android, please remove it.
The SD card path is different for different Android manufacturers. So I make my own research with my friends' sdcard on their phone. And the result:
Sony XPERIA X10i (my phone)
Android 2.3.3 (Gingerbread)
path for phone internal memory: not available
path for sdcard: /mnt/sdcard/
Samsung Galaxy S3 Mini & Samsung Galaxy Young (given same result)
Android 4.2.2 (JellyBean)
path for phone internal memory: /storage/sdcard0/
path for sdcard: /storage/extSdCard/
OPPO (I don't remember what her phone type is)
Android 4.2.2 (JellyBean)
path for phone internal memory: /storage/sdcard0/external_sd/
path for sdcard: /sdcard0/
I wrote the result in a book. So my suggestion, never use hardcode for sdcard's path. Check here to know your sdcard's path.
The external storage may point other places,
you may define and mount other place as device external storage,
it a configure option, that why you have a Lint warning.
For example if the device support External SD card, than the external sdcard (getExteranlStorage()) will point to him (the exteranl sdcard will mount at /nmt/sdcard#/), top keep the internal sdcard free.
To make it clear
The /sdcard/ == /mnt/sdcard[0] -> internal sdcard
other sdcard will mount at /mnt/sdcard[1..]/ -> external sdcard
And also the manufacture of the device can call it as he wish (/sdcard/ is just a convention not a must have)
I have a bunch of Android devices from different vendors.
Some of them attach /mnt/sdcard to internal storage and /mnt/extsd to
external storage(Scenario 1) and others attach /mnt/sdcard to external storage(Scenario 2)
I think the second scenario is standard since the Android API provides a handle to this path. Now the problem is that in scenario 1, /mnt/extsd becomes readonly even with WRITE_EXTERNAL_STORAGE permission!
This means I can only read data from the actual external sd card and not be able to write to it.
Is there a workaround for this so I can write to the extsd folder ?
Environment.getExternalStorageState() returns path to internal SD mount point like "/mnt/sdcard"
Environment.getExternalStorageDirectory() refers to whatever the device manufacturer considered to be "external storage". On some devices, this is removable media, like an SD card. On some devices, this is a portion of on-device flash. Here, "external storage" means "the stuff accessible via USB Mass Storage mode when mounted on a host machine", at least for Android 2.x and above.
But the question is about external SD. How to get a path like "/mnt/sdcard/external_sd" (it may differ from device to device)?
Android has no concept of "external SD", aside from external storage, as described above.
If a device manufacturer has elected to have external storage be on-board flash and also has an SD card, you will need to contact that manufacturer to determine whether or not you can use the SD card (not guaranteed) and what the rules are for using it, such as what path to use for it.
On a rooted device, you can change your /system/etc/permissions/platform.xml to "fix" the permissions issue. The following worked for me:
adb pull /system/etc/permissions/platform.xml
Modify platform.xml such that media_rw is included in the WRITE_EXTERNAL_STORAGE permission like this:
<permission name="android.permission.WRITE_EXTERNAL_STORAGE" >
<group gid="sdcard_rw" />
<group gid="media_rw" />
</permission>
adb push platform.xml /system/etc/permissions/platform.xml
Restart Device
The only work around I've found so far to get write access on the device is rooting the device :(
Samsung provides a work around with a manifest entry
More details are available in the following links
http://www.xda-developers.com/android/android-3-2-code-inadvertently-preventing-write-access-to-external-storage/
and
http://www.chainfire.eu/articles/113/Is_Google_blocking_apps_writing_to_SD_cards_/
Excerpts:
It would seem that Google has a bug in their AOSP code that was
introduced around Android 3.2, which affects how the OS handles USB
Storage and can prevent write access to SD cards and USB sticks. XDA
Elite Recognized Developer, Senior Moderator, and News Writer
Chainfire sums up the issue in his blog post:
"In the past, an app would request the “WRITE_EXTERNAL_STORAGE”
permission, which would grant write access to all external storages
(user/group “sdcard_rw“). This has apparently been changed to only
grant write access to the primary external storage. A second
permission has been introduced called “WRITE_MEDIA_STORAGE“, which
would grant access to the other external storages (user/group
“media_rw“).
The problem is, a third party will not actually be granted this
permission, only system apps and apps provided by the device
manufacturer will normally be granted this permission. There are
exceptions, apparently on some devices third party apps will be
granted this permission, but according to the AOSP sources, they’re
certainly not supposed to."
I am developing an application that has the following requirement:
When the device is connected to a computer via USB, the user should be
able to use Windows Explorer to drag files into and out of the
application directory.
The application will consume some of these files and produces others
which should be able to be copied back to the computer.
The target device does not have an external storage device (for
example an SD Card).
The directories that the files will be stored in should be accessible
whilst the application is running.
I've looked into the data storage page in the android documentation, but none of the methods stated there seem to do what I require.
Alternatively, is there a way to select the computer when the application is running and 'send' files via USB to the computer? How about for 'receiving' files?
What is the best way to fulfill this requirement?
When the device is connected to a computer via USB, the user should be able to use Windows Explorer to drag files into and out of the application directory.
If "the application directory" refers to a spot on external storage, this is possible.
The application will consume some of these files and produces others which should be able to be copied back to the computer.
If this is supposed to happen simultaneously, the device must be running Android 3.x or higher. Android 1.x and 2.x did not support simultaneous access to external storage.
The target device does not have an external storage device (for example an SD Card).
It needs to have something designated as "external storage". That does not have to be removable storage. On Android 3.x and 4.x, it is usually just a part of on-board flash that was designated to be accessible as external storage. In Android terms, "external storage" means "can be accessed by a host computer using USB and by all applications on the device as well".
The directories that the files will be stored in should be accessible whilst the application is running.
Again, this requires Android 3.x or higher. If this is a custom device, that most likely means you are going to need to use the recently-released Android 4.0 source code.
Alternatively, is there a way to select the computer when the application is running and 'send' files via USB to the computer? How about for 'receiving' files?
No and no, respectively.
What your going to want to do is use Environment.getExternalStorageDirectory. Even if there is no sd card, most android devices partition a part of the on board memory to be used as external storage.