简体   繁体   English

如何读取SD卡ID号?

[英]How to read the SD Card ID number?

How can I programatically read the SD Card's CID register, which contains a Serial Number and other information?如何以编程方式读取 SD 卡的 CID 寄存器,其中包含序列号和其他信息? Can I do it through Android Java, or Native code?我可以通过 Android Java 或本机代码来完成吗?

Thanks in advance, Eric提前致谢,埃里克

Here is sample code for getting SID and CID这是获取 SID 和 CID 的示例代码

if (isExteranlStorageAvailable()) {
    try {
        File input = new File("/sys/class/mmc_host/mmc1");
        String cid_directory = null;
        int i = 0;
        File[] sid = input.listFiles();

        for (i = 0; i < sid.length; i++) {
            if (sid[i].toString().contains("mmc1:")) {
                cid_directory = sid[i].toString();
                String SID = (String) sid[i].toString().subSequence(
                        cid_directory.length() - 4,
                        cid_directory.length());
                Log.d(TAG, " SID of MMC = " + SID);
                break;
            }
        }
        BufferedReader CID = new BufferedReader(new FileReader(
                cid_directory + "/cid"));
        String sd_cid = CID.readLine();
        Log.d(TAG, "CID of the MMC = " + sd_cid);

    } catch (Exception e) {
        Log.e("CID_APP", "Can not read SD-card cid");
    }

} else {
    Toast.makeText(this, "External Storage Not available!!",
            Toast.LENGTH_SHORT).show();
}

I managed to find my SD card CID by plugging my phone to my computer via usb and using the adb tool (Android SDK)我设法通过 USB 将手机插入计算机并使用 adb 工具(Android SDK)找到了我的 SD 卡 CID

$ adb shell
# cat /sys/block/mmcblk0/../../cid

My phone is rooted so I'm not sure if this is accessible on non-rooted phones.我的手机是 root 的,所以我不确定这是否可以在非 root 的手机上访问。

Also try也试试

$ adb shell
# cd /sys/block/mmcblk0/../../
# ls
block                 fwrev                 preferred_erase_size
cid                   hwrev                 scr
csd                   manfid                serial
date                  name                  subsystem
driver                oemid                 type
erase_size            power                 uevent

These are explained in the kernel documentation http://www.mjmwired.net/kernel/Documentation/mmc/mmc-dev-attrs.txt这些在内核文档http://www.mjmwired.net/kernel/Documentation/mmc/mmc-dev-attrs.txt 中有解释

I made this one... it worked for me... hope it makes u clear!我做了这个……它对我有用……希望它能让你清楚!

