J'ai eu le même problème, j'ai essayé la solution ci-dessus mais bien qu'elle ait fonctionné en général, pour une raison quelconque, j'ai obtenu un refus d'autorisation sur le fournisseur de contenu Uri pour certaines images bien que j'aie eu le android.permission.MANAGE_DOCUMENTS
permission ajoutée correctement.
J'ai trouvé une autre solution qui consiste à forcer l'ouverture de la galerie d'images au lieu de la vue des documents KITKAT avec :
// KITKAT
i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, CHOOSE_IMAGE_REQUEST);
et ensuite charger l'image :
Uri selectedImageURI = data.getData();
input = c.getContentResolver().openInputStream(selectedImageURI);
BitmapFactory.decodeStream(input , null, opts);
EDITAR
ACTION_OPEN_DOCUMENT
peut vous obliger à faire persister les drapeaux de permissions, etc. et entraîne souvent des exceptions de sécurité...
L'autre solution est d'utiliser le ACTION_GET_CONTENT
combiné avec c.getContentResolver().openInputStream(selectedImageURI)
qui fonctionnera à la fois sur les pré-KK et les KK. Kitkat utilisera alors la nouvelle vue des documents et cette solution fonctionnera avec toutes les applications comme Photos, Gallery, File Explorer, Dropbox, Google Drive etc...) mais n'oubliez pas que lorsque vous utilisez cette solution vous devez créer une image dans votre onActivityResult()
et le stocker sur une carte SD par exemple. Recréer cette image à partir de l'url sauvegardée au prochain lancement de l'application entraînerait une exception de sécurité sur le résolveur de contenu, même si vous ajoutez des drapeaux de permission comme décrit dans les documents de l'API Google (c'est ce qui s'est passé lorsque j'ai fait quelques tests)
De plus, les directives de l'API pour les développeurs Android suggèrent :
ACTION_OPEN_DOCUMENT n'est pas destinée à remplacer ACTION_GET_CONTENT. Celle que vous devez utiliser dépend des besoins de votre application. votre application :
Utilisez ACTION_GET_CONTENT si vous voulez que votre application se contente de lire/importer données. Avec cette approche, l'application importe une copie des données, comme par exemple un fichier image.
Utilisez ACTION_OPEN_DOCUMENT si vous voulez que votre application ait un accès persistant et à long terme aux documents détenus par un fournisseur de fournisseur de documents. Un exemple serait une application d'édition de photos qui permet aux utilisateurs de modifier des images stockées dans un fournisseur de documents.
21 votes
De façon spontanée, je trouverais des moyens d'utiliser le contenu qui ne nécessitent pas un accès direct au fichier. Par exemple, que
Uri
doit pouvoir être ouvert en tant que flux viaContentResolver
. J'ai longtemps été nerveux à l'égard des applications qui supposent qu'unecontent://
Uri
qui représente un fichier peut toujours être convertie en un fichierFile
.0 votes
Je pense qu'une réponse valable est de passer à l'option
ContentResolver
et travailler avecUri
au lieu de File-URLs. Je vais le faire. Cela permet également de mieux gérer les éléments qui ne sont pas des galeries.Uri
s.1 votes
@CommonsWare,Si je veux enregistrer le chemin d'une image dans une base de données sqlite pour pouvoir l'ouvrir plus tard, dois-je enregistrer l'URI ou le chemin absolu du fichier ?
2 votes
@CommonsWare Je suis d'accord avec votre nervosité :-) Cependant, j'ai besoin de pouvoir passer un nom de fichier (pour une image) à un code natif. Une solution consiste à copier les données obtenues à l'aide d'une fonction
InputStream
sur leContentResolver
à un endroit prédéfini pour qu'il ait un nom de fichier connu. Cependant, cela me semble être du gaspillage. Avez-vous d'autres suggestions ?2 votes
@darrenp : Ummm..., réécrire le code natif pour qu'il fonctionne avec un...
InputStream
plutôt que JNI ? Il n'y a pas beaucoup d'options pour vous, malheureusement.1 votes
C'est utile de le savoir. Merci pour votre réponse. J'ai découvert depuis que nous transmettons maintenant l'image au C++ en mémoire plutôt que par l'intermédiaire d'un fichier.
InputStream
au lieu d'un fichier (ce qui est génial). Seule la lecture des balises EXIF est un peu délicate et nécessite de l'aide. La bibliothèque de Drew Noakes . Merci beaucoup pour vos commentaires.0 votes
@Exception un bogue a été signalé dans Cordova à ce sujet. Essayez donc de trouver une réponse qui fonctionne.
0 votes
@SpryTechies Mais cela ne fonctionne que pour les images, qu'en est-il des autres types de médias.
0 votes
@Exception Quel média voulez-vous s'il vous plaît préciser
0 votes
@SpryTechies Je voulais dire fichier vidéo.
0 votes
tagasks.com/
0 votes
Une meilleure réponse se trouve ici stackoverflow.com/questions/20067508/ de Paul Burke
0 votes
MediaStore.Images.Media.DATA est maintenant déprécié et MediaStore.Images.Media._ID avec contentWrapperUri renvoie toujours un uri relatif et non un uri absolu. C'est le principal problème pour obtenir un Uri valide et cet Uri ne renvoie pas un chemin de fichier valide et produit une FileNotFoundException.