Y a-t-il un moyen d'utiliser intent.setType()
et de fournir plusieurs types larges (comme des images et des vidéos) ?
Je suis en train d'utiliser un ACTION_GET_CONTENT
. Il semble fonctionner avec juste des types séparés par des virgules.
Y a-t-il un moyen d'utiliser intent.setType()
et de fournir plusieurs types larges (comme des images et des vidéos) ?
Je suis en train d'utiliser un ACTION_GET_CONTENT
. Il semble fonctionner avec juste des types séparés par des virgules.
Dans Android 4.4, en utilisant le Cadre d'accès au stockage, vous pouvez utiliser le EXTRA_MIME_TYPES
pour passer plusieurs types MIME.
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
String[] mimetypes = {"image/*", "video/*"};
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes);
startActivityForResult(intent, REQUEST_CODE_OPEN);
En fait, plusieurs types de mime sont pris en charge. L'avez-vous même essayé ???
Par exemple : intent.setType("image/*,video/*")
affichera des photos et des vidéos...
Pour moi, ça marche. Ça devrait fonctionner pour vous aussi...
[EDIT]: Cela fonctionne partiellement, car toutes les applications de galerie ne choisissent pas de mettre en œuvre le support pour plusieurs filtres de types de mime.
Désolé, cela n'est actuellement pas pris en charge. Vous avez deux options :
(1) Utilisez un type MIME de */*
et acceptez qu'il puisse y avoir des choses que l'utilisateur peut choisir que vous ne pourrez pas gérer (et ayez un chemin de récupération décent pour cela); ou
(2) Implémentez votre propre sélecteur d'activité, en effectuant des appels directs sur le gestionnaire de packages pour obtenir les activités pouvant gérer les deux types MIME pour l'intention, fusionnez ces listes et affichez-les à l'utilisateur.
De plus, setType()
ne fonctionne pas du tout avec des types séparés par des virgules. Il doit s'agir d'un seul et unique type MIME.
Pour moi, ce qui a le mieux fonctionné était :
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
Vous pouvez ajouter plusieurs types MIME de cette manière
intent.setType("image/*|application/pdf|audio/*");
Mais le sélecteur d'intent ne affichera que les applications capables de gérer les images car c'est le premier dans la chaîne de types MIME.
Cependant, si vous avez un gestionnaire de fichiers installé (j'ai testé avec le gestionnaire de fichiers CyanogenMod), vous pouvez choisir un fichier qui est audio, pdf ou une image.
Si le type MIME audio est le premier, comme ceci :
intent.setType("audio/*|image/*|application/pdf");
Le sélecteur d'intent affichera uniquement les applications qui gèrent l'audio.
Encore une fois en utilisant le gestionnaire de fichiers, vous pouvez sélectionner une image, un pdf ou un audio.
Avec le rappel registerForActivityResult()
:
import androidx.activity.result.contract.ActivityResultContracts
class DocumentsFragment : Fragment() {
companion object {
// 1. Liste des types MIME
/**@see Types MIME
* @see IANA - Types MIME*/
private val MIME_TYPES: Array = arrayOf(
"image/*", "application/pdf", "application/msword",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.oasis.opendocument.text", "text/plain", "text/markdown"
)
}
//2. Enregistrer le callback pour le résultat de l'activité en tant que champ de classe
private val getDocuments =
registerForActivityResult(ActivityResultContracts.OpenMultipleDocuments()/*PAS OpenDocument*/) {
Log.d("Ouvrir les documents", "uri entrante: taille = ${it.size}")
add(it)
}
...
//3. Définir un écouteur onclick
selectDocumentsButton.setOnClickListener { getDocuments.launch(MIME_TYPES) }
...
//4. Gérer la liste d'URI entrante
private fun add(list: List) {
val setOfFiles = copyToAppDir(list)
setOfFiles.forEach {
//TODO: faire quelque chose
}
}
//5. Copier les fichiers dans le dossier de l'application pour un travail ultérieur
private fun copyToAppDir(list: List): Set {
val set = mutableSetOf()
list.forEach { uri ->
try {
val file: File = copyUriContentToTempFile(uri)
set.add(file)
} catch (e: Exception) {
e.printStackTrace()
}
}
return set
}
//6. Copier le contenu sélectionné par l'URI
private fun copyUriContentToTempFile(uri: Uri): File {
val inputStream = requireContext().contentResolver.openInputStream(uri)
inputStream.use { input ->
val tempFile: File = .. ; //TODO: créer le fichier
tempFile.outputStream().use { output ->
input?.copyTo(output)
}
return tempFile
}
}
}
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.