After reading the Android documentation on storing files, I see that External Storage can include both a removable sd card AND storage that is internal to the device, i.e. not removable. Is there a way to distinguish between removable storage and non-removable storage when choosing to save a file to External Storage?
问题:
回答1:
I think you can't reliably distinguish between internal and external (SD) storage.
At first glance it might seem like you can use something like Environment.isExternalStorageRemovable()
but this isn't reliable, because your "primary external" storage device might very well be the device's internal memory, not the SD card.
The doc for Environment.getExternalStorageDirectory()
states:
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.
As an example, my LG G4 has an external SD card installed, and I can see it with adb (external_SD
):
$ adb shell ls -la /storage/
drwx------ root root 2015-02-28 01:10 USBstorage1
drwx------ root root 2015-02-28 01:10 USBstorage2
drwx------ root root 2015-02-28 01:10 USBstorage3
drwx------ root root 2015-02-28 01:10 USBstorage4
drwx------ root root 2015-02-28 01:10 USBstorage5
drwx------ root root 2015-02-28 01:10 USBstorage6
dr-xr-xr-x root root 2015-02-28 01:10 emulated
drwxrwx--x root sdcard_r 2015-07-31 08:19 external_SD
lrwxrwxrwx root root 2015-02-28 01:10 sdcard0 -> /storage/emulated/legacy
However, the various APIs for external storage return values that prove that the device is using internal memory as its "primary external" storage:
- Environment.getExternalStorageState: mounted
- Environment.isExternalStorageEmulated: true
- Environment.isExternalStorageRemovable: false
- Context.getExternalCacheDir: /storage/emulated/0/Android/data/com.codeblast.storagetype/cache
- Context.getExternalFilesDir: /storage/emulated/0/Android/data/com.codeblast.storagetype/files
Running the code on an emulator without external SD card returns exactly the same results.
So you can't assume that /mnt/sdcard
means a physical SD card.
You may have reconsider what you're actually trying accomplish rather than trying to detect the storage type. :-)