web-dev-qa-db-fra.com

Comment puis-je obtenir un chemin de carte SD externe pour Android 4.0+?

Le Samsung Galaxy S3 possède un emplacement pour carte SD supplémentaire, monté sur /mnt/extSdCard.

Ma question est la suivante: comment obtenir ce chemin par quelque chose comme Environment.getExternalStorageDirectory()? Cela renverra mnt/sdcard et je ne trouve pas l'API pour la carte SD externe. (Ou stockage USB amovible sur certaines tablettes)

Je vous remercie!

87

J'ai une variante d'une solution que j'ai trouvée ici

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

La méthode originale a été testée et travaillée avec

  • Huawei X3 (stock)
  • Galaxy S2 (stock)
  • Galaxy S3 (stock)

Je ne suis pas sûr de la version d'Android sur laquelle ils étaient lorsqu'ils ont été testés.

J'ai testé ma version modifiée avec

  • Moto Xoom 4.1.2 (stock)
  • Galaxy Nexus (cyanogenMod 10) utilisant un câble otg
  • HTC Incredible (cyanogenMod 7.2) cela renvoyait à la fois interne et externe. Ce périphérique est un peu étrange dans la mesure où son interne reste largement inutilisé car getExternalStorage () renvoie un chemin vers la carte sd à la place.

et certains périphériques de stockage simples qui utilisent une carte SD comme stockage principal

  • HTC G1 (cyanogenmod 6.1)
  • HTC G1 (stock)
  • HTC Vision/G2 (stock)

À l'exception de l'incroyable, tous ces périphériques ne renvoyaient que leur stockage amovible. Je devrais probablement faire quelques vérifications supplémentaires, mais c'est au moins un peu mieux que toute solution que j'ai trouvée jusqu'à présent.

55
Gnathonic

J'ai trouvé un moyen plus fiable d'obtenir des chemins d'accès à toutes les cartes SD-Card du système .

Fonctionne correctement sur tous mes appareils.

P.S .: Basé sur le code source de la classe d'environnement.

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()]);
}
52
Dmitriy Lozenko

Je suppose que pour utiliser la carte SD externe, vous devez utiliser ceci:

new File("/mnt/external_sd/")

OU 

new File("/mnt/extSdCard/")

dans ton cas...

en remplacement de Environment.getExternalStorageDirectory()

Travaille pour moi. Vous devriez d'abord vérifier ce qui se trouve dans le répertoire mnt et travailler à partir de là.


Vous devez utiliser une méthode de sélection pour choisir la carte mémoire à utiliser:

File storageDir = new File("/mnt/");
if(storageDir.isDirectory()){
    String[] dirList = storageDir.list();
    //TODO some type of selecton method?
}
31
FabianCook

Pour récupérer tous les Stockages externes (qu’ils soient cartes SD ou stockages internes non amovibles), vous pouvez utiliser le code suivant:

final String state = Environment.getExternalStorageState();

if ( Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state) ) {  // we can read the External Storage...           
    //Retrieve the primary External Storage:
    final File primaryExternalStorage = Environment.getExternalStorageDirectory();

    //Retrieve the External Storages root directory:
    final String externalStorageRootDir;
    if ( (externalStorageRootDir = primaryExternalStorage.getParent()) == null ) {  // no parent...
        Log.d(TAG, "External Storage: " + primaryExternalStorage + "\n");
    }
    else {
        final File externalStorageRoot = new File( externalStorageRootDir );
        final File[] files = externalStorageRoot.listFiles();

        for ( final File file : files ) {
            if ( file.isDirectory() && file.canRead() && (file.listFiles().length > 0) ) {  // it is a real directory (not a USB drive)...
                Log.d(TAG, "External Storage: " + file.getAbsolutePath() + "\n");
            }
        }
    }
}

Vous pouvez également utiliser System.getenv ("EXTERNAL_STORAGE") pour récupérer le répertoire de stockage externe principal (par exemple "/ storage/sdcard0") et System.getenv ("SECONDARY_STORAGE"). pour récupérer la liste de tous les répertoires secondaires (par exemple, "/ storage/extSdCard:/storage/UsbDriveA:/storage/UsbDriveB"). N'oubliez pas que, dans ce cas également, vous pouvez filtrer la liste des répertoires secondaires afin d'exclure les lecteurs USB.

