• 8 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 2/2/22

Partagez un fichier en utilisant FileProvider

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...  Dans notre cas, nous utiliserons 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="androidx.core.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 androidx.core.content.

  • 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 AppCompatActivity {

// 1 - Define the authority of the FileProvider

private static final String AUTHORITY="com.openclassrooms.savemytrip.fileprovider";

@Override

public boolean onOptionsItemSelected(MenuItem item) {

int itemId = item.getItemId();

   if (itemId == R.id.action_share) {

shareFile();

return true;

   } else if (itemId == R.id.action_save) {

save();

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...

Une main clique sur le bouton
Partager un fichier depuis la mémoire interne 

En résumé

  •  Pour partager un fichier se situant dans le stockage interne, il faut passer par un FileProvider.

Vous avez maintenant toutes les clés en main pour manipuler et partager des fichiers dans le stockage interne et externe.Nous pouvons à présent attaquer une partie fondamentale dans la programmation Android : le stockage en base de données !

Example of certificate of achievement
Example of certificate of achievement