2016-04-21 22 views
8

我想檢查是否有外部存儲器或設備不使用這樣的下面如何獲得在android6.0編程

if (new File("/ext_card/").exists()) { 
     specialPath = "/ext_card/"; 
    } else if (new File("/mnt/sdcard/external_sd/").exists()) { 
     specialPath = "/mnt/sdcard/external_sd/"; 
    } else if (new File("/storage/extSdCard/").exists()) { 
     specialPath = "/storage/extSdCard/"; 
    } else if (new File("/mnt/extSdCard/").exists()) { 
     specialPath = "/mnt/extSdCard/"; 
    } else if (new File("/mnt/sdcard/external_sd/").exists()) { 
     specialPath = "/mnt/sdcard/external_sd/"; 
    } else if (new File("storage/sdcard1/").exists()) { 
     specialPath = "storage/sdcard1/"; 
    } 

但在棉花糖給定的外部存儲路徑SD_Card路徑I續找到這在使用ES FILEMANAGER進行檢查時,他們給Moto G第三代存儲/ 3263-3131。雖然檢查其他棉花糖設備,數量變得不同。請幫我檢查棉花糖設備是否有外部存儲?如果找到存儲意味着如何獲得外部存儲的路徑?

注意: - 我在我的應用程序中授予了存儲權限,並且在我的應用程序的設置中啓用了存儲權限。

在此先感謝您,並且您是否發現我的問題中有任何錯誤,請立即通知。再次感謝你。

+0

請告訴我爲什麼要爲這個問題投票嗎?如果有人知道答案這意味着請讓我知道... – Palanivelraghul

回答

13

這裏的我的解決方案,這是保證工作到Android 7.0牛軋糖:

/* returns external storage paths (directory of external memory card) as array of Strings */ 
public String[] getExternalStorageDirectories() { 

     List<String> results = new ArrayList<>(); 

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //Method 1 for KitKat & above 
     File[] externalDirs = getExternalFilesDirs(null); 

     for (File file : externalDirs) { 
      String path = file.getPath().split("/Android")[0]; 

      boolean addPath = false; 

      if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
       addPath = Environment.isExternalStorageRemovable(file); 
      } 
      else{ 
       addPath = Environment.MEDIA_MOUNTED.equals(EnvironmentCompat.getStorageState(file)); 
      } 

      if(addPath){ 
       results.add(path); 
      } 
     } 
    } 

     if(results.isEmpty()) { //Method 2 for all versions 
      // better variation of: http://stackoverflow.com/a/4/5002496 
      String output = ""; 
      try { 
       final Process process = new ProcessBuilder().command("mount | grep /dev/block/vold") 
       .redirectErrorStream(true).start(); 
       process.waitFor(); 
       final InputStream is = process.getInputStream(); 
       final byte[] buffer = new byte[1024]; 
       while (is.read(buffer) != -1) { 
        output = output + new String(buffer); 
       } 
       is.close(); 
      } catch (final Exception e) { 
       e.printStackTrace(); 
      } 
      if(!output.trim().isEmpty()) { 
       String devicePoints[] = output.split("\n"); 
       for(String voldPoint: devicePoints) { 
        results.add(voldPoint.split(" ")[2]); 
       } 
      } 
     } 

     //Below few lines is to remove paths which may not be external memory card, like OTG (feel free to comment them out) 
     if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
      for (int i = 0; i < results.size(); i++) { 
       if (!results.get(i).toLowerCase().matches(".*[0-9a-f]{4}[-][0-9a-f]{4}")) { 
        Log.d(LOG_TAG, results.get(i) + " might not be extSDcard"); 
        results.remove(i--); 
       } 
      } 
     } else { 
      for (int i = 0; i < results.size(); i++) { 
       if (!results.get(i).toLowerCase().contains("ext") && !results.get(i).toLowerCase().contains("sdcard")) { 
        Log.d(LOG_TAG, results.get(i)+" might not be extSDcard"); 
        results.remove(i--); 
       } 
      } 
     } 

     String[] storageDirectories = new String[results.size()]; 
     for(int i=0; i<results.size(); ++i) storageDirectories[i] = results.get(i); 

     return storageDirectories; 
    } 
+0