Dans tous les cas, veuillez noter que l’utilisation de chemins codés en dur est toujours une mauvaise approche (surtout lorsque chaque fabricant peut le changer à sa guise).

15
Paolo Rovelli

J'utilisais la solution de Dmitriy Lozenko jusqu'à ce que je vérifie Asus Zenfone2, Marshmallow 6.0.1 et que la solution ne fonctionne pas. La solution a échoué lors de l'obtention de EMULATED_STORAGE_TARGET, en particulier pour le chemin microSD, c'est-à-dire: / storage/F99C-10F4/. J'ai édité le code pour obtenir les chemins racine émulés directement à partir des chemins d'application émulés avec context.getExternalFilesDirs(null); et ajouter des chemins spécifiques au modèle de téléphone plus connus.

Pour rendre notre vie plus facile, j'ai fait une bibliothèque ici . Vous pouvez l'utiliser via Gradle, Maven, sbt et leiningen build system.

Si vous aimez la méthode à l’ancienne, vous pouvez également copier/coller le fichier directement à partir de ici , mais vous ne saurez pas s’il existe une mise à jour à l’avenir sans le vérifier manuellement.

Si vous avez une question ou une suggestion, s'il vous plaît faites le moi savoir

14
HendraWD

Bonnes nouvelles! Dans KitKat, il existe désormais une API publique permettant d'interagir avec ces périphériques de stockage partagés secondaires.

Les nouvelles méthodes Context.getExternalFilesDirs() et Context.getExternalCacheDirs() peuvent renvoyer plusieurs chemins, y compris des périphériques principaux et secondaires. Vous pouvez ensuite les parcourir et vérifier les fonctions Environment.getStorageState() et File.getFreeSpace() afin de déterminer le meilleur emplacement pour stocker vos fichiers. Ces méthodes sont également disponibles sur ContextCompat dans la bibliothèque support-v4.

Notez également que si vous souhaitez uniquement utiliser les répertoires renvoyés par Context, vous n'avez plus besoin des autorisations READ_ ou WRITE_EXTERNAL_STORAGE. À l'avenir, vous aurez toujours un accès en lecture/écriture à ces répertoires sans aucune autorisation supplémentaire requise.

Les applications peuvent également continuer à travailler sur des appareils plus anciens en fin de vie de leur demande d'autorisation comme suit:

<uses-permission
    Android:name="Android.permission.WRITE_EXTERNAL_STORAGE"
    Android:maxSdkVersion="18" />
12
Jeff Sharkey

