广

android开发

  • IOS开发
  • android开发
  • PHP编程
  • JavaScript
  • ASP.NET
  • ASP编程
  • JSP编程
  • Java编程
  • 易语言
  • Ruby编程
  • Perl编程
  • AJAX
  • 正则表达式
  • C语言
  • 编程开发

    android用java和c实现查找sd卡挂载路径(sd卡路径)的方法

    2018-04-09 07:40:47 次阅读 稿源:互联网
    广告

    方法一:

    分析 mount 命令的返回信息,例如:
    代码如下:

    $ mount
    rootfs / rootfs ro,relatime 0 0
    tmpfs /dev tmpfs rw,nosuid,relatime,mode=755 0 0
    devpts /dev/pts devpts rw,relatime,mode=600 0 0
    proc /proc proc rw,relatime 0 0
    sysfs /sys sysfs rw,relatime 0 0
    debugfs /sys/kernel/debug debugfs rw,relatime 0 0
    none /acct cgroup rw,relatime,cpuacct 0 0
    tmpfs /mnt/asec tmpfs rw,relatime,mode=755,gid=1000 0 0
    tmpfs /mnt/obb tmpfs rw,relatime,mode=755,gid=1000 0 0
    none /dev/cpuctl cgroup rw,relatime,cpu 0 0
    /dev/block/platform/sdhci-tegra.3/by-name/system /system ext4 ro,relatime,barrier=1,data=ordered 0 0
    /dev/block/platform/sdhci-tegra.3/by-name/userdata /data ext4 rw,nosuid,nodev,noatime,barrier=1,data=ordered 0 0
    /dev/block/platform/sdhci-tegra.3/by-name/cache /cache ext4 rw,nosuid,nodev,noatime,barrier=1,data=ordered 0 0
    /dev/block/platform/sdhci-tegra.3/by-name/pdsb /pds ext2 ro,relatime 0 0
    /dev/fuse /mnt/sdcard fuse rw,nosuid,nodev,relatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0
    /dev/block/vold/179:9 /mnt/sdcard-ext vfat rw,dirsync,nosuid,nodev,noexec,relatime,uid=1000,gid=1015,fmask=0702,dmask=0702,allow_utime=0020,codepage=cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro 0 0
    /dev/block/vold/179:9 /mnt/secure/asec vfat rw,dirsync,nosuid,nodev,noexec,relatime,uid=1000,gid=1015,fmask=0702,dmask=0702,allow_utime=0020,codepage=cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro 0 0
    tmpfs /mnt/sdcard-ext/.android_secure tmpfs ro,relatime,size=0k,mode=000 0 0

    Java 版代码如下:
    // 给 C/C++ 编写的共享库回调取得全部 SD 卡路径的函数
    public String
    GetAllSDPath() throws TokenException
    {
        String strMountInfo = "";

        // 1.首先获得系统已加载的文件系统信息
        try
        {
            // 创建系统进程生成器对象
            ProcessBuilder objProcessBuilder = new ProcessBuilder();
            // 执行 mount -h 可以看到 mount : list mounted filesystems
            // 这条命令可以列出已加载的文件系统
            objProcessBuilder.command( "mount" ); // 新的操作系统程序和它的参数
            // 设置错误输出都将与标准输出合并
            objProcessBuilder.redirectErrorStream( true );
            // 基于当前系统进程生成器的状态开始一个新进程,并返回进程实例
            Process objProcess = objProcessBuilder.start();
            // 阻塞线程至到本地操作系统程序执行结束,返回本地操作系统程序的返回值
            objProcess.waitFor();

            // 得到进程对象的输入流,它对于进程对象来说是已与本地操作系统程序的标准输出流(stdout)相连接的
            InputStream objInputStream = objProcess.getInputStream();

            byte[] buffer = new byte[1024];

            // 读取 mount 命令程序返回的信息文本
            while ( -1 != objInputStream.read( buffer ) )
            {
                strMountInfo = strMountInfo + new String( buffer );
            }

            // 关闭进程对象的输入流
            objInputStream.close();

            // 终止进程并释放与其相关的任何流
            objProcess.destroy();
        }
        catch ( Exception e )
        {
            e.printStackTrace();
        }

        // 2.然后再在系统已加载的文件系统信息里查找 SD 卡路径  
        // mount 返回的已加载的文件系统信息是以一行一个信息的形式体现的,
        // 所以先用换行符拆分字符串
        String[] lines = strMountInfo.split( "/n" );

        // 清空该字符串对象,下面将用它来装载真正有用的 SD 卡路径列表
        strMountInfo = "";

        for ( int i = 0;
                  i < lines.length;
                  i++ )
        {
            // 如果该行内有 /mnt/和 vfat 字符串,说明可能是内/外置 SD 卡的挂载路径
            if ( -1 != lines[i].indexOf( " /mnt/" ) && // 前面要有空格,以防断章取义
                 -1 != lines[i].indexOf( " vfat " ) )  // 前后均有空格
            {
                // 再以空格分隔符拆分字符串
                String[] blocks = lines[i].split( "//s" ); // //s 为空格字符
                for ( int j = 0;
                          j < blocks.length;
                          j++ )
                {
                    // 如果字符串中含有/mnt/字符串,说明可能是我们要找的 SD 卡挂载路径
                    if ( -1 != blocks[j].indexOf( "/mnt/" ) )
                    {
                        // 排除重复的路径
                        if ( -1 == strMountInfo.indexOf( blocks[j] ) )
                        {
                            // 用分号符(;)分隔 SD 卡路径列表,
                            strMountInfo += blocks[j] + ";";
                        }
                    }
                }
            }
        }

        return strMountInfo;
    }

    C 版代码如下:
    代码如下:

    char caStdOutLine[1024]; // mount 命令的标准输出中的一行信息
    char* pcTmpSDPath = NULL;

    // 再用 mount 命令获得的找身份认证锁
    do // 非循环,只是为了方便控制分支层次,便于控制分支流向
    {
        // 通过创建一个管道,调用 fork 产生一个子进程,
        // 执行一个 shell 以运行命令来开启一个进程。
        // 这个进程必须由 pclose() 函数关闭。
        FILE* fp = popen( "mount", // 一个指向以 NULL 结束的 shell 命令字符串的指针,
                                   // 这行命令将被传到 bin/sh 并使用 -c 标志,
                                   // 那么 shell 将执行这个命令从这个字符串中读取。
                          "r" );   // 文件指针连接到 shell 命令的标准输出

        if ( NULL == fp )
        {
            break;
        }

        while( NULL != fgets( caStdOutLine,
                              sizeof( caStdOutLine ),
                              fp ) )
        {
            // 如果 找到了你想要的 SD 卡挂载路径 的话,则
            if ( 判断条件 )
            {
                // 注:管道中的数据一定要读完,不然会崩溃掉的
                continue; // 就不再试下一个挂载地址了
            }

            // 如果该行内有 /mnt/和 vfat 字符串,说明可能是内/外置 SD 卡的挂载路径
            if ( NULL == strstr( caStdOutLine, " /mnt/" ) &&    // 前面要有空格,以防断章取义
                 NULL == strstr( caStdOutLine, " /storage/" ) ) // 前面要有空格,以防断章取义
            {
                continue; // 不满足条件说明这行不是内/外置 SD 卡的挂载路径
            }

            if ( NULL == strstr( caStdOutLine, " vfat " ) )  // 前后均有空格
            {
                continue; // 不满足条件说明这行不是内/外置 SD 卡的挂载路径
            }

            // 再以空格分隔符拆分字符串
            pcTmpSDPath = strtok( caStdOutLine, " " );

            do // 这里是循环,尝试每一个路径
            {
                if ( ( NULL == pcTmpSDPath ) ||
                     ( '/0' == *pcTmpSDPath ) )
                {
                    continue;
                }

                // 如果字符串中含有/mnt/字符串,说明可能是我们要找的 SD 卡挂载路径
                if ( NULL == strstr( pcTmpSDPath, "/mnt/" ) &&
                     NULL == strstr( pcTmpSDPath, "/storage/" ) )
                {
                    continue;
                }

                // TODO: 在此添加对 SD 卡路径使用的语句,如果只是用其中一个,别忘了设置已找到想要 SD 卡路径的标识

            }while ( pcTmpSDPath = strtok( NULL, " " ) );
        }

        // 关闭标准 I/O 流,等待命令执行结束,然后返回 shell 的终止状态。
        // 如果 shell 不能被执行,
        // 则 pclose() 返回的终止状态与 shell 已执行 exit 一样。
        pclose( fp );

    }while ( 0 );


    方法二:
    分析 cat /system/etc/vold.fstab 命令的返回信息,例如:
    代码如下:

    $ cat /system/etc/vold.fstab
    ## Vold 2.0 fstab for Stingray
    #######################
    ## Regular device mount
    ##
    ## Format: dev_mount <label> <mount_point> <part> <sysfs_path1...>
    ## label        - Label for the volume
    ## mount_point  - Where the volume will be mounted
    ## part         - Partition # (1 based), or 'auto' for first usable partition.
    ## <sysfs_path> - List of sysfs paths to source devices
    ######################

    # external sd card
    dev_mount sdcard-ext /mnt/sdcard-ext auto /devices/platform/sdhci-tegra.2/mmc_host/mmc1 /devices/platform/sdhci-tegra.2/mmc_host/mmc2

    # flash drive connection to USB1
    dev_mount usbdisk_1.0 /mnt/usbdisk_1.0 auto /devices/platform/tegra-ehci.0/usb2/2-1/2-1:1.0

    # flash drive connection through hub connected to USB1
    dev_mount usbdisk_1.1 /mnt/usbdisk_1.1 auto /devices/platform/tegra-ehci.0/usb2/2-1/2-1.1
    dev_mount usbdisk_1.2 /mnt/usbdisk_1.2 auto /devices/platform/tegra-ehci.0/usb2/2-1/2-1.2
    dev_mount usbdisk_1.3 /mnt/usbdisk_1.3 auto /devices/platform/tegra-ehci.0/usb2/2-1/2-1.3
    dev_mount usbdisk_1.4 /mnt/usbdisk_1.4 auto /devices/platform/tegra-ehci.0/usb2/2-1/2-1.4
    dev_mount usbdisk_1.5 /mnt/usbdisk_1.5 auto /devices/platform/tegra-ehci.0/usb2/2-1/2-1.5
    dev_mount usbdisk_1.6 /mnt/usbdisk_1.6 auto /devices/platform/tegra-ehci.0/usb2/2-1/2-1.6
    dev_mount usbdisk_1.7 /mnt/usbdisk_1.7 auto /devices/platform/tegra-ehci.0/usb2/2-1/2-1.7

    C 版代码如下:
    char caStdOutLine[1024]; // cat 命令的标准输出中的一行信息
    char* pcTmpSDPath = NULL;
    char* pcNotSpace = NULL;

    // 用 /system/etc/vold.fstab 获得的 SD 卡路径找身份认证锁
    do // 非循环,只是为了方便控制分支层次,便于控制分支流向
    {
        // 通过创建一个管道,调用 fork 产生一个子进程,
        // 执行一个 shell 以运行命令来开启一个进程。
        // 这个进程必须由 pclose() 函数关闭。
        FILE* fp = popen( "cat /system/etc/vold.fstab", // 一个指向以 NULL 结束的 shell 命令字符串的指针,
                                                        // 这行命令将被传到 bin/sh 并使用 -c 标志,
                                                        // 那么 shell 将执行这个命令从这个字符串中读取。
                          "r" );                        // 文件指针连接到 shell 命令的标准输出

        if ( NULL == fp )
        {
            break;
        }

        while( NULL != fgets( caStdOutLine,
                              sizeof( caStdOutLine ),
                              fp ) )
        {
            // 如果 找到了你想要的 SD 卡挂载路径 的话,则
            if ( 判断条件 )
            {
                // 注:管道中的数据一定要读完,不然会崩溃掉的
                continue; // 就不再试下一个挂载地址了
            }

            // Format: dev_mount <label> <mount_point> <part> <sysfs_path1...>
            // 去除开头的空格
            pcNotSpace = caStdOutLine + strspn( caStdOutLine, " " );

            if ( NULL == pcNotSpace   ||
                 '/0' == *pcNotSpace  ||
                 '#'  == *pcNotSpace  || // 行首字符为#说明是注释行
                 'd' != pcNotSpace[0] || // 句子开头不是 dev_mount
                 'e' != pcNotSpace[1] ||
                 'v' != pcNotSpace[2] ||
                 '_' != pcNotSpace[3] ||
                 'm' != pcNotSpace[4] ||
                 'o' != pcNotSpace[5] ||
                 'u' != pcNotSpace[6] ||
                 'n' != pcNotSpace[7] ||
                 't' != pcNotSpace[8] )
            {
                continue; // 不满足条件说明这行不是内/外置 SD 卡的挂载路径
            }

            // 再以空格分隔符拆分字符串
            pcTmpSDPath = strtok( pcNotSpace, " " );

            do // 这里是循环,尝试每一个路径
            {
                if ( ( NULL == pcTmpSDPath ) ||
                     ( '/0' == *pcTmpSDPath ) )
                {
                    continue;
                }

                // 如果字符串中含有/mnt/字符串,说明可能是我们要找的 SD 卡挂载路径
                if ( NULL == strstr( pcTmpSDPath, "/mnt/" ) &&
                     NULL == strstr( pcTmpSDPath, "/storage/" ) )
                {
                    continue;
                }

                // TODO: 在此添加对 SD 卡路径使用的语句,如果只是用其中一个,别忘了设置已找到想要 SD 卡路径的标识

            }while ( pcTmpSDPath = strtok( NULL, " " ) );
        }

        // 关闭标准 I/O 流,等待命令执行结束,然后返回 shell 的终止状态。
        // 如果 shell 不能被执行,
        // 则 pclose() 返回的终止状态与 shell 已执行 exit 一样。
        pclose( fp );
    }while ( 0 );

    一起学吧部分文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与一起学吧进行文章共享合作。

    广告
    广告
    广告