2016-12-07 42 views
0

我用来从"/storage/external_storage"得到USB/SD卡的所有文件,像这样Android的 - API 23无法获取USB/SD卡目录

File = new File("/storage/external_storage"); 
file.listFiles() 

,并显示在我自己的Fragment的文件和文件夹并且它在API 23之前运行良好。现在,我无法从路径中获取文件列表。

我知道在Android Marshmallow(23)有权限更改一些USB Connection行为改变。

如果您的应用支持用户通过USB端口与设备进行交互,请考虑必须明确启用交互。

没有说明如何或何时用户可以明确地启用交互

我的问题是是否有可能访问USB文件和文件夹列表。 如果有什么可以做到这一点?

编辑:我打开Android设备监视器,我找不到external_storage/storage/external_storage

+0

您需要实现运行时权限或设置目标api版本22. – phnmnn

+0

请注意,不要硬编码路径,而应使用[getExternalStorageDirectory()](https://developer.android.com/reference/ android/os/Environment.html#getExternalStorageDirectory()) – Mudassir

+0

@phnmnn谢谢你的回复。我需要定位api 23.但是我已经有了写权限。除非需要一些新的USB/SD卡权限? – Abbas

回答

0

确实,文档不是很清楚......但似乎您必须要求系统为您安装媒体设备。你可以尝试使用 Environment.getExternalStorageState()看看它回报你吗?

否则,你也可以尝试使用这个类来访问SD /外部USB:

public class ExternalStorage { 

public static final String SD_CARD = "sdCard"; 
public static final String EXTERNAL_SD_CARD = "externalSdCard"; 

/** 
* @return True if the external storage is available. False otherwise. 
*/ 
public static boolean isAvailable() { 
    String state = Environment.getExternalStorageState(); 
    if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { 
     return true; 
    } 
    return false; 
} 

public static String getSdCardPath() { 
    return Environment.getExternalStorageDirectory().getPath() + "/"; 
} 

/** 
* @return True if the external storage is writable. False otherwise. 
*/ 
public static boolean isWritable() { 
    String state = Environment.getExternalStorageState(); 
    if (Environment.MEDIA_MOUNTED.equals(state)) { 
     return true; 
    } 
    return false; 

} 

/** 
* @return A map of all storage locations available 
*/ 
public static Map<String, File> getAllStorageLocations() { 
    Map<String, File> map = new HashMap<String, File>(10); 

    List<String> mMounts = new ArrayList<String>(10); 
    List<String> mVold = new ArrayList<String>(10); 
    mMounts.add("/mnt/sdcard"); 
    mVold.add("/mnt/sdcard"); 

    try { 
     File mountFile = new File("/proc/mounts"); 
     if(mountFile.exists()){ 
      Scanner scanner = new Scanner(mountFile); 
      while (scanner.hasNext()) { 
       String line = scanner.nextLine(); 
       if (line.startsWith("/dev/block/vold/")) { 
        String[] lineElements = line.split(" "); 
        String element = lineElements[1]; 

        // don't add the default mount path 
        // it's already in the list. 
        if (!element.equals("/mnt/sdcard")) 
         mMounts.add(element); 
       } 
      } 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    try { 
     File voldFile = new File("/system/etc/vold.fstab"); 
     if(voldFile.exists()){ 
      Scanner scanner = new Scanner(voldFile); 
      while (scanner.hasNext()) { 
       String line = scanner.nextLine(); 
       if (line.startsWith("dev_mount")) { 
        String[] lineElements = line.split(" "); 
        String element = lineElements[2]; 

        if (element.contains(":")) 
         element = element.substring(0, element.indexOf(":")); 
        if (!element.equals("/mnt/sdcard")) 
         mVold.add(element); 
       } 
      } 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 


    for (int i = 0; i < mMounts.size(); i++) { 
     String mount = mMounts.get(i); 
     if (!mVold.contains(mount)) 
      mMounts.remove(i--); 
    } 
    mVold.clear(); 

    List<String> mountHash = new ArrayList<String>(10); 

    for(String mount : mMounts){ 
     File root = new File(mount); 
     if (root.exists() && root.isDirectory() && root.canWrite()) { 
      File[] list = root.listFiles(); 
      String hash = "["; 
      if(list!=null){ 
       for(File f : list){ 
        hash += f.getName().hashCode()+":"+f.length()+", "; 
       } 
      } 
      hash += "]"; 
      if(!mountHash.contains(hash)){ 
       String key = SD_CARD + "_" + map.size(); 
       if (map.size() == 0) { 
        key = SD_CARD; 
       } else if (map.size() == 1) { 
        key = EXTERNAL_SD_CARD; 
       } 
       mountHash.add(hash); 
       map.put(key, root); 
      } 
     } 
    } 

    mMounts.clear(); 

    if(map.isEmpty()){ 
      map.put(SD_CARD, Environment.getExternalStorageDirectory()); 
    } 
    return map; 
} 
} 

使用是这样的:

Map<String, File> externalLocations = ExternalStorage.getAllStorageLocations(); 
File sdCard = externalLocations.get(ExternalStorage.SD_CARD); 
File externalSdCard = externalLocations.get(ExternalStorage.EXTERNAL_SD_CARD); 

来源的位置:Find an external SD card location

+0

'Environment.getExternalStorageState()'返回“挂载”,我想这应该是USB连接时应该得到的。但是在'Environment.getExternalStorageDirectory()'我得到本地共享目录路径。我会给ExternalStorage一个镜头,然后回复你。 – Abbas

+0

我试过你的代码,但它不起作用。我得到了“mnt/sdcard”这个共享位置的路径。 – Abbas

+0

这个代码根本没有意义。 – greenapps

0

看看getExternalFilesDirs()。 如果插入了micro SD卡,则第二个条目将指向该卡。 如果您随后连接USB OTG驱动器,则第三项将指向驱动器。

借助Intent.ACTION_OPEN_DOCUMENT_TREE,您可以让用户从所有驱动器中进行选择,然后使用Storage Access Framework。

+0

我会检查并回复你。 – Abbas

相关问题