Voici comment obtenir la liste des chemins de la carte SD (à l'exclusion du stockage externe principal):

  /**
   * returns a list of all available sd cards paths, or null if not found.
   * 
   * @param includePrimaryExternalStorage set to true if you wish to also include the path of the primary external storage
   */
  @TargetApi(Build.VERSION_CODES.HONEYCOMB)
  public static List<String> getSdCardPaths(final Context context,final boolean includePrimaryExternalStorage)
    {
    final File[] externalCacheDirs=ContextCompat.getExternalCacheDirs(context);
    if(externalCacheDirs==null||externalCacheDirs.length==0)
      return null;
    if(externalCacheDirs.length==1)
      {
      if(externalCacheDirs[0]==null)
        return null;
      final String storageState=EnvironmentCompat.getStorageState(externalCacheDirs[0]);
      if(!Environment.MEDIA_MOUNTED.equals(storageState))
        return null;
      if(!includePrimaryExternalStorage&&VERSION.SDK_INT>=VERSION_CODES.HONEYCOMB&&Environment.isExternalStorageEmulated())
        return null;
      }
    final List<String> result=new ArrayList<>();
    if(includePrimaryExternalStorage||externalCacheDirs.length==1)
      result.add(getRootOfInnerSdCardFolder(externalCacheDirs[0]));
    for(int i=1;i<externalCacheDirs.length;++i)
      {
      final File file=externalCacheDirs[i];
      if(file==null)
        continue;
      final String storageState=EnvironmentCompat.getStorageState(file);
      if(Environment.MEDIA_MOUNTED.equals(storageState))
        result.add(getRootOfInnerSdCardFolder(externalCacheDirs[i]));
      }
    if(result.isEmpty())
      return null;
    return result;
    }

  /** 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;
      }
    }
9
android developer

J'ai fait ce qui suit pour avoir accès à toutes les cartes SD externes.

Avec:

File primaryExtSd=Environment.getExternalStorageDirectory();

vous obtenez le chemin vers le SD externe principal Puis avec:

File parentDir=new File(primaryExtSd.getParent());

vous obtenez le répertoire parent du stockage externe principal et il est également le parent de tous les disques externes. Maintenant, vous pouvez lister tout le stockage et choisir celui que vous voulez.

J'espère que c'est utile.

9
valenta

Merci pour les indices fournis par vous, en particulier @SmartLemon, j'ai eu la solution. Au cas où quelqu'un en aurait besoin, je mettrais ma solution finale ici (pour trouver la première carte SD externe répertoriée):

public File getExternalSDCardDirectory()
{
    File innerDir = Environment.getExternalStorageDirectory();
    File rootDir = innerDir.getParentFile();
    File firstExtSdCard = innerDir ;
    File[] files = rootDir.listFiles();
    for (File file : files) {
        if (file.compareTo(innerDir) != 0) {
            firstExtSdCard = file;
            break;
        }
    }
    //Log.i("2", firstExtSdCard.getAbsolutePath().toString());
    return firstExtSdCard;
}

Si aucune carte SD externe n’est présente, elle renvoie le stockage intégré. Je vais l'utiliser si la carte SD n'existe pas, vous devrez peut-être la changer. 

5
rml

se référer à mon code, j'espère utile pour vous:

    Runtime runtime = Runtime.getRuntime();
    Process proc = runtime.exec("mount");
    InputStream is = proc.getInputStream();
    InputStreamReader isr = new InputStreamReader(is);
    String line;
    String mount = new String();
    BufferedReader br = new BufferedReader(isr);
    while ((line = br.readLine()) != null) {
        if (line.contains("secure")) continue;
        if (line.contains("asec")) continue;

        if (line.contains("fat")) {//TF card
            String columns[] = line.split(" ");
            if (columns != null && columns.length > 1) {
                mount = mount.concat("*" + columns[1] + "\n");
            }
        } else if (line.contains("Fuse")) {//internal storage
            String columns[] = line.split(" ");
            if (columns != null && columns.length > 1) {
                mount = mount.concat(columns[1] + "\n");
            }
        }
    }
    txtView.setText(mount);
3
cst05001

En fait, sur certains appareils, le nom par défaut de la carte SD externe s’affiche sous la forme extSdCard et pour d’autres, sdcard1.

Cet extrait de code permet de connaître le chemin exact et de récupérer le chemin du périphérique externe.

String sdpath,sd1path,usbdiskpath,sd0path;    
        if(new File("/storage/extSdCard/").exists())
            {
               sdpath="/storage/extSdCard/";
               Log.i("Sd Cardext Path",sdpath);
            }
        if(new File("/storage/sdcard1/").exists())
         {
              sd1path="/storage/sdcard1/";
              Log.i("Sd Card1 Path",sd1path);
         }
        if(new File("/storage/usbcard1/").exists())
         {
              usbdiskpath="/storage/usbcard1/";
              Log.i("USB Path",usbdiskpath);
         }
        if(new File("/storage/sdcard0/").exists())
         {
              sd0path="/storage/sdcard0/";
              Log.i("Sd Card0 Path",sd0path);
         }
2
Sam

Oui. Différents fabricants utilisent des noms de cartes SD différents, comme dans Samsung Tab 3, son extsd, tandis que d'autres appareils Samsung utilisent une carte SD, comme les noms de fabricants différents.

J'ai eu la même exigence que vous. j'ai donc créé pour vous un exemple d'exemple de mon projet goto this link Sélecteur d'annuaire Android exemple qui utilise la bibliothèque androi-dirchooser. Cet exemple détecte la carte SD et répertorie tous les sous-dossiers. Il détecte également si le périphérique dispose de plus d’une carte SD.

Une partie du code ressemble à ceci: Pour un exemple complet, allez au lien Sélecteur d’annuaire Android

/**
* Returns the path to internal storage ex:- /storage/emulated/0
 *
* @return
 */
private String getInternalDirectoryPath() {
return Environment.getExternalStorageDirectory().getAbsolutePath();
 }

/**
 * Returns the SDcard storage path for samsung ex:- /storage/extSdCard
 *
 * @return
 */
    private String getSDcardDirectoryPath() {
    return System.getenv("SECONDARY_STORAGE");
}


 mSdcardLayout.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
        String sdCardPath;
        /***
         * Null check because user may click on already selected buton before selecting the folder
         * And mSelectedDir may contain some wrong path like when user confirm dialog and swith back again
         */

        if (mSelectedDir != null && !mSelectedDir.getAbsolutePath().contains(System.getenv("SECONDARY_STORAGE"))) {
            mCurrentInternalPath = mSelectedDir.getAbsolutePath();
        } else {
            mCurrentInternalPath = getInternalDirectoryPath();
        }
        if (mCurrentSDcardPath != null) {
            sdCardPath = mCurrentSDcardPath;
        } else {
            sdCardPath = getSDcardDirectoryPath();
        }
        //When there is only one SDcard
        if (sdCardPath != null) {
            if (!sdCardPath.contains(":")) {
                updateButtonColor(STORAGE_EXTERNAL);
                File dir = new File(sdCardPath);
                changeDirectory(dir);
            } else if (sdCardPath.contains(":")) {
                //Multiple Sdcards show root folder and remove the Internal storage from that.
                updateButtonColor(STORAGE_EXTERNAL);
                File dir = new File("/storage");
                changeDirectory(dir);
            }
        } else {
            //In some unknown scenario at least we can list the root folder
            updateButtonColor(STORAGE_EXTERNAL);
            File dir = new File("/storage");
            changeDirectory(dir);
        }


    }
});
2
Shivaraj Patil

