如何获取Android设备的已安装外部存储列表

时间:2012-02-18 10:18:21

标签: android

这里我们正在为Android电视盒开发Android应用程序。如何获取已安装的外部存储列表,如USB stick, SDCARD and SATA HDD.

6 个答案:

答案 0 :(得分:60)

我使用 / proc / mounts 文件获取可用存储空间选项列表

public class StorageUtils {

    private static final String TAG = "StorageUtils";

    public static class StorageInfo {

        public final String path;
        public final boolean readonly;
        public final boolean removable;     
        public final int number;

        StorageInfo(String path, boolean readonly, boolean removable, int number) {
            this.path = path;
            this.readonly = readonly;
            this.removable = removable;         
            this.number = number;
        }

        public String getDisplayName() {
            StringBuilder res = new StringBuilder();
            if (!removable) {
                res.append("Internal SD card");
            } else if (number > 1) {
                res.append("SD card " + number);
            } else {
                res.append("SD card");
            }
            if (readonly) {
                res.append(" (Read only)");
            }
            return res.toString();
        }
    }

    public static List<StorageInfo> getStorageList() {

        List<StorageInfo> list = new ArrayList<StorageInfo>();
        String def_path = Environment.getExternalStorageDirectory().getPath();
        boolean def_path_removable = Environment.isExternalStorageRemovable();
        String def_path_state = Environment.getExternalStorageState();
        boolean def_path_available = def_path_state.equals(Environment.MEDIA_MOUNTED)
                                    || def_path_state.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
        boolean def_path_readonly = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED_READ_ONLY);

        HashSet<String> paths = new HashSet<String>();
        int cur_removable_number = 1;

        if (def_path_available) {
            paths.add(def_path);
            list.add(0, new StorageInfo(def_path, def_path_readonly, def_path_removable, def_path_removable ? cur_removable_number++ : -1));
        }

        BufferedReader buf_reader = null;
        try {
            buf_reader = new BufferedReader(new FileReader("/proc/mounts"));
            String line;
            Log.d(TAG, "/proc/mounts");
            while ((line = buf_reader.readLine()) != null) {
                Log.d(TAG, line);
                if (line.contains("vfat") || line.contains("/mnt")) {
                    StringTokenizer tokens = new StringTokenizer(line, " ");
                    String unused = tokens.nextToken(); //device
                    String mount_point = tokens.nextToken(); //mount point
                    if (paths.contains(mount_point)) {
                        continue;
                    }
                    unused = tokens.nextToken(); //file system
                    List<String> flags = Arrays.asList(tokens.nextToken().split(",")); //flags
                    boolean readonly = flags.contains("ro");

                    if (line.contains("/dev/block/vold")) {
                        if (!line.contains("/mnt/secure")
                            && !line.contains("/mnt/asec")
                            && !line.contains("/mnt/obb")
                            && !line.contains("/dev/mapper")
                            && !line.contains("tmpfs")) {
                            paths.add(mount_point);
                            list.add(new StorageInfo(mount_point, readonly, true, cur_removable_number++));
                        }
                    }
                }
            }

        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            if (buf_reader != null) {
                try {
                    buf_reader.close();
                } catch (IOException ex) {}
            }
        }
        return list;
    }
}

答案 1 :(得分:10)

要获取所有可用的外部存储文件夹(包括SD卡),您可以使用:

File[] externalStorageFiles=ContextCompat.getExternalFilesDirs(this,null);

转到&#34; root&#34;每个外部存储(一个是真正的安装文件夹路径),你可以使用我已经做过的这个功能:

  /** Given any file/folder inside an sd card, this will return the path of the sd card */
  private static String getRootOfInnerSdCardFolder(File file)
    {
    if(file==null)
      return null;
    final long totalSpace=file.getTotalSpace();
    while(true)
      {
      final File parentFile=file.getParentFile();
      if(parentFile==null||parentFile.getTotalSpace()!=totalSpace)
        return file.getAbsolutePath();
      file=parentFile;
      }
    }

答案 2 :(得分:7)

Environment.getExternalStorageState()返回内部SD挂载点的路径,如&#34; / mnt / sdcard&#34;

不,Environment.getExternalStorageDirectory()指的是设备制造商认为的外部存储&#34;。在某些设备上,这是可移动媒体,如SD卡。在某些设备上,这是设备上闪存的一部分。在这里,&#34;外部存储&#34;意味着&#34;当安装在主机上时,可通过USB大容量存储模式访问的东西&#34;,至少对于Android 1.x和2.x。

但问题是关于外部SD。如何获得类似&#34; / mnt / sdcard / external_sd&#34;的路径(它可能因设备而异)?

除了外部存储之外,Android没有&#34;外部SD&#34;的概念,如上所述。

如果设备制造商选择将外部存储设备作为板载闪存并且还具有SD卡,则需要与该制造商联系以确定是否可以使用SD卡(不保证)以及规则用于使用它,例如使用它的路径。

试试这个:

的Manifest.xml:

<receiver android:name=".MyReceiver">
    <intent-filter>
         <action android:name="android.intent.action.ums_connected" />
     </intent-filter>
  </receiver>

Myreceiver:

public class MyReceiver extends BroadcastReceiver{
if (intent.getAction().equalsIgnoreCase(
        "android.intent.action.UMS_CONNECTED")) {...}
}

答案 3 :(得分:2)

另一种选择。

首先获取所有外部文件dirs

File[] externalStorageFiles=ContextCompat.getExternalFilesDirs(this,null);

然后为每个文件夹

调用此函数
private static String getRootOfExternalStorage(File file)
{
    if (file == null)
        return null;
    String path = file.getAbsolutePath();
    return path.replaceAll("/Android/data/" + getPackageName() + "/files", "");
}

答案 4 :(得分:1)

您可以使用getExternalStorageDirectory()获取外部存储目录。该文档很好地解释了它的用法http://developer.android.com/reference/android/os/Environment.html#getExternalStorageDirectory%28%29

对于USB设备,您可能需要查看UsbManager课程或更常见的android.hardware.usb http://developer.android.com/reference/android/hardware/usb/UsbManager.html

答案 5 :(得分:0)

我现在这个话题已经过时但这可能有所帮助。你应该使用这种方法。

System.getenv();

请参阅项目Environment3以访问连接到您设备的所有存储。

https://github.com/omidfaraji/Environment3