• 20 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

Ce cours est en vidéo.

Vous pouvez obtenir un certificat de réussite à l'issue de ce cours.

J'ai tout compris !

Mis à jour le 30/04/2018

Partagez un fichier en utilisant FileProvider

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Vos utilisateurs sont ravis de pouvoir écrire tout ce qui leur passe par la tête dans leur carnet de voyage ! Cependant, ils aimeraient maintenant pouvoir partager ce carnet de voyage... et plus particulièrement celui qui se trouve dans l'espace de stockage interne, ce dernier étant théoriquement inaccessible pour l'utilisateur.

Découvrez le FileProvider

Afin d'exposer du contenu de manière protégée sur Android à destination d'applications tierces (par exemple mettre à disposition un fichier contenant du texte... ;)), il est très courant d'utiliser la classe ContentProvider, littéralement "Fournisseur de contenu". Ce dernier permettra de générer une URI sécurisée, permettant à celui qui la possède d'accéder à la ressource que vous aurez partagée.

La classe FileProvider est une classe enfant héritant de ContentProvider, et permettant d'exposer de manière sécurisée une ressource de type File, donc un fichier... :) Nous utiliserons dans notre cas cette classe afin de partager le fichier tripBook.txt se trouvant dans notre mémoire interne.

Définissez un FileProvider

Afin de commencer à utiliser un FileProvider, nous devons déclarer une instance dans le manifeste de notre application :

Extrait de AndroidManifest.xml :

<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.openclassrooms.savemytrip">
    
    ...

    <application
        ...>

        ...

        <!-- FileProvider - Expose File -->
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.openclassrooms.savemytrip.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths" />
        </provider>
        
        ...

    </application>

</manifest>

Explications : Nous avons ici déclaré notre FileProvider directement en XML dans le manifeste de notre application. Pas besoin de JAVA ! 

La déclaration s'effectue grâce à la balise provider qui nous permet de déclarer un ContentProvider :

  • android:name  : Correspond au nom de la classe qui implémente le ContentProvider, ici FileProvider du package android.support.v4.

  • android:authorities  : Permet d'identifier de manière unique l'autorité qui expose les données.

  • android:exported  : Permet de définir si le fournisseur de contenu peut être accessible par d'autres applications que la nôtre. Dans notre cas, nous souhaitons simplement que la nôtre puisse partager du contenu, mais pas que d'autres applications y accèdent.

  • android:grantUriPermissions  : Permet d'autoriser ou non des actions nécessitant généralement des autorisations spéciales, comme les droits de lecture ou d'écriture sur un espace de stockage par exemple.

Nous avons également défini, grâce aux balises meta-data, l'emplacement que nous souhaitons exposer. Pour cela, créez dans le dossier res/ le sous-dossier xml/ et placez-y le fichier suivant :

Fichier res/xml/provider_paths.xml :

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path name="BookTrip" path="bookTrip/"/>
</paths>

Explications : Nous indiquons ici le dossier dans lequel nous avons placé précédemment notre fichier tripBook.txt et que nous souhaitons exposer.

Et c'est tout, le reste se passera dans notre contrôleur TripBookActivity !

Partagez un fichier

Dans un premier temps, nous allons ajouter dans notre classe StorageUtils une méthode permettant de récupérer un fichier depuis un emplacement défini, afin de récupérer par la suite notre fichier tripBook.txt depuis l'espace de stockage interne.

Extrait de StorageUtils.java : 

public class StorageUtils {

    ...

    public static File getFileFromStorage(File rootDestination, Context context, String fileName, String folderName){
        return createOrGetFile(rootDestination, fileName, folderName);
    }

    ...
}

Explications : Rien de bien compliqué ici, nous récupérons simplement un fichier depuis un répertoire racine passé en paramètre ( rootDestination ).

Maintenant, modifions notre activité TripBookActivity afin de partager le fichier.

Extrait de TripBookActivity :

public class TripBookActivity extends BaseActivity {

    ...
    
    // 1 - Define the authority of the FileProvider
    private static final String AUTHORITY="com.openclassrooms.savemytrip.fileprovider";

    ...

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_share:
                // 3 - Call the sharing when user clicked on share button
                this.shareFile();
                return true;
                ...
        }
        return super.onOptionsItemSelected(item);
    }
    
    ...

    // ----------------------------------
    // SHARE FILE
    // ----------------------------------

    // 2 - Share the internal file
    private void shareFile(){
        File internalFile = StorageUtils.getFileFromStorage(getFilesDir(),this, FILENAME, FOLDERNAME);
        Uri contentUri = FileProvider.getUriForFile(getApplicationContext(), AUTHORITY, internalFile);

        Intent sharingIntent = new Intent(Intent.ACTION_SEND);
        sharingIntent.setType("text/*");
        sharingIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
        startActivity(Intent.createChooser(sharingIntent, getString(R.string.trip_book_share)));
    }
}

Explications : Dans un premier temps, nous avons créé une variable statique (1) contenant l'identifiant de notre autorité (celle que l'on a déclarée dans notre manifeste). Puis, nous avons créé une méthode (2) appelée  shareFile  qui sera appelée dès que l'utilisateur cliquera sur le bouton "Partager" (3) de la Toolbar.

Parlons un peu plus de la méthode  shareFile . Celle-ci récupère dans un premier temps le fichier se trouvant dans notre espace de stockage interne grâce à la méthode précédemment créée dans notre classe StorageUtils. Puis, grâce à la méthode  FileProvider.getUriForFile , nous allons générer une URI (donc un identifiant unique) sécurisée pointant vers notre fichier.

Maintenant que cette URI est générée, nous allons pouvoir créer un Intent de partage (Intent.ACTION_SEND), utilisant cette URI pour partager notre fichier ! :)

Et c'est tout ! Lancez votre application et cliquez sur le bouton "Partager". Vous devriez pouvoir maintenant partager ce fichier, pourtant stocké dans la mémoire interne de votre application... ;)

Partager un fichier depuis la mémoire interne
Partager un fichier depuis la mémoire interne

Maintenant que vous êtes à l'aise avec le stockage de fichiers sur les espaces de stockages d'Android (Interne et Externe), nous allons nous intéresser dans la prochaine partie de ce cours à la persistance de données structurées dans une base de données SQLite.

Exemple de certificat de réussite
Exemple de certificat de réussite