Cette solution (issue d’autres réponses à cette question) gère le fait (comme mentionné par @ono) que System.getenv("SECONDARY_STORAGE") n’est pas utile avec Marshmallow.

Testé et travaillant sur:

  • Samsung Galaxy Tab 2 (Android 4.1.1 - Stock)
  • Samsung Galaxy Note 8.0 (Android 4.2.2 - Stock)
  • Samsung Galaxy S4 (Android 4.4 - Stock)
  • Samsung Galaxy S4 (Android 5.1.1 - CyanogenMod)
  • Samsung Galaxy Tab A (Android 6.0.1 - Stock)

    /**
     * Returns all available external SD-Card roots in the system.
     *
     * @return paths to all available external SD-Card roots in the system.
     */
    public static String[] getStorageDirectories() {
        String [] storageDirectories;
        String rawSecondaryStoragesStr = System.getenv("SECONDARY_STORAGE");
    
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KitKat) {
            List<String> results = new ArrayList<String>();
            File[] externalDirs = applicationContext.getExternalFilesDirs(null);
            for (File file : externalDirs) {
                String path = file.getPath().split("/Android")[0];
                if((Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop && Environment.isExternalStorageRemovable(file))
                        || rawSecondaryStoragesStr != null && rawSecondaryStoragesStr.contains(path)){
                    results.add(path);
                }
            }
            storageDirectories = results.toArray(new String[0]);
        }else{
            final Set<String> rv = new HashSet<String>();
    
            if (!TextUtils.isEmpty(rawSecondaryStoragesStr)) {
                final String[] rawSecondaryStorages = rawSecondaryStoragesStr.split(File.pathSeparator);
                Collections.addAll(rv, rawSecondaryStorages);
            }
            storageDirectories = rv.toArray(new String[rv.size()]);
        }
        return storageDirectories;
    }
    
2
DaveAlden

Sur certains périphériques (par exemple, Samsung Galaxy SII), la carte mémoire interne peut être en vfat. Dans ce cas, utilisez le dernier code, nous obtenons le chemin de la carte mémoire interne (/ mnt/sdcad) mais pas de carte externe. Code référez-vous ci-dessous pour résoudre ce problème.

static String getExternalStorage(){
         String exts =  Environment.getExternalStorageDirectory().getPath();
         try {
            FileReader fr = new FileReader(new File("/proc/mounts"));       
            BufferedReader br = new BufferedReader(fr);
            String sdCard=null;
            String line;
            while((line = br.readLine())!=null){
                if(line.contains("secure") || line.contains("asec")) continue;
            if(line.contains("fat")){
                String[] pars = line.split("\\s");
                if(pars.length<2) continue;
                if(pars[1].equals(exts)) continue;
                sdCard =pars[1]; 
                break;
            }
        }
        fr.close();
        br.close();
        return sdCard;  

     } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}
