2012-02-18 3 views
17

Qui stiamo sviluppando app Android per Android TV Box. Come posso ottenere l'elenco di memoria esterna montata come USB stick, SDCARD and SATA HDD.Come posso ottenere l'elenco della memoria esterna montata del dispositivo Android

+0

ora questo tema è vecchio ma questo può aiutare. dovresti usare il metodo. System.getenv(); vedere il progetto Ambiente3 per accedere a tutti gli archivi collegati al dispositivo. https://github.com/omidfaraji/Environment3 –

risposta

1

È possibile utilizzare lo getExternalStorageDirectory() per ottenere la directory di archiviazione esterna. La documentazione dà una buona spiegazione del suo utilizzo http://developer.android.com/reference/android/os/Environment.html#getExternalStorageDirectory%28%29

Per i dispositivi USB che probabilmente deve guardare nella classe UsbManager o più in generale android.hardware.usbhttp://developer.android.com/reference/android/hardware/usb/UsbManager.html

+0

Grazie mille shiraz Per impostazione predefinita mostra solo SDCARD, in alcuni casi può essere chiavetta USB o SATA HDD. Per questo cosa devo fare –

+0

Grazie ancora per il tuo sforzo .... Ma è api livello 12 (Android 3.0). Ma sto usando Android 2.2 e 2.3. E 'possibile con Android 2.2 o 2.3 –

+1

Per me, 'getExternalStorageDirectory()' non funziona, perché restituisce sdcard0 - questa è la memoria interna. Ho Samsung Galaxy Note 2. – Peter

7

Environment.getExternalStorageState() ritorna percorso SD interna punto, come "/ mnt/sdcard" mount

No, Environment.getExternalStorageDirectory() si riferisce a qualunque sia il produttore del dispositivo considerato "memoria esterna". Su alcuni dispositivi, questo è un supporto rimovibile, come una scheda SD. Su alcuni dispositivi, questa è una parte del flash sul dispositivo. Qui, "memoria esterna" significa "le cose accessibili tramite la modalità di archiviazione di massa USB quando montate su una macchina host", almeno per Android 1.xe 2.x.

Ma la domanda riguarda la SD esterna. Come ottenere un percorso come "/ mnt/sdcard/external_sd" (potrebbe differire da dispositivo a dispositivo)?

Android non ha il concetto di "SD esterna", a parte l'archiviazione esterna, come descritto sopra.

Se il produttore di un dispositivo ha scelto di avere memoria esterna come flash integrato e dispone anche di una scheda SD, è necessario contattare il produttore per determinare se è possibile utilizzare o meno la scheda SD (non garantita) e che le regole sono per usarlo, ad esempio quale percorso utilizzare per questo.

Prova questo fuori:

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")) {...} 
} 
+0

Ciao Shishir ... Grazie ... –

+0

In qualsiasi momento fratello :) –

+0

Ciao Shishir ... Grazie ... Ma questo dispositivo ha uno slot per schede Sd e due porte host USB. Quindi l'utente finale può utilizzare qualsiasi memoria di massa USB. In questo caso devo dare delle opzioni. Ora Sdcard funziona abbastanza bene con "Environment.getExternalStorageDirectory()" –

55

Io uso /proc/mounts di file per ottenere l'elenco di opzioni di archiviazione disponibili

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

In realtà, questa è la risposta migliore, fa esattamente ciò che l'OP chiedeva. – WonderCsabo

+1

Questo non funziona con schede SD di grandi dimensioni che utilizzano il filesystem exfat, controllare: http://stackoverflow.com/questions/11281010/how-can-i-get-external-sd-card-path-for-android-4- 0 – joecks

+0

@WonderCsabo C'è un modo molto più breve. Vedi la mia risposta. –

9

Per ottenere tutte le cartelle di memorizzazione esterni disponibili (comprese le carte SD), è possibile utilizzare questo:

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

Per passare alla "radice" di ogni storage esterno (quello che è il percorso della cartella vero e proprio montaggio), è possibile utilizzare questa funzione che ho effettuato:

/** 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; 
     } 
    } 
+0

Ciò richiederebbe il supporto della libreria 4 (per usare ContextCompat), getTotalSpace() richiede l'API minima di livello 9, non funziona per l'API Livello 8. –

+0

@ AB ok. usare l'API 9 e sopra è abbastanza buono al giorno d'oggi. –

+0

Ciò può anche restituire cartelle di file system private, che non sono leggibili o scrivibili dall'app. –

0

Ora questo argomento è vecchio ma questo può essere d'aiuto. dovresti usare il metodo.

System.getenv();

vedere il progetto Ambiente3 per accedere a tutti gli archivi collegati al dispositivo.

https://github.com/omidfaraji/Environment3

2

Un'altra alternativa.

primo luogo ottenere tutti i file esterni dirs

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

quindi chiamare questa funzione per ciascuna delle cartelle

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

Funziona perfettamente, grazie – Angelica

+0

getExternalFilesDirs non ha un percorso di archiviazione USB. – Tom

Problemi correlati