java.lang.SecurityException: Autorisation de Déni: ouverture fournisseur de com.android.les prestataires.médias.MediaDocumentsProvider de ProcessRecord{430b1748 29271:com.x.x.x/u0a88} (pid=29271, uid=10088) nécessite android.la permission.MANAGE_DOCUMENTS ou android.la permission.MANAGE_DOCUMENTS
J'ai ajouté la gestion des Documents d'autorisation et READ_EXTERNAL_STORAGE. J'obtiens toujours cette erreur. Le code incriminé:
public static String getImagePath(HailoDriverApplication app, Uri uri) { Cursor cursor = null; if (uri == null) { return null; } try { cursor = app.getContentResolver().query(uri, new String[] { MediaStore.Images.Media.DATA }, null, null, null); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); if (cursor.moveToFirst()) { return cursor.getString(column_index); } } finally { if (cursor != null) { cursor.close(); } } return null; }
Comme demandé extrait du manifeste:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.x.x.x" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_COURSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.READ_LOGS" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MANAGE_DOCUMENTS" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" /> <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" tools:ignore="ProtectedPermissions" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <uses-permission android:name="android.intent.action.BATTERY_CHANGED" /> <uses-permission android:name="android.permission.INSTALL_PACKAGES" tools:ignore="ProtectedPermissions" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
Réponses
Trop de publicités?Eu le même problème pour le couple des derniers jours. Essayé quelques solutions, mais pour une raison que j'ai obtenu la permission de déni de l'Uri fournisseur de contenu pour certaines images, même lorsque j'avais le android.la permission.MANAGE_DOCUMENTS l'autorisation d'ajouter à mon manifeste.
Voici une solution de contournement, pour le moment:
i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, CHOOSE_IMAGE);
Cela force l'ancienne galerie d'image pour l'ouvrir à la place de la nouvelle Kitkat documents.
Maintenant, vous pouvez obtenir l'Uri en appelant la ligne suivante dans votre onActivityResult:
Uri selectedImageURI = data.getData();
Espérons que cette aide.
Dans le but utilisé pour demander à l'utilisateur d'ajouter un fichier, utiliser l'Intention.ACTION_OPEN_DOCUMENT (sur KitKat API de 19 ans ou plus) au lieu de l'Intention.ACTION_GET_CONTENT ou l'Intention.ACTION_PICK. Ensuite, lorsque vous souhaitez utiliser l'Uri, prendre la précédente persistante autorisations qui ont été définies par l'Intention.ACTION_OPEN_DOCUMENT comme décrit dans @feri du lien ( https://developer.android.com/guide/topics/providers/document-provider.html#permissions):
final int takeFlags = data.getFlags()
& (Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// Check for the freshest data.
getContentResolver().takePersistableUriPermission(originalUri, takeFlags);
Vous pouvez lire plus sur les différences entre l'Intention.ACTION_GET_CONTENT, l'Intention.ACTION_PICK, et de l'Intention.ACTION_OPEN_DOCUMENT ici: http://developer.android.com/reference/android/content/Intent.html#ACTION_OPEN_DOCUMENT
OK, j'ai trouvé un exemple de travail qui échappe à la question:
intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, myClassConstant.SELECT_PICTURE);
Voici ce que j'ai appris...c'est un changement de KitKat, et que ce code ne fonctionne que sur les API de 19 et. Il ne fonctionnera pas pour les versions antérieures, si vous avez besoin d'avoir des méthodes de pré-KitKat ainsi. Une fois que vous obtenez le fichier à l'aide de la Category_Openable argument, dans mon cas, une image, vous pouvez alors l'utiliser par la référence à elle comme de l'URI. Dans mon cas, je stocke les URIString (chemin du fichier) et je suis capable de faire ce que je veux avec elle après l'open se produit.
La question que je vais maintenant essayer de comprendre c'est combien de temps les autorisations de fichier persistent. Il semble qu'il a expiré depuis hier, mon code ressemble pour le UriString, puis essaie d'ouvrir le fichier. Si j'utilise le code ci-dessus pour sélectionner l'image, il fonctionne, il stocke le nom, et j'ai été en mesure de quitter le programme, aller en arrière et il fonctionnait toujours...cependant, ma première exécution du programme ce matin (après ne pas toucher à 12 heures et+), il a agi comme il ne pouvait pas trouver le fichier (et je suis sûr que si je regardais à travers le débogueur, j'aimerais voir le non-critique d'erreur s'affiche à nouveau.
Alors maintenant, la question est: Comment faire pour conserver les autorisations une fois, je sais ce que le fichier (nom)?
Je suppose que l'Uri que vous souhaitez afficher les références d'une image à partir d'un fournisseur qui met en œuvre la nouvelle d'Accès au Stockage-Cadre introduite avec Android 4.4 KitKat. Cela peut être de la Galerie ainsi que sur Google Drive. La seule manière d'accéder à ces documents semble être d'utiliser le système de sélecteur de fichiers. Si l'utilisateur sélectionne les fichiers pour l'ouverture, le système de subventions de l'autorisation à l'application, qui a commencé la boîte de dialogue ouvrir fichier. Ces autorisations sont valables tant que l'appareil n'est pas rebootet. D'autres images peuvent ne pas être accessibles et mener à l'Exception de Sécurité.
Si l'Uri est être persistantes, puis les droits reconnus à l'accès à l'Uri doit également être conservé. Pour plus de détails, regardez ici: https://developer.android.com/guide/topics/providers/document-provider.html#permissions
L' MANAGE_DOCUMENTS
autorisation peut être prise uniquement par le système :
Le MANAGE_DOCUMENTS autorisation. Par défaut, le prestataire est disponible pour tout le monde. L'ajout de cette autorisation limite de votre fournisseur pour le système. Cette restriction est importante pour la sécurité.
(tiré de l'Accès au Stockage-Cadre)
Ainsi, en utilisant cette autorisation dans votre DocumentProvider
vous limitez l'accès à votre fournisseur pour seulement le système. Ce que cela signifie, c'est que seul l' System UI picker
sera en mesure d'accéder à vos fichiers. Donc, pour une application pour récupérer un fichier à partir de votre Provider
il devra lancer une Intent
avec ACTION_OPEN_DOCUMENT
, qui sera en fait le lancement de l' System UI picker
permettra à l'utilisateur de choisir un fichier à partir de là, et puis l' URI
sera retourné à vous.