1
Alex
       File[] files = null;
    File file = new File("/storage");// /storage/emulated
if (file.exists()) {
        files = file.listFiles();
            }
            if (null != files)
                for (int j = 0; j < files.length; j++) {
                    Log.e(TAG, "" + files[j]);
                    Log.e(TAG, "//--//--// " +             files[j].exists());

                    if (files[j].toString().replaceAll("_", "")
                            .toLowerCase().contains("extsdcard")) {
                        external_path = files[j].toString();
                        break;
                    } else if (files[j].toString().replaceAll("_", "")
                            .toLowerCase()
                            .contains("sdcard".concat(Integer.toString(j)))) {
                        // external_path = files[j].toString();
                    }
                    Log.e(TAG, "--///--///--  " + external_path);
                }
1
Amit

Pour accéder aux fichiers de ma carte SD sur mon HTC One X (Android), j'utilise ce chemin:

file:///storage/sdcard0/folder/filename.jpg

Remarque le triple "/"!

0
HTC user

Vous pouvez utiliser quelque chose comme - Context.getExternalCacheDirs () ou Context.getExternalFilesDirs () ou Context.getObbDirs (). Ils donnent des répertoires spécifiques à l'application sur tous les périphériques de stockage externes où l'application peut stocker ses fichiers.

Donc, quelque chose comme: Context.getExternalCacheDirs () [i] .getParentFile (). GetParentFile (). GetParentFile (). GetParent () peut vous obtenir le chemin racine des périphériques de stockage externes.

Je sais que ces commandes ont un but différent, mais d’autres réponses n’ont pas fonctionné pour moi.

Ce lien m'a donné de bons conseils - https://possiblemobile.com/2014/03/Android-external-storage/

0
Sharath Holla

Je suis sûr que ce code résoudra sûrement vos problèmes ... Cela fonctionne très bien pour moi ... \

try {
            File mountFile = new File("/proc/mounts");
            usbFoundCount=0;
            sdcardFoundCount=0;
            if(mountFile.exists())
             {
                Scanner usbscanner = new Scanner(mountFile);
                while (usbscanner.hasNext()) {
                    String line = usbscanner.nextLine();
                    if (line.startsWith("/dev/Fuse /storage/usbcard1")) {
                        usbFoundCount=1;
                        Log.i("-----USB--------","USB Connected and properly mounted---/dev/Fuse /storage/usbcard1" );
                    }
            }
         }
            if(mountFile.exists()){
                Scanner sdcardscanner = new Scanner(mountFile);
                while (sdcardscanner.hasNext()) {
                    String line = sdcardscanner.nextLine();
                    if (line.startsWith("/dev/Fuse /storage/sdcard1")) {
                        sdcardFoundCount=1;
                        Log.i("-----USB--------","USB Connected and properly mounted---/dev/Fuse /storage/sdcard1" );
                    }
            }
         }
            if(usbFoundCount==1)
            {
                Toast.makeText(context,"USB Connected and properly mounted", 7000).show();
                Log.i("-----USB--------","USB Connected and properly mounted" );
            }
            else
            {
                Toast.makeText(context,"USB not found!!!!", 7000).show();
                Log.i("-----USB--------","USB not found!!!!" );

            }
            if(sdcardFoundCount==1)
            {
                Toast.makeText(context,"SDCard Connected and properly mounted", 7000).show();
                Log.i("-----SDCard--------","SDCard Connected and properly mounted" );
            }
            else
            {
                Toast.makeText(context,"SDCard not found!!!!", 7000).show();
                Log.i("-----SDCard--------","SDCard not found!!!!" );

            }
        }catch (Exception e) {
            e.printStackTrace();
        } 
0
Sam

ce n'est pas vrai./mnt/sdcard/external_sd peut exister même si la carte SD n'est pas montée. votre application se bloquera si vous essayez d'écrire dans/mnt/sdcard/external_sd sans l'avoir montée.

vous devez vérifier si la carte SD est montée en premier en utilisant:

boolean isSDPresent = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
0
Marcin Skoczylas
//manifest file outside the application tag
//please give permission write this 
//<uses-permission Android:name="Android.permission.READ_EXTERNAL_STORAGE"/>
        File file = new File("/mnt");
        String[] fileNameList = file.list(); //file names list inside the mnr folder
        String all_names = ""; //for the log information
        String foundedFullNameOfExtCard = ""; // full name of ext card will come here
        boolean isExtCardFounded = false;
        for (String name : fileNameList) {
            if (!isExtCardFounded) {
                isExtCardFounded = name.contains("ext");
                foundedFullNameOfExtCard = name;
            }
            all_names += name + "\n"; // for log
        }
        Log.d("dialog", all_names + foundedFullNameOfExtCard);
