web-dev-qa-db-fra.com

Android 6: ne peut plus partager de fichiers?

Je partage une image et ce code fonctionne correctement pour les appareils antérieurs à Android 6:

Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/*");
Uri uri = Uri.fromFile(new File(mFilename));
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
mContext.startActivity(Intent.createChooser(shareIntent, mChooserTitle));

Cependant, l'erreur " ne peut pas joindre les fichiers vides " lorsque je tente de partager avec Android 6.

J'ai vérifié que le fichier existe et qu'il n'est pas de longueur nulle.

Quelqu'un a une solution pour cela?

29
Daniele B

Une des limites du système de permission d'exécution Android 6.0 est qu'il y aura des cas de blocage pouvant causer des problèmes. Ce que vous avez rencontré est un: essayez de partager un fichier sur un stockage externe avec une application qui ne dispose pas des autorisations nécessaires à l'exécution pour ce chemin d'interface utilisateur particulier.

Je dis qu'il s'agit d'un "cas d'angle" car, pour que ce bogue de l'application réceptrice affecte l'utilisateur, celui-ci ne peut pas avoir déjà utilisé cette application et obtenu l'autorisation nécessaire. Non plus:

  • L'utilisateur n'a jamais utilisé cette application auparavant, et pourtant, il essaie toujours de partager du contenu, ou

  • L'utilisateur a révoqué l'autorisation via Paramètres, mais ne s'est pas rendu compte que cela casserait cette fonctionnalité.

Les deux sont des événements à faible probabilité.

En tant qu’expéditeur, vous avez deux options principales:

  1. Éloignez-vous des valeurs file://Uri au lieu d'une valeur ContentProvider comme FileProvider, de sorte que l'autorisation n'est plus nécessaire, ou

  2. Vivre avec le coin

22
CommonsWare

Je l'ai résolu en implémentant une FileProvider, comme suggéré par @CommonsWare

Vous devez d’abord configurer un fournisseur de fichiers:

  • d’abord, ajoutez le <provider> à votre fichier XML de fichier manifeste

    <provider
        Android:name="Android.support.v4.content.FileProvider"
        Android:authorities="com.myfileprovider"
        Android:exported="false"
        Android:grantUriPermissions="true">
        <meta-data
            Android:name="Android.support.FILE_PROVIDER_PATHS"
            Android:resource="@xml/file_provider_paths" />
    </provider>
    
  • deuxièmement, définissez vos chemins de fichiers dans un fichier XML séparé, je l'ai appelé "file_provider_paths.xml".

    <paths xmlns:Android="http://schemas.Android.com/apk/res/Android">
        <external-path name="share" path="/" />
    </paths>
    

vous pouvez trouver l'explication complète dans cette page de documentation

après avoir configuré votre fournisseur de fichiers en XML, le code permettant de partager le fichier image est le code suivant:

Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/*");
Uri fileUri = FileProvider.getUriForFile(mContext, "com.myfileprovider", new File(mFilename));
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
mContext.startActivity(Intent.createChooser(shareIntent, mChooserTitle));
36
Daniele B

Sinon, vous n'avez pas besoin d'un ContentProvider/FileProvider. Vous pouvez simplement ajouter le drapeau qui accorde une autorisation de lecture sur l'URI partagé. Plus précisément, share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); devrait faire l'affaire. 

2
yrizk

Pour résoudre ce problème, j’avais un autre moyen d’obtenir l’URI de style fournisseur de contenu en utilisant MediaScannerConnection juste après l’écriture de votre fichier dans le répertoire public:

        MediaScannerConnection.scanFile(context, new String[] {imageFile.toString()}, yourMimeType, new OnScanCompletedListener() {
            @Override
            public void onScanCompleted(String path, Uri uri) {
                //uri = "content://" style URI that is safe to attach to share intent
            }
        });

Cela peut être une solution plus courte pour vos besoins.

0
AndroidEx