How can I retrieve an SD card's serial number

2020-02-08 05:49发布

问题:

N.B.: This question about the serial number of the physical SD card, not the UUID of the mounted volume. These are two independent pieces of data.

In some versions of Android, and other variants of Linux, it's possible to get the serial number of a mounted SD card, e.g. by reading the contents of /sys/class/mmc_host/mmc0/mmc0:0001/serial or /sys/block/mmcblk0/device/serial (specific numbers may vary). In my testing this has worked pretty reliably, as long as the SD card is inserted in a built-in SD card slot (not mounted via USB adapter).

But as of Android 7.0 Nougat, the OS is said to be blocking access to this information, at least on some devices. I tested this by running a test app on a new Alcatel A30 GSM (Android 7.0), and in fact the above approach fails with a permission error:

java.io.FileNotFoundException: /sys/block/mmcblk0/device/serial (Permission denied)
at java.io.FileInputStream.open(Native Method)

For future reference, we (testing from an adb shell) have permissions to ls -ld the following:

  • /sys/class/mmc_host but not /sys/class/mmc_host/mmc0
  • /sys/block but not /sys/block/mmcblk0

Since the above approach no longer works,

  • Is there another way to obtain the serial number of a mounted SD card in Android 7.0 or later?

  • Failing that, is there any documentation or other statement from Google on plans for providing or not providing this function? I haven't found anything in the Android issue tracker, but maybe I'm not searching right.

To make sure the question is clear, I'm talking about what an ordinary (non-system) app running on a non-rooted device can do, with any permissions that an app can normally request and receive.

FYI, the /sbin directory doesn't seem to be readable, so commands like /sbin/udevadm aren't an option.

回答1:

In Android N access to /sys nad /proc was significantly restricted, this was done to provide stricter sandboxes where applications run. This is explained in https://issuetracker.google.com/issues/37091475 as intentional. Actually its not said that all the data in /sys is not accessible, and Google is open to allow access to other files from this location:

If there are specific files in /sys you believe should be available to applications, but are not, please file a new bug where the request can be evaluated. For instance, /sys/devices/system/cpu is available to all processes, so it's inaccurate to say all of /sys is restricted.

I have a bad feeling that google is making changes similar to Apple where it is not allowed to gain hardware id-s. If that is not resolved then the solution is to use google account IDs instead. But I am aware it is not always possible, and will require major changes in business logic (licensing etc.).

Hopefully your bug report will be considered positively.

another related SO I found : File system changes in Android Nougat



回答2:

Use StorageVolume.getUuid() on StorageVolume which you get from StorageManager.

The value is volume ID assigned during formatting of the card, and its length/format differs depending on file system type. For FAT32 it is XXXX-XXXX, for NTFS it's longer hex string, for Internal mass storage it returns null.



回答3:

public String getSDCARDiD()
{
    String sd_cid = null;
    try {

        File file = new File("/sys/block/mmcblk1");
        String memBlk;
        if (file.exists() && file.isDirectory()) {

            memBlk = "mmcblk1";
        } else {
            //System.out.println("not a directory");
            memBlk = "mmcblk0";
        }

        Process cmd = Runtime.getRuntime().exec("cat /sys/block/"+memBlk+"/device/cid");
        BufferedReader br = new BufferedReader(new InputStreamReader(cmd.getInputStream()));
        sd_cid = br.readLine();
        //System.out.println(sd_cid);

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return sd_cid;
}

try this: reference original link :Android get id of SD Card programmatically



回答4:

adb shell cat /sys/class/mmc_host/mmc1/mmc1:*/cid

You can also try

sudo hwinfo --disk

to get information on your disks, including SD Cards.

Also try

sudo hdparm -I /dev/sdb | more



回答5:

As an FYI to those looking into UUID or volume serial numbers of FAT type volumes under Android: Some Fujifilm cameras, including the X-T30 (Firmware 1.10) do not write a volume serial number into the FAT volume when formatting.

Under Windows, CHKDSK displays no volume serial number at all. On Android, calling StorageVolume.getUuid() returns "0000-0000".

This is all fine and dandy, until you on Android mount two Fujifilm-formatted cards via a hub. Then there seems to be identity collision, where the Android OS prompts the user to format one of the cards. Separately they are accessible.

I'm guessing there are two combined problems here: 1) Fujifilm is not writing a volume serial number when formatting, and 2) Android uses the volume serial number as part of the mount point path, leading to collision.

Fujifilm and Google might both want to pay attention to this issue.

EDIT: Card formatted in a Nikon D810 also has the same problem, no Volume Serial Number.