0
Emre Kilinc Arslan
String secStore = System.getenv("SECONDARY_STORAGE");

File externalsdpath = new File(secStore);

Cela obtiendra le chemin du stockage secondaire externe sd.

0
Kenneth Villamin
 String path = Environment.getExternalStorageDirectory()
                        + File.separator + Environment.DIRECTORY_PICTURES;
                File dir = new File(path);
0
sarra srairi

System.getenv("SECONDARY_STORAGE") renvoie null pour Marshmallow. C'est une autre façon de trouver tous les dirs externes. Vous pouvez vérifier si c'est amovible, ce qui détermine si interne/externe

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    File[] externalCacheDirs = context.getExternalCacheDirs();
    for (File file : externalCacheDirs) {
        if (Environment.isExternalStorageRemovable(file)) {
            // It's a removable storage
        }
    }
}
0
ono

J'ai essayé les solutions fournies par Dmitriy Lozenko et Gnathonic sur mon Samsung Galaxy Tab S2 (modèle: T819Y) mais aucune ne m'a aidé à récupérer le chemin d'accès à un répertoire de carte SD externe. L'exécution de la commande mount contenait le chemin requis pour accéder au répertoire de la carte SD externe (c'est-à-dire/Storage/A5F9-15F4) mais il ne correspondait pas à l'expression régulière et n'a donc pas été renvoyé. Je ne comprends pas le mécanisme de dénomination de répertoire suivi par Samsung. Pourquoi ils s’écartent des normes (c’est-à-dire extsdcard) et proposent quelque chose de vraiment louche, comme dans mon cas ((c.-à-d./Storage/A5F9-15F4). Y a-t-il quelque chose qui me manque? Quoi qu'il en soit, les changements apportés dans l'expression régulière de la solution de Gnathonic m'ont aidé à obtenir un répertoire sdcard valide:

final HashSet<String> out = new HashSet<String>();
        String reg = "(?i).*(vold|media_rw).*(sdcard|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;

Je ne suis pas sûr qu'il s'agisse d'une solution valable et qu'elle donnera des résultats pour d'autres tablettes Samsung, mais cela a résolu mon problème pour le moment. Voici une autre méthode pour récupérer le chemin de la carte SD amovible dans Android (v6.0). J'ai testé la méthode avec Android Marshmallow et cela fonctionne. L'approche utilisée est très basique et fonctionnera sûrement pour d'autres versions également, mais les tests sont obligatoires. Quelques éclaircissements seront utiles:

public static String getSDCardDirPathForAndroidMarshmallow() {

    File rootDir = null;

    try {
        // Getting external storage directory file
        File innerDir = Environment.getExternalStorageDirectory();

        // Temporarily saving retrieved external storage directory as root
        // directory
        rootDir = innerDir;

        // Splitting path for external storage directory to get its root
        // directory

        String externalStorageDirPath = innerDir.getAbsolutePath();

        if (externalStorageDirPath != null
                && externalStorageDirPath.length() > 1
                && externalStorageDirPath.startsWith("/")) {

            externalStorageDirPath = externalStorageDirPath.substring(1,
                    externalStorageDirPath.length());
        }

        if (externalStorageDirPath != null
                && externalStorageDirPath.endsWith("/")) {

            externalStorageDirPath = externalStorageDirPath.substring(0,
                    externalStorageDirPath.length() - 1);
        }

        String[] pathElements = externalStorageDirPath.split("/");

        for (int i = 0; i < pathElements.length - 1; i++) {

            rootDir = rootDir.getParentFile();
        }

        File[] files = rootDir.listFiles();

        for (File file : files) {
            if (file.exists() && file.compareTo(innerDir) != 0) {

                // Try-catch is implemented to prevent from any IO exception
                try {

                    if (Environment.isExternalStorageRemovable(file)) {
                        return file.getAbsolutePath();

                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return null;
}

Merci de partager si vous avez une autre approche pour traiter ce problème. Merci

0
Abdul Rehman