以编程方式检查SD卡是否可用

58

我的应用仅适用于有SD卡的移动设备。因此,我想通过编程来检查SD卡是否可用以及如何查找SD卡的剩余空间。这是否可以实现?

如果可以,我该怎么做呢?


“仅支持SD卡”是什么意思?你的意思是它没有内部存储器吗?这很难想象。 - LarsH
12个回答

138
Boolean isSDPresent = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
Boolean isSDSupportedDevice = Environment.isExternalStorageRemovable();

if(isSDSupportedDevice && isSDPresent)
{
  // yes SD-card is present
}
else
{
 // Sorry
}

3
如何检查SD卡的剩余空间? - naresh
49
如果手机有内置存储,则它会返回true,因此这不是正确的答案。 - User10001
22
判断外部存储是否为SD卡,请结合使用上述内容和:Environment.isExternalStorageRemovable() - user608578
2
这适用于没有SD卡,只有内部存储器的设备返回真。 - Tom Kincaid
3
针对模拟外部存储而言,这显然是一个错误答案。理想情况下应该使用Environment.isExternalStorageRemovable()。您也可以查看Environment.isExternalStorageEmulated()。@naresh 您不应接受部分回答。 - atuljangra
显示剩余6条评论

24

被接受的答案对我没用。

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

如果设备有内置存储,则返回true;我的解决方案是检查外部文件目录的数量,如果大于1,则设备具有SD卡。 它有效,并且我已经对多个设备进行了测试。

public static boolean hasRealRemovableSdCard(Context context) {
    return ContextCompat.getExternalFilesDirs(context, null).length >= 2;
}

1
但是,如果设备上有插槽而SD卡未插入,则长度显示为2。文件数组具有null文件。不管怎样,这对我来说是最好的解决方案 :) - Jyoti JK
@JemoMgebrishvili 我在三星 J2 (API 22) 5.1 上测试过了,运行良好。非常感谢。 - M DEV
ContextCompat.getExternalFilesDirs 在某些设备上会出现 ANR。 - Yasiru Nayanajith

16

您可以按照以下方式检查外置可移动SD卡是否可用

public static boolean externalMemoryAvailable(Activity context) {
    File[] storages = ContextCompat.getExternalFilesDirs(context, null);
    if (storages.length > 1 && storages[0] != null && storages[1] != null)
        return true;
    else
        return false;

}

我已经测试过,这个功能完美运作。


我已在三星A70s上进行了测试,无论是带有还是没有外部(可拆卸)SD卡,在这两种情况下,它都可以正常工作。我尝试了其他人提出的所有建议解决方案,但只有这个能够正确地工作。希望对所有设备都有效。非常感谢。 - Shailesh

15

按照"使用外部存储"中的描述,使用Environment.getExternalStorageState()

要获取外部存储空间的可用空间,请使用StatFs

// do this only *after* you have checked external storage state:
File extdir = Environment.getExternalStorageDirectory();
File stats = new StatFs(extdir.getAbsolutePath());
int availableBytes = stats.getAvailableBlocks() * stats.getBlockSize();

5

我写了一个小类来检查存储状态,也许对你有用。

import android.os.Environment;

/**
 * Checks the state of the external storage of the device.
 * 
 * @author kaolick
 */
public class StorageHelper
{
// Storage states
private boolean externalStorageAvailable, externalStorageWriteable;

/**
 * Checks the external storage's state and saves it in member attributes.
 */
private void checkStorage()
{
// Get the external storage's state
String state = Environment.getExternalStorageState();

if (state.equals(Environment.MEDIA_MOUNTED))
{
    // Storage is available and writeable
    externalStorageAvailable = externalStorageWriteable = true;
}
else if (state.equals(Environment.MEDIA_MOUNTED_READ_ONLY))
{
    // Storage is only readable
    externalStorageAvailable = true;
    externalStorageWriteable = false;
}
else
{
    // Storage is neither readable nor writeable
    externalStorageAvailable = externalStorageWriteable = false;
}
}

/**
 * Checks the state of the external storage.
 * 
 * @return True if the external storage is available, false otherwise.
 */
public boolean isExternalStorageAvailable()
{
checkStorage();

return externalStorageAvailable;
}

/**
 * Checks the state of the external storage.
 * 
 * @return True if the external storage is writeable, false otherwise.
 */
public boolean isExternalStorageWriteable()
{
checkStorage();

return externalStorageWriteable;
}

/**
 * Checks the state of the external storage.
 * 
 * @return True if the external storage is available and writeable, false
 *         otherwise.
 */    
public boolean isExternalStorageAvailableAndWriteable()
{
checkStorage();

if (!externalStorageAvailable)
{
    return false;
}
else if (!externalStorageWriteable)
{
    return false;
}
else
{
    return true;
}
}
}

这个类能帮助检测SD卡的可用性吗? - Pankaj Nimgade
这个类可以帮助你检查外部存储是否可用或可写。外部存储可以是SD卡,也可以是类似于Nexus设备中的内置存储。@PankajNimgade - kaolick
能否具体检查“sdcard”?谢谢。 - Pankaj Nimgade
@PankajNimgade 我不知道有没有这样的功能。我建议在这里阅读有关内部和外部存储的信息:https://developer.android.com/guide/topics/data/data-storage.html - kaolick
浏览了许多相关文档,谷歌并没有明确区分“设备上可用的外部存储”和“SD卡”之间的具体区别....... :( - Pankaj Nimgade

4
我修改了它,如果存在SD卡,则将路径设置在SD卡上。如果没有,则将其设置为内部目录。
Boolean isSDPresent = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
if(isSDPresent)
{
    path = theAct.getExternalCacheDir().getAbsolutePath() + "/GrammarFolder";
}
else
{
    path = theAct.getFilesDir() + "/GrammarFolder";
}

3
 void updateExternalStorageState() {
     String state = Environment.getExternalStorageState();
     if (Environment.MEDIA_MOUNTED.equals(state)) {
        mExternalStorageAvailable = mExternalStorageWriteable = true;
     } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        mExternalStorageAvailable = true;
       mExternalStorageWriteable = false;
     } else {
       mExternalStorageAvailable = mExternalStorageWriteable = false;
}
handleExternalStorageState(mExternalStorageAvailable,
        mExternalStorageWriteable);
}

2

这个简单的方法对我很有效,在所有类型的设备上测试过。

public boolean externalMemoryAvailable() {
    if (Environment.isExternalStorageRemovable()) {
      //device support sd card. We need to check sd card availability.
      String state = Environment.getExternalStorageState();
      return state.equals(Environment.MEDIA_MOUNTED) || state.equals(
          Environment.MEDIA_MOUNTED_READ_ONLY);
    } else {
      //device not support sd card. 
      return false;
    }
  }

2

Kotlin

fun Context.externalMemoryAvailable(): Boolean {
    val storages = ContextCompat.getExternalFilesDirs(this, null)
    return storages.size > 1 && storages[0] != null && storages[1] != null
}

1
  public static boolean hasSdCard(Context context) {

    File[] dirs = context.getExternalFilesDirs("");        
    if(dirs.length >= 2 && dirs[1]!=null){
        if(Environment.isExternalStorageRemovable(dirs[1])){ // Extra Check
            return true;
        }
     }
    return false;
   }

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