如何判断Android设备中的SD卡是否已挂载?

18

我正在开发一款Android应用程序,需要查看用户存储的图像。问题在于,如果用户通过USB电缆挂载了SD卡,我就无法读取磁盘上的图像列表。

有人知道如何判断USB是否已挂载,以便弹出消息通知用户它不起作用吗?


4
仅供参考,拔掉USB电缆并不是卸载SD卡的唯一方式 —— 在存储设置中卸载卡片或物理取出卡片也可以实现。此外,由T-Mobile UK提供的8GB SD卡没有正确预格式化,因此由于I/O,只要它们没有被正确重新格式化,它们就会一直被卸载。我只是想说,有时仅仅告诉用户拔掉电缆是不够的。 - Tamas Czinege
8个回答

41

如果您正在尝试访问设备上的图像,最好的方法是使用MediaStore内容提供程序。作为内容提供程序访问它将允许您查询存在的图像,并在适当的情况下将content:// URL映射到设备上的文件路径。

如果您仍然需要访问SD卡,则相机应用程序包括一个ImageUtils类,可以按以下方式检查SD卡是否已挂载:

static public boolean hasStorage(boolean requireWriteAccess) {
    //TODO: After fix the bug,  add "if (VERBOSE)" before logging errors.
    String state = Environment.getExternalStorageState();
    Log.v(TAG, "storage state is " + state);

    if (Environment.MEDIA_MOUNTED.equals(state)) {
        if (requireWriteAccess) {
            boolean writable = checkFsWritable();
            Log.v(TAG, "storage writable is " + writable);
            return writable;
        } else {
            return true;
        }
    } else if (!requireWriteAccess && Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        return true;
    }
    return false;
}

5
哦,有人提供了使用Android API的方法。点赞! - Neil Trodden
3
checkFsWritable(); 方法在哪里? - GrIsHu
我们需要 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> 来使它在外部存储上工作吗? - Anggrayudi H

9

这里是jargonjustin帖子中缺少的checkFsWritable函数。

private static boolean checkFsWritable() {
        // Create a temporary file to see whether a volume is really writeable.
        // It's important not to put it in the root directory which may have a
        // limit on the number of files.
        String directoryName = Environment.getExternalStorageDirectory().toString() + "/DCIM";
        File directory = new File(directoryName);
        if (!directory.isDirectory()) {
            if (!directory.mkdirs()) {
                return false;
            }
        }
        return directory.canWrite();
    }

3
public static boolean isSdPresent() {

return android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);

}

@MartinSmith 那里的源代码也是我。 - Harinder

2

在jargonjustin的帖子中:

文件ImageManager.java

方法hasStorage -->

该方法用于检查设备是否有可用存储空间。
public static boolean hasStorage(boolean requireWriteAccess) {
        String state = Environment.getExternalStorageState();

        if (Environment.MEDIA_MOUNTED.equals(state)) {
            if (requireWriteAccess) {
                boolean writable = checkFsWritable();
                return writable;
            } else {
                return true;
            }
        } else if (!requireWriteAccess
                && Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
            return true;
        }
        return false;
    }

方法 checkFsWritable -->

该方法检查文件系统是否可写。
 private static boolean checkFsWritable() {
        // Create a temporary file to see whether a volume is really writeable.
        // It's important not to put it in the root directory which may have a
        // limit on the number of files.
        String directoryName =
                Environment.getExternalStorageDirectory().toString() + "/DCIM";
        File directory = new File(directoryName);
        if (!directory.isDirectory()) {
            if (!directory.mkdirs()) {
                return false;
            }
        }
        File f = new File(directoryName, ".probe");
        try {
            // Remove stale file if any
            if (f.exists()) {
                f.delete();
            }
            if (!f.createNewFile()) {
                return false;
            }
            f.delete();
            return true;
        } catch (IOException ex) {
            return false;
        }
    }

2

很抱歉我发布了一个非Android的做法,希望有人能够使用Android API提供答案。

您可以列出SD卡根目录下的文件。如果没有文件,则表示SD卡完全为空(不常见,但可能),或未安装。如果您尝试在SD卡上创建一个空文件并且失败了,那么这意味着您正在尝试在SD卡的挂载点上创建一个文件,由于权限问题而被拒绝,因此您会知道SD卡未安装。

是的,我知道这很丑陋......


0

在处理外部存储器之前,您应该始终调用getExternalStorageState()来检查介质是否可用。介质可能已经被挂载到计算机上、丢失、只读或者处于其他状态。例如,这里有几种方法可以用来检查可用性:

/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state) ||
        Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        return true;
    }
    return false;
}

source: http://developer.android.com/guide/topics/data/data-storage.html


0

我使用游标从SD卡中检索图像,当设备中没有插入SD卡时,游标为空。 实际上,这是在通过从设备中物理移除卡片卸载SD卡卷时发生的情况。这是我使用的代码:

  Cursor mCursor = this.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, null);
    if (mCursor == null || !mCursor .moveToFirst()) {
                /**
                 *mCursor == null:
                 * - query failed; the app don't have access to sdCard; example: no sdCard 
                 *
                 *!mCursor.moveToFirst():
                 *     - there is no media on the device
                 */
            } else {
                 // process the images...
                 mCursor.close(); 
    }

更多信息:http://developer.android.com/guide/topics/media/mediaplayer.html#viacontentresolver


-1
Cool....Check it out...
try {
            File mountFile = new File("/proc/mounts");
            usbFoundCount=0;
            sdcardFoundCount=0;
            if(mountFile.exists())
             {
                Scanner usbscanner = new Scanner(mountFile);
                while (usbscanner.hasNext()) {
                    String line = usbscanner.nextLine();
                    if (line.startsWith("/dev/fuse /storage/usbcard1")) {
                        usbFoundCount=1;
                        Log.i("-----USB--------","USB Connected and properly mounted---/dev/fuse /storage/usbcard1" );
                    }
            }
         }
            if(mountFile.exists()){
                Scanner sdcardscanner = new Scanner(mountFile);
                while (sdcardscanner.hasNext()) {
                    String line = sdcardscanner.nextLine();
                    if (line.startsWith("/dev/fuse /storage/sdcard1")) {
                        sdcardFoundCount=1;
                        Log.i("-----USB--------","USB Connected and properly mounted---/dev/fuse /storage/sdcard1" );
                    }
            }
         }
            if(usbFoundCount==1)
            {
                Toast.makeText(context,"USB Connected and properly mounted", 7000).show();
                Log.i("-----USB--------","USB Connected and properly mounted" );
            }
            else
            {
                Toast.makeText(context,"USB not found!!!!", 7000).show();
                Log.i("-----USB--------","USB not found!!!!" );

            }
            if(sdcardFoundCount==1)
            {
                Toast.makeText(context,"SDCard Connected and properly mounted", 7000).show();
                Log.i("-----SDCard--------","SDCard Connected and properly mounted" );
            }
            else
            {
                Toast.makeText(context,"SDCard not found!!!!", 7000).show();
                Log.i("-----SDCard--------","SDCard not found!!!!" );

            }
        }catch (Exception e) {
            e.printStackTrace();
        } 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接