如何读取SD卡ID号?

时间:2010-07-27 22:49:50

标签: android c++ windows mfc

如何以编程方式读取SD卡的CID寄存器,其中包含序列号和其他信息?我可以通过Android Java或Native代码吗?

提前致谢, 埃里克

12 个答案:

答案 0 :(得分:12)

以下是获取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();
}

答案 1 :(得分:7)

我设法通过USB将手机插入电脑并使用adb工具(Android SDK)找到我的SD卡CID

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

我的手机已植根,所以我不确定这是否可以在非root手机上访问。

也可以尝试

$ 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

内核文档http://www.mjmwired.net/kernel/Documentation/mmc/mmc-dev-attrs.txt

中对此进行了解释

答案 2 :(得分:5)

我做了这个...它对我有用...希望它能让你清楚!

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;
    }

答案 3 :(得分:4)

到目前为止我发现的唯一提供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
如果您是C ++开发人员,您可以使用它并使其在Android上运行。

答案 4 :(得分:4)

正如BMB所写,你无法知道/ sys文件系统中SD卡的真实路径。但是,/ sys也实现了别名,您可以通过/ sys / block / mmcblk0 / device / cid检索CID。

例如,在运行2.2的Tattoo上,/ sys / block / mmcblk0是一个软链接(由系统自动建立)到/sys/devices/platform/msm_sdcc.2/mmc_host/mmc1/mmc1:aaaa/block / mmcblk0。

答案 5 :(得分:4)

在android中有api获取sd卡序列号。该方法称为getFatVolumeId(String mountPoint),其中“mountPoint”是sd卡名称(您可以通过调用Environment.getExternalStorageDirectory()来获取此名称)。但是getFatVolumeId是隐藏的函数(或者被遗忘),所以你想在你的项目中创建名为android.os的包及其中的类来引用本机方法,以便能够调用它:

package android.os;

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

代码是:

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

另见链接

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

答案 6 :(得分:3)

我所知道的没有可以执行此操作的Android API以及所需的常规解决方案。为了提供一些背景知识,SD卡连接到特定于设备平台的hw控制器。如果您了解您的平台,则可以从linux / sys文件系统中读出cid值。以下代码段适用于我的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");
    }

在另一个平台上,我们正在寻找的sys文件是不同的。由于我无法测试,因此在同一平台上的不同卡之间甚至可能不同。在基于MSM的设备上,路径类似于/sys/devices/platform/msm_sdcc.1/mmc_host /...

由于我们的硬件依赖于读取SD卡CID,因此必须对Android API进行更新:提供一般访问权限。然后,每个设备制造商必须实现此API以映射到正确的SD卡控制器驱动程序。

答案 7 :(得分:2)

我也在寻找这个功能,但永远无法获得自制的解决方案。我最终找到了一家制作SID读卡器的公司。转到nexcopy.com并查看他们的SD或microSD复制器部分。它一次最多可以读取20张卡片。

答案 8 :(得分:2)

对于mmcblk0,只需在shell中写为:

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

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

您可以轻松地在java中实现它。

REF:
https://www.kernel.org/doc/Documentation/mmc/mmc-dev-attrs.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/

答案 9 :(得分:1)

即使相对古老的Palm OS和Windows Mobile OS设备能够读取SD卡ID,AFAIK Android设备也无法做到这一点。鉴于Settings.Secure.ANDROID_ID讨论here的问题,这尤其令人不安。

答案 10 :(得分:0)

以Dinesh的回答为基础......

Dinesh建议查看目录 名为/sys/class/mmc_host/mmc1/mmc1:*/的文件的cid(其中*是数字),它为我们提供了卡的CID寄存器的内容。这在许多情况下都有效,并且是一个非常有用的开始。

但是mmc1并不总是可移动的SD卡。有时,例如在Android API级别为10的Motorola Droid Pro上,mmc0是可移动SD卡,mmc1是其他内容。我猜测mmc1,如果存在,则指向某种内部存储(可能是不可移动的microSD卡)。在我们测试的廉价Android平板电脑上,mmc0是SD卡,没有mmc1

所以你不能假设mmc1是SD卡。

一线希望:看来(到目前为止)通过查看与type文件相同的目录中的cid文件(例如/sys/class/mmc_host/mmc1/mmc1:0007/type),我们可以确定其中:类型值SD表示可移动SD卡,而MMC则不是。

但是,这只是在一些Android设备上进行测试。我无法找到有关type文件内容的任何规范,因此如果有人知道相关文档,请告知我们。

当然,MMC和SD只是两种不同的存储技术标准,SD与MMC向后兼容。因此,类型SD始终对应于外部microSD卡的情况并非必然MMC根本不可能指示microSD卡(如果类型字段准确填充)似乎不太可能;但另一方面,可以想象不可移动的SD卡可以有SD类型。

有待进一步研究:当microSD卡通过USB适配器连接时,这种方法是否有效?我用平板电脑对此进行了一次测试,USB连接的microSD卡显示为mmc1,类型为SD

答案 11 :(得分:0)

您可以使用StorageManager来获得它。
这是示例代码:

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();
     }
 }