Existe-t-il un moyen universel de trouver l'emplacement d'une carte SD externe?
Veuillez ne pas confondre avec le stockage externe .
Environment.getExternalStorageState()
renvoie le chemin vers le point de montage SD interne, comme "/ mnt / sdcard". Mais la question concerne le SD externe. Comment obtenir un chemin comme "/ mnt / sdcard / external_sd" (il peut différer d'un périphérique à l'autre)?
Je suppose que je terminerai par le filtrage de la sortie de la mount
commande par nom de système de fichiers. Mais je ne suis pas sûr que cette méthode soit suffisamment robuste.
Réponses:
Non,
Environment.getExternalStorageDirectory()
fait référence à tout ce que le fabricant de l'appareil considère comme "stockage externe". Sur certains appareils, il s'agit d'un support amovible, comme une carte SD. Sur certains appareils, il s'agit d'une partie du flash sur l'appareil. Ici, "stockage externe" signifie "les éléments accessibles via le mode de stockage de masse USB lorsqu'ils sont montés sur une machine hôte", au moins pour Android 1.x et 2.x.Android n'a pas de concept de «SD externe», à part le stockage externe, comme décrit ci-dessus.
Si un fabricant de périphérique a choisi d'avoir un stockage externe intégré à la mémoire flash et possède également une carte SD, vous devrez contacter ce fabricant pour déterminer si vous pouvez utiliser la carte SD (non garantie) et quelles sont les règles. en l'utilisant, comme le chemin à utiliser pour cela.
METTRE À JOUR
Deux choses récentes à noter:
Tout d'abord, sur Android 4.4+, vous n'avez pas accès en écriture aux supports amovibles (par exemple, "SD externe"), à l'exception des emplacements sur ce support qui pourraient être retournés par
getExternalFilesDirs()
etgetExternalCacheDirs()
. Voir l'excellente analyse de Dave Smith à ce sujet, surtout si vous voulez les détails de bas niveau.Deuxièmement, de peur que quiconque ne se demande si l'accès aux médias amovibles fait partie du SDK Android, voici l'évaluation de Dianne Hackborn :
la source
J'ai trouvé la solution suivante basée sur quelques réponses trouvées ici.
CODE:
USAGE:
la source
J'avais une application qui utilisait un
ListPreference
emplacement où l'utilisateur devait sélectionner l'emplacement où il voulait enregistrer quelque chose.Dans cette application, j'ai scanné
/proc/mounts
et/system/etc/vold.fstab
recherché des points de montage sdcard. J'ai stocké les points de montage de chaque fichier dans deuxArrayList
s distincts .Ensuite, j'ai comparé une liste avec l'autre et jeté les éléments qui n'étaient pas dans les deux listes. Cela m'a donné une liste de chemins racine vers chaque carte SD.
A partir de là, je l' ai testé les chemins avec
File.exists()
,File.isDirectory()
etFile.canWrite()
. Si l'un de ces tests était faux, j'ai écarté ce chemin de la liste.Tout ce qui restait dans la liste, je l'ai converti en un
String[]
tableau afin qu'il puisse être utilisé par l'ListPreference
attribut values.Vous pouvez voir le code ici: http://sapienmobile.com/?p=204
la source
Vous pouvez essayer d'utiliser la fonction de bibliothèque de support appelée ContextCompat.getExternalFilesDirs () :
Le premier est le stockage externe principal, et les autres sont censés être de vrais chemins de cartes SD.
La raison du multiple ".getParentFile ()" est de remonter dans un autre dossier, car le chemin d'origine est
EDIT: voici un moyen plus complet que j'ai créé, pour obtenir les chemins des cartes SD:
la source
App
,ContextCompact
,EnvironmentCompact
Afin de récupérer tous les stockages externes (qu'il s'agisse de cartes SD ou de stockages internes non amovibles ), vous pouvez utiliser le code suivant:
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 souhaiterez peut-être 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).
la source
System.getenv("SECONDARY_STORAGE")
pourrait également concerner certaines références, car elle semble non documentée./mnt
qu'il peut y avoir divers autres arbres fs, pas seulement des cartes SD et des clés USB. Votre code répertorie également tous les supports de système de fichiers internes (peut-être même virtuels), si je comprends bien, alors que la question ne veut que des cartes SD .Comme Richard, j'utilise également le fichier / proc / mounts pour obtenir la liste des options de stockage disponibles
la source
printStackTrace
? Quand on aandroid.util.Log.e
?Il est possible de trouver où toutes les cartes SD supplémentaires sont montées en lisant
/proc/mounts
(fichier Linux standard) et en recoupant les données vold (/system/etc/vold.conf
). Et notez que l'emplacement renvoyé parEnvironment.getExternalStorageDirectory()
peut ne pas apparaître dans la configuration vold (dans certains appareils, c'est le stockage interne qui ne peut pas être démonté), mais doit toujours être inclus dans la liste. Cependant, nous n'avons pas trouvé un bon moyen de les décrire à l'utilisateur .la source
mount
est plus compatible que la lecture d'un/proc
système de fichiers. Le problème est que la carte SD n'est pas nécessairement formatée en FAT. De plus, le point de montage de la carte peut varier d'une ROM à l'autre. En outre, il pourrait y avoir plusieurs autres partitions VFAT ...mount
exécutable, d'autant plus que le lancement des exécutables est déconseillé.J'essaie toutes les solutions à l'intérieur de ce sujet cette fois. Mais tous ne fonctionnaient pas correctement sur les appareils avec une carte externe (amovible) et une carte interne (non amovible). Le chemin de la carte externe n'est pas possible obtenir à partir de la commande 'mount', du fichier 'proc / mounts' etc.
Et je crée ma propre solution (sur celle de Paulo Luan):
la source
Si vous regardez le code source,
android.os.Environment
vous verrez qu'Android dépend fortement des variables d'environnement pour les chemins. Vous pouvez utiliser la variable d'environnement "SECONDARY_STORAGE" pour trouver le chemin d'accès à la carte SD amovible.Exemple d'utilisation:
la source
Utilisez simplement ceci:
la source
SECONDARY_STORAGE
plusieurs chemins sont séparés par deux points (":"). C'est pourquoi j'ai divisé la chaîne (voir ma réponse ci-dessus).Par voie universelle , si vous voulez dire par voie officielle; Oui il y en a un.
Dans l'API niveau 19, c'est-à-dire dans la version Android 4.4 Kitkat, ils ont ajouté
File[] getExternalFilesDirs (String type)
enContext
classe qui permet aux applications de stocker des données / fichiers sur des cartes micro SD.Android 4.4 est la première version de la plate-forme qui a permis aux applications d'utiliser des cartes SD pour le stockage. Tout accès aux cartes SD avant le niveau 19 de l'API se faisait via des API privées non prises en charge.
getExternalFilesDirs (type String) renvoie des chemins absolus vers des répertoires spécifiques à l'application sur tous les périphériques de stockage partagés / externes. Cela signifie qu'il retournera des chemins vers la mémoire interne et externe. Généralement, le deuxième chemin renvoyé serait le chemin de stockage pour la carte microSD (le cas échéant).
Mais notez que,
La terminologie de stockage interne et externe selon Google / documents Android officiels est assez différente de ce que nous pensons.
la source
getExternalFilesDirs()
renvoie souvent des cartes SD qui ne sont pas amovibles, donc non, ce n'est pas un moyen universel de trouver l'emplacement d'une carte SD amovible.Voici la façon dont j'utilise pour trouver la carte externe. Utilisez mount cmd return puis analysez la partie vfat.
la source
Cette solution gère le fait que cela
System.getenv("SECONDARY_STORAGE")
n'est d'aucune utilité avec Marshmallow.Testé et travaillant sur:
Samsung Galaxy Tab A (Android 6.0.1 - Stock)
la source
Depuis ma réponse originale ci-dessus, la numérisation de vold n'est plus viable entre les différents fabricants.
J'ai développé une méthode plus fiable et simple.
les racines contiendront tous les répertoires racine accessibles en écriture sur le système, y compris tous les périphériques USB connectés par USB.
REMARQUE: La méthode canWrite a besoin de l'autorisation android.permission.WRITE_EXTERNAL_STORAGE.
la source
/external_sd
trouve la carte microSD externe; sur certains LG, c'est/_ExternalSD
; sur certains appareils, c'est/sdcard
. Peut-être que ce dernier est un lien symbolique vers/storage/sdcard0
ou similaire, mais ces autres seront-ils vraiment couverts de manière fiable par/storage/*
et/mount/*
?pathname.canWrite()
et d'exiger l'autorisation WRITE_EXTERNAL_STORAGE? Pourquoi ne pas simplement appelerpathname.canRead()
?il a été si tard, mais finalement j'ai obtenu quelque chose que j'ai testé la plupart des appareils (par fabricant et versions Android) son travail sur Android 2.2+. si vous trouvez que cela ne fonctionne pas, commentez-le avec le nom de votre appareil. je le réparerai. si quelqu'un est intéressé, je vais vous expliquer comment cela fonctionne.
la source
En écrivant le code ci-dessous, vous obtiendrez l'emplacement:
/ stockage / 663D-554E / Android / data / nom_package_app / files /
qui stocke les données de votre application dans / android / data à l'intérieur de la sd_card.
J'ai testé ce code sur une moto g4 plus et un appareil Samsung (tout fonctionne bien).
j'espère que cela pourrait être utile.
la source
Voici la méthode que j'utilise pour trouver une carte SD amovible . C'est complexe et probablement exagéré dans certaines situations, mais cela fonctionne sur une grande variété de versions d'Android et de fabricants d'appareils que j'ai testés au cours des dernières années. Je ne connais aucun périphérique depuis le niveau 15 de l'API sur lequel il ne trouve pas la carte SD, s'il y en a une montée. Il ne retournera pas de faux positifs dans la plupart des cas, surtout si vous lui donnez le nom d'un fichier connu à rechercher.
Veuillez me faire savoir si vous rencontrez des cas où cela ne fonctionne pas.
PS
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
dans le manifeste. Et au niveau API 23 et supérieur, assurez-vous d'utilisercheckSelfPermission
/requestPermissions
.findSdCardPath(),
plutôt que de la recalculer chaque fois que vous en avez besoin.Log.d()
) dans le code ci-dessus. Il aide à diagnostiquer tous les cas où le bon chemin n'est pas trouvé. Commentez-le si vous ne voulez pas vous connecter.la source
La seule solution de travail que j'ai trouvée était celle-ci qui utilise la réflexion
la source
Je ne sais pas pourquoi mais je dois appeler .createNewFile () sur un fichier créé dans les répertoires de stockage public avant de l'utiliser. Dans le cadre, les commentaires de cette méthode disent qu'elle n'est pas utile. Voici un exemple ...
la source
J'ai créé une méthode utils pour vérifier qu'une carte SD est disponible sur l'appareil ou non, et obtenir le chemin de la carte SD sur l'appareil si elle est disponible.
Vous pouvez copier 2 méthodes ci-dessous dans la classe de votre projet dont vous avez besoin. C'est tout.
la source
Son travail pour tous les périphériques externes, mais assurez-vous d'obtenir uniquement le nom du dossier du périphérique externe, puis vous devez obtenir le fichier à partir d'un emplacement donné à l'aide de la classe File.
Appel:
Accéder à un stockage externe
Pour lire ou écrire des fichiers sur le stockage externe, votre application doit acquérir les autorisations système READ_EXTERNAL_STORAGE ou WRITE_EXTERNAL_STORAGE . Par exemple:
la source
/ sdcard => Stockage interne (c'est un lien symbolique mais devrait fonctionner)
/ mnt / extSdCard => Carte Sd externe
C'est pour Samsung Galaxy S3
Vous pouvez probablement miser sur le fait que cela est vrai pour la plupart ... revérifiez cependant!
la source
/sdcard
est un lien symbolique vers externe sur mon sony 2305.