【问题标题】:Get the public/root directory of a secondary external storage device in Android?在Android中获取辅助外部存储设备的公共/根目录?
【发布时间】:2017-08-29 09:41:32
【问题描述】:

在 android 中,我可以通过以下方式获取手机的可移动外部存储:

for (File f : context.getExternalFilesDirs("/")) 
    if (Environment.isExternalStorageRemovable(f))
        Log.println(Log.DEBUG, "#", f.getAbsolutePath());

但是,这会返回 /storage/8E6A-06FF/Android/data/test.application/files,这不是我想要的,因为我只想要可移动设备的根路径 /storage/8E6A-06FF/。如何获取手机移动存储的根路径?

【问题讨论】:

  • 你已经有了那个路径。只需删除以 /Android/.. 开头的多余部分即可
  • @greenapps getExternalStorageDirectory() 返回手机不可移动的主存储,而不是辅助存储。至于删除/Android/,你能确定/Android/会在每部安卓手机的路径中吗?
  • 是的。我从未见过其他任何东西。
  • Paths.get(path_string).getParent()
  • @greenapps 你知道/storage 是否一直存在吗?在这种情况下,我可以使用 while 循环,直到 .getParent() 返回存储空间。

标签: android android-external-storage


【解决方案1】:

你可以试试这个,它对我来说很完美。它在所有 Os 版本中都像一个魅力。到目前为止,我没有发现这个功能有任何问题。

public static String getSDPath() {
    String filepath = "";
    String[] strPath = {"/storage/sdcard1", "/storage/extsdcard",
            "/storage/sdcard0/external_sdcard", "/mnt/extsdcard",
            "/mnt/sdcard/external_sd", "/mnt/external_sd",
            "/mnt/media_rw/sdcard1", "/removable/microsd", "/mnt/emmc",
            "/storage/external_SD", "/storage/ext_sd",
            "/storage/removable/sdcard1", "/data/sdext", "/data/sdext2",
            "/data/sdext3", "/data/sdext4", "/emmc", "/sdcard/sd",
            "/mnt/sdcard/bpemmctest", "/mnt/sdcard/_ExternalSD",
            "/mnt/sdcard-ext", "/mnt/Removable/MicroSD",
            "/Removable/MicroSD", "/mnt/external1", "/mnt/extSdCard",
            "/mnt/extsd", "/mnt/usb_storage", "/mnt/extSdCard",
            "/mnt/UsbDriveA", "/mnt/UsbDriveB"};

    for (String value : strPath) {
        File f = null;
        f = new File(value);
        if (f.exists() && f.isDirectory()) {
            filepath = value;
            break;
        }
    }
    return filepath;
}

【讨论】:

  • 这段代码有更新吗?还是仍然可以完美运行?
  • @quetzalfi 无需为此更新。这很好用,先生 :) 您只需要在获取目录之前检查外部权限,从 7.0 开始,您还需要实现 xml 路径和权限。我希望知道它。
【解决方案2】:

试试这个:

for (File f : context.getExternalFilesDirs("/")) 
    if (Environment.isExternalStorageRemovable(f))
        Log.println(Log.DEBUG, "#", f.getParentFile().getParentFile().getParentFile().getParent());

context.getExternalFilesDirs() 将始终返回特定于应用程序的目录。但好在应用程序特定的目录总是距存储设备的根文件夹 4 级深。因此,在 File f 上调用 getParentFile() 四次而不是 f.getAbsolutePath() 将获得手机可移动存储的根路径。

【讨论】:

  • 还有人如何写入该存储空间?这实际上仍然有效,但我无法写入存储
【解决方案3】:

也许只是将其拆分为Android

我测试了它,它在我 request for permission - WRITE_EXTERNAL_STORAGE 之后工作。

fun getBaseDir(dir: File): String {
    val absPath = dir.absolutePath
    return if (absPath.contains("/Android")) {
        absPath.split("/Android")[0]
    } else {
        absPath
    }
}

【讨论】:

    【解决方案4】:

    这将遍历 sdcard 根目录中的文件。如果您想要主存储,只需将 [1] 更改为 [0]。 getExternalFilesDirs 返回主存储和辅助存储上您的应用目录的路径。通过“Android”分割第二个路径后,第一个字符串将包含您的辅助存储根的路径。例如,在我的情况下,它是“/storage/B242-37B2/”。使用 minSdkVersion 19+

                String sdCardRoot = ContextCompat.getExternalFilesDirs(getApplicationContext(), null)[1].getAbsolutePath().split("Android")[0];
    
                File f = new File(sdCardRoot);
                File[] files = f.listFiles();
    
                for (File inFile : files){
                    Log.d("Files", inFile.getName());
                }
    

    【讨论】:

      【解决方案5】:

      如果对你有帮助,试试这个。更多信息请参考this link

      public static HashSet<String> getExternalMounts() {
          final HashSet<String> out = new HashSet<String>();
          String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*";
          String s = "";
          try {
              final Process process = new ProcessBuilder().command("mount")
                      .redirectErrorStream(true).start();
              process.waitFor();
              final InputStream is = process.getInputStream();
              final byte[] buffer = new byte[1024];
              while (is.read(buffer) != -1) {
                  s = s + new String(buffer);
              }
              is.close();
          } catch (final Exception e) {
              e.printStackTrace();
          }
      
          // parse output
          final String[] lines = s.split("\n");
          for (String line : lines) {
              if (!line.toLowerCase(Locale.US).contains("asec")) {
                  if (line.matches(reg)) {
                      String[] parts = line.split(" ");
                      for (String part : parts) {
                          if (part.startsWith("/"))
                              if (!part.toLowerCase(Locale.US).contains("vold"))
                                  out.add(part);
                      }
                  }
              }
          }
          return out;
      }
      

      这是相同的另一种方法。来源here

      Environment.getExternalStorageState() 返回内部 SD 的路径 像“/mnt/sdcard”这样的挂载点

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

      如上所述,除了外部存储之外,Android 没有“外部 SD”的概念。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-12
        • 2015-03-18
        • 1970-01-01
        • 1970-01-01
        • 2016-07-31
        • 2017-02-12
        相关资源
        最近更新 更多