感謝您的答案。我會檢查並讓你知道你使用了「正則表達式」來過濾掉可能不是SD卡的路徑 – Palanivelraghul

+0

。你可以請分享可用的Android設備(特別是三星)具有SD卡路徑匹配此表達式的百分比的可能性。我有一個設備的SD卡路徑爲**/Storage/A5F9-15F4/**,並且表達能夠正常工作,但我想確定其他三星設備是否能夠通過此檢查。如果您有任何關於此的信息,請提供幫助。謝謝 –

+0

@Abdul實際上稱爲[Volume ID](https://www.google.com/search?q=volume+id)或[Volume Serial Number](https://en.wikipedia.org/wiki/Volume_serial_number )這就是外部SD卡目錄是如何綁定自棉花糖..該正則表達式將匹配卷ID沒有任何問題 –

3

我發現這個解決方案在這裏https://stackoverflow.com/a/13648873/842607

的代碼 -

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; 
} 

另一種是我在同一頁面中發現的黑客 -

private static final Pattern DIR_SEPORATOR = Pattern.compile("/"); 

/** 
* Raturns all available SD-Cards in the system (include emulated) 
* 
* Warning: Hack! Based on Android source code of version 4.3 (API 18) 
* Because there is no standart way to get it. 
* TODO: Test on future Android versions 4.4+ 
* 
* @return paths to all available SD-Cards in the system (include emulated) 
*/ 
public static String[] getStorageDirectories() 
{ 
    // Final set of paths 
    final Set<String> rv = new HashSet<String>(); 
    // Primary physical SD-CARD (not emulated) 
    final String rawExternalStorage = System.getenv("EXTERNAL_STORAGE"); 
    // All Secondary SD-CARDs (all exclude primary) separated by ":" 
    final String rawSecondaryStoragesStr = System.getenv("SECONDARY_STORAGE"); 
    // Primary emulated SD-CARD 
    final String rawEmulatedStorageTarget = System.getenv("EMULATED_STORAGE_TARGET"); 
    if(TextUtils.isEmpty(rawEmulatedStorageTarget)) 
    { 
     // Device has physical external storage; use plain paths. 
     if(TextUtils.isEmpty(rawExternalStorage)) 
     { 
      // EXTERNAL_STORAGE undefined; falling back to default. 
      rv.add("/storage/sdcard0"); 
     } 
     else 
     { 
      rv.add(rawExternalStorage); 
     } 
    } 
    else 
    { 
     // Device has emulated storage; external storage paths should have 
     // userId burned into them. 
     final String rawUserId; 
     if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) 
     { 
      rawUserId = ""; 
     } 
     else 
     { 
      final String path = Environment.getExternalStorageDirectory().getAbsolutePath(); 
      final String[] folders = DIR_SEPORATOR.split(path); 
      final String lastFolder = folders[folders.length - 1]; 
      boolean isDigit = false; 
      try 
      { 
       Integer.valueOf(lastFolder); 
       isDigit = true; 
      } 
      catch(NumberFormatException ignored) 
      { 
      } 
      rawUserId = isDigit ? lastFolder : ""; 
     } 
     // /storage/emulated/0[1,2,...] 
     if(TextUtils.isEmpty(rawUserId)) 
     { 
      rv.add(rawEmulatedStorageTarget); 
     } 
     else 
     { 
      rv.add(rawEmulatedStorageTarget + File.separator + rawUserId); 
     } 
    } 
    // Add all secondary storages 
    if(!TextUtils.isEmpty(rawSecondaryStoragesStr)) 
    { 
     // All Secondary SD-CARDs splited into array 
     final String[] rawSecondaryStorages = rawSecondaryStoragesStr.split(File.pathSeparator); 
     Collections.addAll(rv, rawSecondaryStorages); 
    } 
    return rv.toArray(new String[rv.size()]); 
} 
+0

和我都工作順利....檢查是否可以幫助你出 –

+0

感謝您的答案我會檢查,讓你知道 – Palanivelraghul

0

在這裏我有redmi note prime 2.and我沒有記憶card.so當我找到路徑和File [] externalDirs = getExternalFilesDirs(null);給出文件[]的空秒位置值。 }

+0

如果沒有SD卡,它返回null。所以通過這個結果你需要識別 – Palanivelraghul