In an Android app, I am storing files on a SD card in the device.
Occasionally the user also need to export data to a USB disk that will be attached for the occasion.
I am using Context.getExternalFilesDirs() to locate the SD card and I am using Environment.isExternalStorageRemovable() to distinguish the internal storage from the SD card.
My problem is that the USB disk, when attached, show up the exact same way as the SD card. It is included in the list returned by Context.getExternalFilesDirs() and is also "removable" according to Environment.isExternalStorageRemovable() and the path does not reveal anything.
Is there a way to distinguish an attached SD card from an attached USB drive?
Related
My Phonegap application deals with some large files, so I want to store them on the user's external SD card if possible. The org.apache.cordova.file plugin says that you can call
window.resolveLocalFileSystemURL(
cordova.file.externalDataDirectory, ...)
which it describes as "where to put app-specific data files on external storage."
This resolves to file:///mnt/sdcard/Android/data/my.app.id and that's where my files get saved. Unfortunately, that's not "external" storage; a number of phones I have tested appear to have an "internal" SD card (built into the phone, limited capacity) and an external SD card (the pluggable slot).
With the Sony Xperia st23i, for example, the external SD card gets mounted at /mnt/ext_sdcard. Judging by pages like this one it's very device-specific where the physical external SD card appears on the system.
In this JIRA issue it was suggested that the file-system-roots plugin should provide a way to get at file:/storage/extSdCard, but the file-system-roots plugin is now supposed to be folded into org.apache.cordova.file; however, its documentation does not appear to have an option for the actual external SD card. ("External storage (SD card) " just means "not the phone's internal storage" rather than the pluggable slot.)
Is there a sensible, portable way to address the user-supplied microSD (if there is one) card from phonegap?
I'm using CyanogenMod 10.2.1 on an Xperia ZR. This device has an emulated SD card and a removable SD card. The stock camera app has an option to store images in the emulated or the removable SD card (see screenshots below).
I'm writing a camera app and I want to do the same thing, so I looked at the code of the camera app in Android's source and in CyanogenMod's source. The first uses Environment.getExternalStoragePublicDirectory() and the second Environment.getExternalStorageDirectory(). Neither of those seem to be dynamic, so where does the setting item come from?
Here are some screenshots showing the storage option:
All in all, I want to find out whether those apps use the techniques in Find an external SD card location to access secondary storage.
Device 1
/sdcard attached to real sd card
/mnt/sdcard attached to real sd card
Device 2
/sdcard attached to internal memory
/mnt/sdcard attached to internal memory
/external_storage(something like this) to real sd card
.
.
/sdcard and /mnt/sdcard seems to have the same location. Always ?
My question is, how do I know if they attached to same directory ?
I tried new File(path1).equals(new File(path2)); but it return false. Only way I see is, create a hidden file with unique id and check the existence in both paths.
PS : I'm aware of Environment.getExternalStorageDirectory(). But I need these paths for some specific purpose.
/sdcard and /mnt/sdcard are not always the same. There are many paths that can exsist such as:
/emmc
/mnt/sdcard/external_sd
/mnt/external_sd
/sdcard/sd
/mnt/sdcard/bpemmctest
/mnt/sdcard/_ExternalSD
/mnt/sdcard-ext
/mnt/Removable/MicroSD
/Removable/MicroSD
/mnt/external1
/mnt/extSdCard
/mnt/extsd
/mnt/usb_storage <-- usb flash mount
/mnt/extSdCard <-- usb flash mount
/mnt/UsbDriveA <-- usb flash mount
/mnt/UsbDriveB <-- usb flash mount
There should be no reason that you would need a direct path hard coded to the internal or external memory when they make functions available for that. Anything that you are hard coding will be the same as what you get back from the functions that you have listed only the will be for that specific devices.
This will give you a string of the absolute path to a file on the external storage:
String myPath = sdcardEnvironment.getExternalStorageDirectory().getAbsolutePath() + "/folder file is in/file you want path to";
And this will get you the path your applications internal storage:
this.getApplicationContext().getFilesDir()
You cannot always access the external SD card from code because of the way that newer versions of android partition itself. Here is statement directly from android dev site:
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
new File("/sdcard").getCanonicalPath().equals(new File("/mnt/sdcard").getCanonicalPath())
Omitted are exception handling and other niceties. Note, however, that ObieMD5 is correct, and you should not be doing this, as you can see from the list of paths in the answer above.
Also note that this method will only resolve symlinks; if your device uses mount instead to have the same space accessible from two locations, this method will not work.
attached to real sd card
The Android SDK, at present, has no concept of "real sd card". There is external storage. The definition of where external storage resides is up to the device manufacturer.
attached to internal memory
Those paths at best refer to external storage, and at worst do not exist.
/sdcard and /mnt/sdcard seems to have the same location. Always ?
No. Those paths may not even exist on some devices, as there is no requirement that they exist, and modern devices do not use those paths. Always use methods on Environment or Context to find locations on external storage.
I am connected android device and PC via USB cable. My Internal SD Card location Path as /mnt/sdcard. But my External USB device path as /mnt/userdata1. I am try to use this code to find only the Internal SD Card Path Environment.getExternalStorageDirectory(). I am using this code to access only in the internal SD Card path. How to access the external USB Path.
For example Screenshot is here...
Example
In this example contains Internal Memory, External SD card and USB Storage. How to find this path ( Internal Memory, External SD card and USB Storage) programmatically. In this code Environment.getExternalStorageDirectory() is viewed files from all Internal Memory Files only. So how to access others path ( External SD card and USB Storage ) Please guide me with code. Thanks..
If I understand correctly, what you are calling "external" USB path is actually the mount point for your SD card on your computer. Most likely, your SD card has label userdata1. Therefore when it's mounted on the computer, it gets /mnt/userdata1 mount point. However this is not strictly necessary and it can be any mount point at all. In fact, if you connect it to another computer, it can easily be another mount point.
Because this path is determined by the computer operating system, you'll need to find this path on your computer (note that this can be different every time you connect your phone to your PC, so you'll need to do it every time).
From your question and path structure (/mnt/userdata1) I'm guessing you're using linux or some other unix version. Therefore you could run mount on your PC to see the list of the mounted devices. For example, here's the output on my mac:
$ mount
/dev/disk0s2 on / (hfs, local, journaled)
devfs on /dev (devfs, local, nobrowse)
map -hosts on /net (autofs, nosuid, automounted, nobrowse)
map auto_home on /home (autofs, automounted, nobrowse)
/dev/disk1s1 on /Volumes/ALEKS540 (msdos, local, nodev, nosuid, noowners)
Note the last line in the output - this is my connected android phone with the SD card mounted to the computer. On macs, the mount points are created under /Volumes instead of /mnt. Other than than, ALEKS540 is the label of my SD card, hence it's mounted this way.
Internally on the phone, it's still mounted as /mnt/sdcard.
From the point of view of Android, there may be three storage types:
Internal memory it's always mounted under / on the device and contains everything except the SD card and USB storage below.
SD card - this is referred to as "external storage" and is usually mounted as /mnt/sd, but not always. Environment.getExternalStorageDirectory() will return the path of SD card mount point.
USB storage - this is only supported on very few devices (those that support USB host mode for external storage). This will be mounted somewhere under /mnt, but the exact location will vary. You will need to use Android NDK to interrogate and iterate mounted devices to find the one you're after.
When I play Temple Run on Android, the app stores data somewhere. If I enable a USB connection and then try playing the game, the app now stores this information somewhere completely new, so that my previous information is not visible any more. Only when I disable the USB connection does the previous data get used.
In other words, I start off as a completely new user if the SD card is mounted and am only able to resume my old state when the SD card is unmounted.
What kind of storage is this? Why is it not visible when I mount the SD card? Can I keep data when switching phones and keeping the SD card?
Sounds Like it must be storing it on the SD Card, when you plug your phone into a USB port it mounts the SD Card to your computer not allowing access to it from your game... so the game will fallback onto internal storage (on phone).
When you plug your phone in it will be defaulting to mounting SD Card, Change this to "Just Charge" and try playing the game.
They probably check if an SD-card is available, and if not use the internal storage.
When you mount the SD-card, the applications cannot access it, so it switches to internal storage, where you do not have any saved games.