How can I retrieve an SD card's serial number in Android 7.0+?
Asked Answered
A

5

22

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.

Archaeornis answered 19/4, 2017 at 1:4 Comment(18)
The only thing that I can think of that is in the ballpark is getUuid() on StorageVolume. You would get StorageVolume objects from StorageManager. However, I have no idea if the UUID relates to the serial number.Trigraph
@CommonsWare: Thanks, I will try it. I've read that Volume IDs don't correlate to the serial number of the chip, but don't know if that's true on Android. If getUuid() really returns a UUID, then it can't be exactly the chip serial number, because the latter is only 32 bits. However if it's a predictable number based on the chip's serial number, that would be OK.Archaeornis
I do not have any better options for you -- sorry!Trigraph
For future reference, here are the results: The device I tested it on gave a UUID of 76DE-3B41... notable that it's only 8 digits. This was for a chip whose serial number was 000fec46. The volume UUID did not change when when we called getUuid() with a different chip. So the UUID is definitely not the chip serial number. @Commonsware thanks for the idea ... that's more info than I had before.Archaeornis
by any chance, does an unprivileged mount command show anything useful?Invagination
does this topic helps #3349143 or does it fail in the permission problem case ?Polybius
@nandsito: the mount command shows this line for the SD card: /dev/fuse on /storage/76DE-3B41 type fuse (rw,nosuid,nodev,noexec,noatime,user_id=1023,group_id=1023,default_permissions,allow_other). So again, it's not showing the serial number.Archaeornis
@Polybius The answers there are primarily about the above approach, which now fails with a permissions error.Archaeornis
I feel stupid to suggest that, but did you try to give the app the permission to access to external storage with <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> ? And in the case you have such permission, did you try to find out if there exists a permission for your case somewhere ?Polybius
@Feuby: Thanks for asking even though it seemed like a dumb question. Often it turns out that I've forgotten something dumb. But in this case yes the app has android.permission.READ_EXTERNAL_STORAGE. And at your suggestion I looked again at the list of available permissions (normal and dangerous) and didn't see anything else relevant.Archaeornis
Do you have permission to write ? maybe acessing these data also need writing permission (like you know, storing "last access" to these data). Sometimes having "readonly" is not enought even to read only... But i don't know at allPolybius
@Feuby: My test app does have WRITE_EXTERNAL_STORAGE permission in the manifest. But it doesn't have read permission on the required directories (as noted in the question), let alone write permission. However I don't think the app can do anything about that.Archaeornis
@Archaeornis I suspect those are changes in selinux configuration, I have forwarded your question here: issuetracker.google.com/issues/37091475Damar
@Damar Thanks for linking to that issue... I hadn't found anything about it. It sounds like Google is treating this as "won't fix, works as intended, even though apps that have millions of users are now broken."Archaeornis
@marcinj: FYI, I created a separate bug report at issuetracker.google.com/issues/37705442 to focus on this narrower issue, and thereby hope to avoid opening such a large can of worms regarding security.Archaeornis
@marcinj: Your comment has been the closest thing to actually answering the question. If you turn it into an answer, and I don't see a better answer by tomorrow, I'll award the bounty to you.Archaeornis
@Archaeornis I have turned it into an answer, and put all the information I have found on it. I am planning also to add comment to your bug report.Damar
@marcinj: Thanks for adding that good comment to the bug report.Archaeornis
D
5

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

Damar answered 26/4, 2017 at 16:41 Comment(5)
Thanks for your comments on that bug report: you said exactly what needed to be said.Archaeornis
Can you tell me on what Android 7 devices you've seen this problem? The only Nougat device I have access to is the Alcatel A30 I mentioned above, and I would like to know how widespread the problem is.Archaeornis
We have seen this currently only on Sony Z5.Damar
I have added question on Sony developer forum, maybe they will give some official response in this topic: talk.sonymobile.com/t5/General-Discussion/…Damar
FYI I didn't receive any answers to my requests for clarification or to your comment on the Android issue I filed. So I filed a new one beginning with an explicit reference to "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.": issuetracker.google.com/issues/38492944Archaeornis
S
1

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

Selfoperating answered 27/4, 2017 at 22:34 Comment(2)
The first suggestion is just like what was mentioned in the question as not working, but using cid instead of serial. It suffers from the same issue: /sys/class/mmc_host/mmc* is not readable. I will try the other two suggestions on Android 7.0 when I can, but when I try them under adb shell in 6.0, there is no sudo, hwinfo, or hdparm to be found.Archaeornis
I tried the last two suggestions on an Android 7.0 device, and got the same results -- there is no sudo, hwinfo, or hdparm to be found.Archaeornis
P
0

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.

Pricefixing answered 21/4, 2017 at 22:3 Comment(1)
Thanks for the idea. This is the same as CommonsWare's comment; see my response at #43485064Archaeornis
I
0
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

Insist answered 24/4, 2017 at 11:56 Comment(5)
This appears to be retrieving the device ID, the SIM serial number, and the Android ID -- none of which are the SD card serial number. Do you have some indication that this would actually retrieve the SD card serial number instead?Archaeornis
i have edit my answer follow this link and also i update above code. #9063661 credit to : stackoverflow.com/users/1408418/awcroperInsist
This is essentially the method that I described in the first paragraph of the question, which is no longer working as of Android 7. The CID includes the serial number. Neither serial nor cid can be read, because /sys/block/mmcblk0 (or /sys/block/mmcblk1 as the case may be) is unreadable.Archaeornis
which device you are take for testing ?Insist
See 2nd paragraph of the question.Archaeornis
S
0

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.

Sauncho answered 27/12, 2019 at 2:2 Comment(3)
This is helpful to know. However it's not an answer to this question, which is about how to get the serial number of the SD card. The ID of the mounted volume is completely separate from the serial number of the SD card (see comment #43485064).Archaeornis
Ah. My mistake. Please note that the field in the FAT standard containing an "UUID" (obviously not really unique so that's a misnomer) is called Volume Serial Number (though it obviously is not a serial number, just a random, hopefully pseudo-unique ID).Sauncho
You're right, it is called a "serial number" sometimes. And I don't mean that term is wrong. It's just a different thing from the SD card serial number. The Volume UUID can change when media is reformatted, but the SD card serial number shouldn't be changeable.Archaeornis

© 2022 - 2024 — McMap. All rights reserved.