Super ! Dorénavant, vos utilisateurs peuvent normalement envoyer et recevoir des messages sur les différents chats de l'application, le tout en temps réel.
Oui mais pour le moment, nos utilisateurs ne peuvent s'envoyer que des données texte... Et ça commence déjà à les lasser !
Mince, alors ne perdons pas de temps ! Dans ce chapitre je vais vous montrer comment récupérer une image locale depuis le téléphone de vos utilisateurs.
Demandez des permissions
Sur Android, vous avez plusieurs manières de demander des permissions à vos utilisateurs en fonction de la version du système Android de leur(s) appareil(s) :
Si la version d'Android est égale ou inférieure à 5.1.1 (API 22) : Au moment de l'installation ou du téléchargement, le système demande à l'utilisateur d'autoriser les permissions exigées par l'application. A chaque mise à jour de l'application, si de nouvelles permissions sont ajoutées, l'utilisateur devra également les approuver. Le seul moyen de révoquer ces permissions est la désinstallation de l'application. Nous configurerons les permissions dans le manifeste de notre application Android.
Si la version d'Android est égale ou supérieure à 6.0 (API 23) : Après que l'application est installée, le système demandera à l'utilisateur d'autoriser les permissions au moment où celle-ci l'exigera. L'utilisateur pourra révoquer à n'importe quel instant les permissions précédemment approuvées. Nous configurerons les permissions dans notre code JAVA.
Ainsi, pour que nos utilisateurs puissent envoyer des images à travers le chat de notre application, il faut que cette dernière puisse avoir la permission d'accéder à leurs données. Cette permission est la suivante : READ_EXTERNAL_STORAGE. Elle nous permettra de lire les données se trouvant sur l'espace de stockage du téléphone Android de l'utilisateur.
Implémentons cette permission, en supportant bien sûr l'ensemble des versions d'Android.
Dans un premier temps, je vous laisse installer la librairie EasyPermissions qui nous facilitera grandement la demande de permission pour les versions d'Android supérieures ou égales à 6.0 :
Extrait de build.gradle :
dependencies {
...
//EASY PERMISSIONS
implementation 'pub.devrel:easypermissions:3.0.0'
}
Une fois la librairie installée, nous commencerons par demander la permission READ_EXTERNAL_STORAGE pour les versions d'Android inférieures ou égales à l'API 22 :
Extrait de AndroidManifest.xml :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.openclassrooms.firebaseoc">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
...
</manifest>
Puis, afin de gérer les versions d'Android supérieures ou égales à l'API 23, modifions notre activité MentorChatActivity afin de demander la permission READ_EXTERNAL_STORAGE uniquement quand l'utilisateur clique sur l'image orange en forme de croix :
Extrait de MentorChatActivity :
public class MentorChatActivity extends BaseActivity<ActivityMentorChatBinding> implements MentorChatAdapter.Listener {
...
private static final String PERMS = Manifest.permission.READ_EXTERNAL_STORAGE;
private static final int RC_IMAGE_PERMS = 100;
private static final int RC_CHOOSE_PHOTO = 200;
...
private void setupListeners(){
binding.addFileButton.setOnClickListener(view -> { addFile(); });
...
}
...
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
...
@AfterPermissionGranted(RC_IMAGE_PERMS)
private void addFile(){
if (!EasyPermissions.hasPermissions(this, PERMS)) {
EasyPermissions.requestPermissions(this, getString(R.string.popup_title_permission_files_access), RC_IMAGE_PERMS, PERMS);
return;
}
Toast.makeText(this, "Vous avez le droit d'accéder aux images !", Toast.LENGTH_SHORT).show();
}
...
}
Explications : L'implémentation de EasyPermissions est plutôt simple. En effet, nous créons d'abord deux variables statiques permettant de plus facilement identifier notre permission et notre requête de demande de permission. Puis, nous re-déclarons la méthode onRequestPermissionsResult()
qui nous servira à récupérer le résultat de la demande de permission (donc de savoir si l'utilisateur a accepté... ou refusé).
Nous transférons la responsabilité du traitement de cette réponse à EasyPermissions qui se chargera de ré-exécuter la méthode addFile()
si l'utilisateur accepte la permission grâce à l'annotation @AfterPermissionGranted(RC_IMAGE_PERMS)
.
Enfin, quand l'utilisateur cliquera sur le bouton orange +, nous vérifierons si ce dernier a correctement accepté la permission READ_EXTERNAL_STORAGE, sinon nous lui afficherons une pop-up lui permettant d'accepter ou non celle-ci grâce à la méthode EasyPermissions.requestPermissions()
de la librairie EasyPermissions.
Lancez l'application et testez le résultat !
Récupérez une image sur le téléphone
Maintenant que les permissions nous sont accordées, nous pouvons enfin récupérer une image sur le téléphone de nos utilisateurs. Pour cela, nous allons utiliser l'Intent Intent.ACTION_PICK !
Modifions notre activité afin de lancer cet Intent.
Extrait de MentorChatActivity :
public class MentorChatActivity extends BaseActivity<ActivityMentorChatBinding> implements MentorChatAdapter.Listener {
...
private Uri uriImageSelected;
...
private static final int RC_CHOOSE_PHOTO = 200;
...
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
this.handleResponse(requestCode, resultCode, data);
}
@AfterPermissionGranted(RC_IMAGE_PERMS)
private void addFile(){
if (!EasyPermissions.hasPermissions(this, PERMS)) {
EasyPermissions.requestPermissions(this, getString(R.string.popup_title_permission_files_access), RC_IMAGE_PERMS, PERMS);
return;
}
Intent i = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RC_CHOOSE_PHOTO);
}
// Handle activity response (after user has chosen or not a picture)
private void handleResponse(int requestCode, int resultCode, Intent data){
if (requestCode == RC_CHOOSE_PHOTO) {
if (resultCode == RESULT_OK) { //SUCCESS
this.uriImageSelected = data.getData();
Glide.with(this) //SHOWING PREVIEW OF IMAGE
.load(this.uriImageSelected)
.apply(RequestOptions.circleCropTransform())
.into(binding.imagePreview);
} else {
Toast.makeText(this, getString(R.string.toast_title_no_image_chosen), Toast.LENGTH_SHORT).show();
}
}
}
...
}
Explications : Premièrement, nous allons créer une variable de classe permettant d'enregistrer par la suite l'URI de l'image sélectionnée par l'utilisateur.
C'est quoi une URI ?
Une fois notre URI créée, nous avons défini une variable statique contenant un identifiant permettant d'identifier l'activité de sélection d'image que nous lancerons via un Intent spécial ( Intent.ACTION_PICK
). Nous avons d'ailleurs placé cette action dans la méthode addFile()
et mis à jour le listener du bouton correspondant.
Cette Intent lançant une activité, il va falloir récupérer le résultat de celle-ci (en l'occurrence l'URI de l'image sélectionnée par l'utilisateur). C'est exactement ce que réalise la méthode handleResponse()
qui affichera l'image en question dans une petite image en forme de bulle. Cette méthode est bien évidemment appelée via la méthode onActivityResult()
.
Et c'est tout ! Lancez maintenant votre application afin de vérifier que le processus de sélection d'image fonctionne correctement.
En résumé
Vous devez utiliser des autorisations afin d'accéder aux fonctionnalités du téléphone (espace de stockage par exemple).
Certains versions d'Android vous demanderons plus d'efforts afin de pouvoir accéder aux autorisations nécessaires au fonctionnement de votre application.