String getSDCARDiD()
    {
        try {

            File file = new File("/sys/block/mmcblk1");
            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;
    }

The only code I've found thus far to provide the id is C++ or C# http://jo0ls-dotnet-stuff.blogspot.com/2008/12/read-secure-digital-sd-card-serial.html到目前为止,我发现提供 ID 的唯一代码是 C++ 或 C# http://jo0ls-dotnet-stuff.blogspot.com/2008/12/read-secure-digital-sd-card-serial.html
http://jo0ls-dotnet-stuff.blogspot.com/2008/12/read-cid-and-csd-c-implementation.html http://jo0ls-dotnet-stuff.blogspot.com/2008/12/read-cid-and-csd-c-implementation.html
If you are a C++ developer you may be able to take this and make it work on Android.如果您是 C++ 开发人员,您也许可以接受它并使其在 Android 上运行。

As BMB wrote, you cannot know the real path of the SD card in the /sys filesystem.正如 BMB 所写,您无法知道 /sys 文件系统中 SD 卡的真实路径。 However, /sys implements aliases as well, and you may be able to retrieve the CID through /sys/block/mmcblk0/device/cid.但是,/sys 也实现了别名,您可以通过 /sys/block/mmcblk0/device/cid 检索 CID。

For example, on a Tattoo running 2.2, /sys/block/mmcblk0 is a soft link (established automatically by the system) to /sys/devices/platform/msm_sdcc.2/mmc_host/mmc1/mmc1:aaaa/block/mmcblk0.例如,在运行 2.2 的纹身上,/sys/block/mmcblk0 是一个软链接(由系统自动建立)到 /sys/devices/platform/msm_sdcc.2/mmc_host/mmc1/mmc1:aaaa/block/mmcblk0。

There is api in android for getting sd card serial id. android中有用于获取sd卡序列号的api。 The method is called getFatVolumeId(String mountPoint), where "mountPoint" is sd card name (you can get this name by calling Environment.getExternalStorageDirectory()).该方法称为getFatVolumeId(String mountPoint),其中“mountPoint”为sd 卡名称(您可以通过调用Environment.getExternalStorageDirectory() 获取此名称)。 But getFatVolumeId is kindof hidden function (or forgotten), so you want to create package in your project named android.os and the class in it to reference the native method, to be able to call it:但是 getFatVolumeId 是一种隐藏函数(或被遗忘的函数),因此您希望在名为 android.os 的项目中创建包以及其中的类来引用本机方法,以便能够调用它:

package android.os;

public class FileUtils {
    public static native int getFatVolumeId(String mountPoint);
}

And the code is:代码是:

File SdCard = Environment.getExternalStorageDirectory();
int Serial = FileUtils.getFatVolumeId(SdCard.getName());

Also see the links另请参阅链接

http://groups.google.com/group/android-framework/browse_thread/thread/1abd18435ba20a67?pli=1 http://markmail.org/message/rdl4bhwywywhhiau#query:+page:1+mid:rdl4bhwywywhhiau+state:results http://groups.google.com/group/android-framework/browse_thread/thread/1abd18435ba20a67?pli=1 http://markmail.org/message/rdl4bhwywywhhiau#query:+page:1+mid:rdl4bhwywywhhiau+state:结果

There is no Android API that can do this that I am aware of and for a general solution that is needed.我知道没有 Android API 可以做到这一点,也没有需要的通用解决方案。 To provide some background the SD card is connected to a hw-controller that is specific to the device platform.为了提供一些背景,SD 卡连接到特定于设备平台的硬件控制器。 It is possible to read out the cid value from the linux /sys file system if you know your platform.如果您了解您的平台,则可以从 linux /sys 文件系统中读出 cid 值。 The following snippet works on my droid (TI omap based platform) but not on Qualcomm MSM based platforms.以下代码段适用于我的 droid(基于 TI omap 的平台),但不适用于基于 Qualcomm MSM 的平台。

try {
        BufferedReader input = new BufferedReader(new FileReader("/sys/devices/platform/mmci-omap-hs.0/mmc_host/mmc0/mmc0:aaaa/cid"));
        String sd_cid = input.readLine();
        Log.i("CID_APP", sd_cid);
    } catch (Exception e) {
        Log.e("CID_APP","Can not read SD-card cid");
    }

On a another platform the sys file we are looking for is different.在另一个平台上,我们正在寻找的 sys 文件是不同的。 It may even differ between different cards on the same platform since I was not able to test that.由于我无法测试,因此同一平台上的不同卡之间甚至可能有所不同。 On MSM based devices the path would be something like /sys/devices/platform/msm_sdcc.1/mmc_host/...在基于 MSM 的设备上,路径类似于 /sys/devices/platform/msm_sdcc.1/mmc_host/...

Since we have this hardware dependence on reading out the SD-card CID there would have to be an update to the Android API:s that provides general access.由于我们对读取 SD 卡 CID 有这种硬件依赖性,因此必须对提供通用访问的 Android API:s 进行更新。 This API would then have to be implemented by each device manufacturer to map to the correct sd card controller driver.然后,每个设备制造商都必须实现此 API 以映射到正确的 SD 卡控制器驱动程序。

I was looking for this function too but could never get a home brewed solution.我也在寻找此功能,但永远无法获得自制解决方案。 I ended up finding a company that makes an SID reader.我最终找到了一家制造 SID 阅读器的公司。 Go to nexcopy.com and look in their SD or microSD duplicator section.转到 nexcopy.com 并查看他们的 SD 或 microSD 复制器部分。 It can read up to 20 cards at a time.它一次最多可以读取 20 张卡片。

for mmcblk0 , just write in shell as:对于mmcblk0 ,只需在 shell 中写为:

cat /sys/block/mmcblk0/device/cid 
2750485344303847307cf6851900b99b

cat /sys/block/mmcblk0/device/serial 
0x7cf68519

you can implement it in java easily.你可以很容易地在java中实现它。

ref:参考:
https://www.kernel.org/doc/Documentation/mmc/mmc-dev-attrs.txt https://www.kernel.org/doc/Documentation/mmc/mmc-dev-attrs.txt
https://www.kernel.org/doc/Documentation/sysfs-rules.txt https://www.kernel.org/doc/Documentation/sysfs-rules.txt
http://www.cameramemoryspeed.com/sd-memory-card-faq/reading-sd-card-cid-serial-psn-internal-numbers/ http://www.cameramemoryspeed.com/sd-memory-card-faq/reading-sd-card-cid-serial-psn-internal-numbers/

Even though the relatively ancient Palm OS and Windows Mobile OS devices are able to read the SD card ID, AFAIK Android devices aren't capable of doing that yet.尽管相对古老的 Palm OS 和 Windows Mobile OS 设备能够读取 SD 卡 ID,但 AFAIK Android 设备还不能这样做。 This is particularly troubling given the problems with the Settings.Secure.ANDROID_ID discussed here .鉴于此处讨论的 Settings.Secure.ANDROID_ID 存在问题,这尤其令人不安。

You can get it with the StorageManager.您可以使用 StorageManager 获取它。
Here is a sample-code:这是一个示例代码:

final StorageManager storageManager = (StorageManager) activity.getSystemService(Context.STORAGE_SERVICE);
final List<StorageVolume> storageVolumes = storageManager.getStorageVolumes();
final UserHandle user = android.os.Process.myUserHandle();
for (StorageVolume storageVolume : storageVolumes) {
     // "SDCARD" must be your sd-card name
     if (storageVolume.getDescription(activity).equals("SDCARD")){
        // the SD Card ID number
        return storageVolume.getUuid();
     }
 }

Building on Dinesh's answer...基于 Dinesh 的回答...

Dinesh suggested looking in the directory /sys/class/mmc_host/mmc1/mmc1:*/ (where * is a number) for the file named cid , which gives us the contents of the card's CID register. Dinesh 建议在目录/sys/class/mmc_host/mmc1/mmc1:*/ (其中 * 是一个数字)中查找名为cid的文件,它为我们提供了卡的 CID 寄存器的内容。 This is does work in many cases, and is a very helpful start.这在许多情况下确实有效,并且是一个非常有用的开始。

But mmc1 is not always the removable SD card.mmc1并不总是可移动 SD 卡。 Sometimes, eg on a Motorola Droid Pro with Android API level 10, mmc0 is the removable SD card, and mmc1 is something else.有时,例如在具有 Android API 级别 10 的 Motorola Droid Pro 上, mmc0是可移动 SD 卡,而mmc1是其他东西。 I'm guessing that mmc1 , when present, points to internal storage of some sort (possibly a non-removable microSD card).我猜mmc1存在时,指向某种内部存储(可能是不可移动的 microSD 卡)。 On a cheap Android tablet we tested, mmc0 is the SD card and there is no mmc1 .在我们测试的廉价 Android 平板电脑上, mmc0是 SD 卡,没有mmc1

So you can't just assume that mmc1 is the SD card.所以你不能只假设mmc1是 SD 卡。

A glimmer of hope: It seems (so far) that by looking at the type file in the same directory as the cid file (eg /sys/class/mmc_host/mmc1/mmc1:0007/type ), we can determine which is which: a type value of SD indicates a removable SD card, while MMC is not.一线希望:似乎(到目前为止)通过查看与cid文件位于同一目录中的type文件(例如/sys/class/mmc_host/mmc1/mmc1:0007/type ),我们可以确定哪个是哪个: 类型值为SD表示可移动 SD 卡,而MMC不是。

However, that's just from testing on a few Android devices.但是,这只是在一些 Android 设备上进行的测试。 I can't find any specifications about the contents of the type file, so if somebody else knows of relevant documentation, please let me know.我找不到关于type文件内容的任何规范,所以如果其他人知道相关文档,请告诉我。

Of course, MMC and SD are just two different storage technology standards, and SD is backward-compatible with MMC.当然,MMC和SD只是两种不同的存储技术标准,SD是向下兼容MMC的。 So it's not necessarily the case that type SD always corresponds to an external microSD card.因此,类型 SD不一定总是对应于外部 microSD 卡。 It doesn't seem likely that MMC could indicate a microSD card at all (if the type field is populated accurately); MMC似乎根本不可能指示 microSD 卡(如果类型字段填充准确); but on the other hand, it's conceivable that a non-removable SD card could have type SD .但另一方面,可以想象,不可移动的 SD 卡可能具有SD类型。

For further research: Does this approach work when an microSD card is connected via a USB adapter?进一步研究:当 microSD 卡通过 USB 适配器连接时,这种方法是否有效? My one test on this, with a tablet, had the USB-connected microSD card show up as mmc1 , with type SD .我使用平板电脑对此进行的一项测试将 USB 连接的 microSD 卡显示为mmc1 ,类型为SD

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM