1. Introduction
Nous emportons nos téléphones partout avec nous, mais jusqu'à présent, il était difficile pour les applications d'adapter leur expérience à l'environnement et à l'activité en constante évolution de l'utilisateur.
Pour ce faire, les développeurs passaient auparavant du temps précieux à combiner différents signaux (position,capteur, etc.) pour déterminer le début et la fin d'une activité comme la marche ou la conduite. Pire encore, lorsque les applications vérifient de manière indépendante et continue les changements d'activité des utilisateurs, l'autonomie de la batterie en souffre.
L'API Activity Recognition Transition résout ces problèmes en fournissant une API simple qui effectue tout le traitement à votre place et vous indique simplement ce qui vous intéresse: quand l'activité d'un utilisateur a changé. Votre application s'abonne simplement à une transition dans les activités qui vous intéressent, et l'API vous informe des modifications.
Par exemple, une application de messagerie peut demander "M'indiquer quand l'utilisateur est entré ou sorti d'un véhicule" pour définir son état sur "occupé". De même, une application de détection de parking peut demander "Dites-moi quand l'utilisateur est sorti d'un véhicule et a commencé à marcher" pour enregistrer l'emplacement de stationnement de l'utilisateur.
Dans cet atelier de programmation, vous allez apprendre à utiliser l'API Activity Recognition Transition pour déterminer quand un utilisateur commence ou arrête une activité comme la marche ou la course à pied.
Conditions préalables
Connaissances du développement Android et des rappels
Points abordés
- S'inscrire pour recevoir des notifications sur les transitions d'activité
- Traiter ces événements
- Se désinscrire des transitions d'activité lorsqu'elles ne sont plus nécessaires
Prérequis
- Android Studio Bumblebee
- Vous disposez d'un appareil ou d'un émulateur Android.
2. Premiers pas
Cloner les éléments du projet de démarrage
Pour vous aider à démarrer le plus rapidement possible, nous avons préparé un projet de démarrage. Si git est installé, vous pouvez simplement exécuter la commande ci-dessous. (Pour vérifier, saisissez git --version
dans le terminal ou l'outil de ligne de commande et vérifiez qu'il s'exécute correctement.)
git clone https://github.com/android/codelab-activity_transitionapi
Si vous ne disposez pas de Git, vous pouvez obtenir le projet sous forme de fichier ZIP:
Importer le projet
Lancez Android Studio, sélectionnez "Open an existing Android Studio project" (Ouvrir un projet Android Studio existant) sur l'écran d'accueil, puis ouvrez le répertoire du projet.
Une fois le projet chargé, une alerte peut s'afficher, indiquant que Git ne suit pas toutes les modifications locales. Vous pouvez cliquer sur Ignorer ou sur le X en haut à droite. (Vous ne transmettrez pas vos modifications au dépôt Git.)
En haut à gauche de la fenêtre du projet, vous devriez obtenir une image semblable à celle affichée dans la vue Android. (Si vous êtes dans la vue Project (Projet), vous devez développer le projet pour voir la même chose.)
Deux icônes de dossier s'affichent (base
et complete
). Chacun est considéré comme un "module" distinct.
Notez que, la première fois, Android Studio peut mettre plusieurs secondes pour compiler le projet en arrière-plan. Pendant ce temps, une icône de chargement s'affiche dans la barre d'état en bas d'Android Studio :
Nous vous recommandons d'attendre la fin de cette opération avant de modifier le code. Android Studio pourra ainsi récupérer tous les composants nécessaires.
Si une invite "Reload for language changes to take effect?" (Charger à nouveau pour appliquer les modifications de langue) ou similaire apparaît sélectionnez "Yes" (Oui).
Comprendre le projet de démarrage
La configuration initiale est terminée, nous pouvons passer à la reconnaissance de l'activité. Nous utiliserons le module base
, qui constitue le point de départ de cet atelier de programmation. En d'autres termes, vous allez ajouter le code de chaque étape à base
.
Vous pouvez utiliser le module complete
pour vérifier votre travail ou comme référence si vous rencontrez des problèmes.
Les principaux composants :
MainActivity
: contient tout le code nécessaire à la reconnaissance d'activité.
Configuration de l'émulateur
Si vous avez besoin d'aide pour configurer un émulateur Android, consultez l'article Exécuter votre application.
Exécuter le projet de démarrage
Exécutons notre application.
- Connectez votre appareil Android à votre ordinateur ou démarrez un émulateur.
- Dans la barre d'outils, sélectionnez la configuration
base
dans le menu déroulant, puis cliquez sur le triangle vert (Exécuter) situé à côté:
- L'application devrait s'afficher ci-dessous:
- L'application n'effectue actuellement que l'impression d'un message. Nous allons maintenant ajouter la reconnaissance de l'activité.
Résumé
Dans cette étape, vous vous êtes familiarisé avec les thèmes suivants :
- Configuration générale de l'atelier de programmation.
- Principes de base de notre application
- Déployez votre application.
3. Examiner la bibliothèque et ajouter une autorisation au fichier manifeste
Pour utiliser l'API Transition dans votre application, vous devez déclarer une dépendance à l'API Google Location and Activity Recognition et spécifier l'autorisation com.google.android.gms.permission.ACTIVITY_RECOGNITION dans le fichier manifeste de l'application.
- Dans le fichier build.gradle, recherchez TODO: Review play services library required for activity recognition (Examiner les bibliothèques de services Play requises pour la reconnaissance d'activité). Aucune action n'est requise pour cette étape (étape 1). Il vous suffit d'examiner la dépendance déclarée dont nous avons besoin. Cela devrait se présenter comme ceci :
// TODO: Review play services library required for activity recognition.
implementation 'com.google.android.gms:play-services-location:19.0.1'
- Dans le fichier
AndroidManifest.xml
du modulebase
, recherchez TODO: Add both activity recognition permissions to the manifest (Ajouter les deux autorisations de reconnaissance de l'activité au fichier manifeste) et ajoutez le code ci-dessous à l'élément<manifest>
.
<!-- TODO: Add both activity recognition permissions to the manifest. -->
<!-- Required for 28 and below. -->
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
<!-- Required for 29+. -->
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
Votre code doit maintenant ressembler à ceci :
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<!-- TODO: Add both activity recognition permissions to the manifest. -->
<!-- Required for 28 and below. -->
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
<!-- Required for 29+. -->
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
...
</manifest>
Comme vous pouvez le voir dans les commentaires, vous devez ajouter une deuxième autorisation pour Android 10. Cela est nécessaire pour l'autorisation d'exécution ajoutée dans la version 29 de l'API.
Et voilà ! Votre application peut désormais prendre en charge la reconnaissance d'activité. Il vous suffit d'ajouter le code pour l'obtenir.
Exécuter l'application
Exécutez votre application à partir d'Android Studio. Il doit se présenter exactement de la même manière. Nous n'avons pas encore ajouté de code pour suivre les transitions. Nous le ferons dans la section suivante.
4. Vérifier/Demander des autorisations d'exécution sur Android
Bien que les autorisations soient couvertes pour la version 28 de l'API et les versions antérieures, nous devons prendre en charge les autorisations d'exécution pour la version 29 et les versions ultérieures:
- Dans
MainActivity.java
, nous vérifierons si l'utilisateur utilise Android 10 (29) ou une version ultérieure. Si c'est le cas, nous vérifierons les autorisations liées à la reconnaissance de l'activité. - Si les autorisations ne sont pas accordées, nous redirigerons l'utilisateur vers un écran de démarrage (
PermissionRationalActivity.java
) qui explique pourquoi l'application a besoin de l'autorisation et lui permet de l'approuver.
Examiner le code qui vérifie la version d'Android
Dans le fichier MainActivity.java
du module base
, recherchez TODO: Review check for devices with Android 10 (29+) (Vérifier la présence d'appareils équipés d'Android 10 (29 et versions ultérieures)). Vous devriez obtenir cet extrait de code.
Remarque : Cette section ne demande aucune intervention de votre part.
// TODO: Review check for devices with Android 10 (29+).
private boolean runningQOrLater =
android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q;
Comme indiqué précédemment, vous devez obtenir l'approbation de l'autorisation d'exécution android.permission.ACTIVITY_RECOGNITION
sous Android 10 et versions ultérieures. Nous utilisons cette vérification simple pour décider si nous devons ou non vérifier les autorisations d'exécution.
Vérifier les autorisations d'exécution pour la reconnaissance de l'activité si nécessaire
Dans le fichier MainActivity.java
du module base
, recherchez TODO: Review permission check for 29+ (Vérifier les autorisations pour les versions 29 et ultérieures). Vous devriez obtenir cet extrait de code.
Remarque : Cette section ne demande aucune intervention de votre part.
// TODO: Review permission check for 29+.
if (runningQOrLater) {
return PackageManager.PERMISSION_GRANTED == ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACTIVITY_RECOGNITION
);
} else {
return true;
}
Nous utilisons la variable que nous avons créée à l'étape précédente pour voir si nous devons vérifier les autorisations d'exécution.
Pour Q et versions ultérieures, nous vérifions et renvoyons le résultat de l'autorisation d'exécution. Il s'agit d'une méthode plus vaste appelée activityRecognitionPermissionApproved()
, qui indique au développeur en un seul appel s'il doit demander une autorisation ou non.
Demander des autorisations d'exécution et activer/désactiver les transitions de reconnaissance de l'activité
Dans le fichier MainActivity.java
du module base
, recherchez TODO: Enable/Disable activity tracking and ask for permissions if needed (Activer/Désactiver le suivi de l'activité et demander les autorisations si nécessaire). Ajoutez le code ci-dessous après le commentaire.
// TODO: Enable/Disable activity tracking and ask for permissions if needed.
if (activityRecognitionPermissionApproved()) {
if (activityTrackingEnabled) {
disableActivityTransitions();
} else {
enableActivityTransitions();
}
} else {
// Request permission and start activity for result. If the permission is approved, we
// want to make sure we start activity recognition tracking.
Intent startIntent = new Intent(this, PermissionRationalActivity.class);
startActivityForResult(startIntent, 0);
}
Ici, nous demandons si la reconnaissance de l'activité est approuvée. Si c'est le cas et que la reconnaissance de l'activité est déjà activée, nous la désactivons. Sinon, nous l'activons.
Si l'autorisation n'est pas accordée, nous devons rediriger l'utilisateur vers l'écran de démarrage, qui explique pourquoi nous avons besoin de l'autorisation, et l'inviter à nous l'accorder.
Examiner le code de la demande d'autorisation
Dans le fichier PermissionRationalActivity.java
du module base
, recherchez TODO: Review permission request for activity recognition (Examiner la demande d'autorisation pour la reconnaissance de l'activité). Vous devriez obtenir cet extrait de code.
Remarque : Cette section ne demande aucune intervention de votre part.
// TODO: Review permission request for activity recognition.
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.ACTIVITY_RECOGNITION},
PERMISSION_REQUEST_ACTIVITY_RECOGNITION)
Il s'agit de la partie la plus importante de l'activité et celle que vous devez examiner. Le code déclenche la demande d'autorisation lorsque l'utilisateur la demande.
En dehors de cela, la classe PermissionRationalActivity.java
affiche une justification expliquant pourquoi l'utilisateur doit approuver l'autorisation de reconnaissance de l'activité (bonne pratique). L'utilisateur peut cliquer sur le bouton Non, merci ou sur le bouton Continuer (ce qui déclenche le code ci-dessus).
N'hésitez pas à consulter le fichier pour en savoir plus.
5. Enregistrer/Désenregistrer un broadcast receiver pour les transitions d'activité
Avant de configurer le code de reconnaissance d'activité, nous voulons nous assurer que notre activité peut gérer les actions de transition générées par le système.
Créer un BroadcastReceiver pour la transition
Dans le fichier MainActivity.java
du module base
, recherchez TODO: Create a BroadcastReceiver to listen for activity transitions (Créer un BroadcastReceiver pour écouter les transitions d'activité). Collez l'extrait ci-dessous.
// TODO: Create a BroadcastReceiver to listen for activity transitions.
// The receiver listens for the PendingIntent above that is triggered by the system when an
// activity transition occurs.
mTransitionsReceiver = new TransitionsReceiver();
Enregistrer un BroadcastReceiver pour la transition
Dans le fichier MainActivity.java
du module base
, recherchez TODO: Register a BroadcastReceiver to listen for activity transitions (Enregistrer un BroadcastReceiver pour écouter les transitions d'activité). (il se trouve dans onStart()
). Collez l'extrait ci-dessous.
// TODO: Register a BroadcastReceiver to listen for activity transitions.
registerReceiver(mTransitionsReceiver, new IntentFilter(TRANSITIONS_RECEIVER_ACTION));
Nous pouvons maintenant obtenir des mises à jour lorsque les transitions d'activité sont déclenchées via le PendingIntent.
Désenregistrer BroadcastReceiver
Dans le module base
, recherchez Unregister activity transition receiver when user leaves the app (Désenregistrer le récepteur de transition d'activité lorsque l'utilisateur quitte l'application) dans MainActivity.java
. (il se trouve dans onStop()
).Collez l'extrait ci-dessous.
// TODO: Unregister activity transition receiver when user leaves the app.
unregisterReceiver(mTransitionsReceiver);
Il est recommandé d'annuler l'enregistrement d'un récepteur lorsque l'Activity
s'arrête.
6. Configurer les transitions d'activité et demander des mises à jour
Pour commencer à recevoir des informations sur la transition des activités, vous devez implémenter les éléments suivants:
- Un objet ActivityTransitionRequest qui spécifie le type d'activité et de transition.
- Un rappel PendingIntent où votre application reçoit des notifications. Pour en savoir plus, consultez la section Utiliser un intent en attente.
Créer une liste d'ActivitiyTransitions à suivre
Pour créer l'objet ActivityTransitionRequest, vous devez créer une liste d'objets ActivityTransition, qui représentent la transition que vous souhaitez suivre. Un objet ActivityTransition inclut les données suivantes:
- Type d'activité, représenté par la classe DetectedActivity. L'API Transition accepte les activités suivantes:
- Type de transition, représenté par la classe ActivityTransition. Les types de transition sont les suivants:
Dans le fichier MainActivity.java
du module base
, recherchez TODO: Add activity transitions to track (Ajouter les transitions d'activité à suivre). Ajoutez le code ci-dessous après le commentaire.
// TODO: Add activity transitions to track.
activityTransitionList.add(new ActivityTransition.Builder()
.setActivityType(DetectedActivity.WALKING)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
.build());
activityTransitionList.add(new ActivityTransition.Builder()
.setActivityType(DetectedActivity.WALKING)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
.build());
activityTransitionList.add(new ActivityTransition.Builder()
.setActivityType(DetectedActivity.STILL)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
.build());
activityTransitionList.add(new ActivityTransition.Builder()
.setActivityType(DetectedActivity.STILL)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
.build());
Ce code ajoute les transitions que nous souhaitons suivre à une liste précédemment vide.
Créer un PendingIntent
Comme indiqué précédemment, nous avons besoin d'un PendingIntent
si nous souhaitons être avertis de tout changement dans notre ActivityTransitionRequest. Par conséquent, avant de configurer notre ActivityTransitionRequest, nous devons créer un PendingIntent
.
Dans le fichier MainActivity.java
du module base
, recherchez TODO: Initialize PendingIntent that will be triggered when a activity transition occurs (Initialiser le PendingIntent qui sera déclenché lorsqu'une transition d'activité se produira). Ajoutez le code ci-dessous après le commentaire.
// TODO: Initialize PendingIntent that will be triggered when a activity transition occurs.
Intent intent = new Intent(TRANSITIONS_RECEIVER_ACTION);
mActivityTransitionsPendingIntent =
PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
Nous disposons maintenant d'un PendingIntent que nous pouvons déclencher lorsqu'une des transitions d'activité se produit.
Créer une ActivityTransitionRequest et demander des mises à jour
Vous pouvez créer un objet ActivityTransitionRequest en transmettant la liste des ActivityTransitions à la classe ActivityTransitionRequest.
Dans le fichier MainActivity.java
du module base
, recherchez Create request and listen for activity changes (Créer une requête et écouter les modifications d'activité). Ajoutez le code ci-dessous après le commentaire.
// TODO: Create request and listen for activity changes.
ActivityTransitionRequest request = new ActivityTransitionRequest(activityTransitionList);
// Register for Transitions Updates.
Task<Void> task =
ActivityRecognition.getClient(this)
.requestActivityTransitionUpdates(request, mActivityTransitionsPendingIntent);
task.addOnSuccessListener(
new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void result) {
activityTrackingEnabled = true;
printToScreen("Transitions Api was successfully registered.");
}
});
task.addOnFailureListener(
new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
printToScreen("Transitions Api could NOT be registered: " + e);
Log.e(TAG, "Transitions Api could NOT be registered: " + e);
}
});
Passons en revue le code. Tout d'abord, nous créons un ActivityTransitionRequest à partir de notre liste de transitions d'activité.
ActivityTransitionRequest request = new ActivityTransitionRequest(activityTransitionList);
Ensuite, nous nous abonnons aux mises à jour de la transition d'activité en transmettant votre instance d'ActivityTransitionRequest et notre objet PendingIntent que nous avons créé à l'étape précédente à la méthode requestActivityTransitionUpdates(). La méthode requestActivityTransitionUpdates() renvoie un objet Task pour lequel vous pouvez vérifier la réussite ou l'échec, comme indiqué dans le bloc de code suivant:
// Register for Transitions Updates.
Task<Void> task =
ActivityRecognition.getClient(this)
.requestActivityTransitionUpdates(request, mActivityTransitionsPendingIntent);
task.addOnSuccessListener(
new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void result) {
activityTrackingEnabled = true;
printToScreen("Transitions Api was successfully registered.");
}
});
task.addOnFailureListener(
new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
printToScreen("Transitions Api could NOT be registered: " + e);
Log.e(TAG, "Transitions Api could NOT be registered: " + e);
}
});
Une fois que vous êtes abonné aux mises à jour de la transition d'activité, votre application reçoit des notifications dans le PendingIntent enregistré. Nous définissons également une variable indiquant que le suivi de l'activité est activé pour nous permettre de savoir si nous devons le désactiver/activer si l'utilisateur clique à nouveau sur le bouton.
Supprimer les mises à jour lorsque l'application se ferme
Il est important de supprimer les mises à jour de transition lorsque l'application se ferme.
Dans le fichier MainActivity.java
du module base
, recherchez Stop listening for activity changes (Arrêter l'écoute des modifications d'activité). Ajoutez le code ci-dessous après le commentaire.
// TODO: Stop listening for activity changes.
ActivityRecognition.getClient(this).removeActivityTransitionUpdates(mActivityTransitionsPendingIntent)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
activityTrackingEnabled = false;
printToScreen("Transitions successfully unregistered.");
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
printToScreen("Transitions could not be unregistered: " + e);
Log.e(TAG,"Transitions could not be unregistered: " + e);
}
});
Nous devons maintenant appeler la méthode contenant le code ci-dessus lorsque l'application s'arrête.
Dans le fichier MainActivity.java
du module base
, recherchez TODO: Disable activity transitions when user leaves the app (Désactiver les transitions d'activité lorsque l'utilisateur quitte l'application) dans onPause()
. Ajoutez le code ci-dessous après le commentaire.
// TODO: Disable activity transitions when user leaves the app.
if (activityTrackingEnabled) {
disableActivityTransitions();
}
Vous avez terminé de suivre les modifications apportées aux transitions d'activités. Il ne nous reste plus qu'à traiter les mises à jour.
7. Traiter les événements
Lorsque la transition d'activité demandée se produit, votre application reçoit un rappel d'intent. Un objet ActivityTransitionResult peut être extrait de l'intent, qui inclut une liste d'objets ActivityTransitionEvent. Les événements sont classés par ordre chronologique. Par exemple, si une application demande le type d'activité IN_VEHICLE au niveau des transitions ACTIVITY_TRANSITION_ENTER et ACTIVITY_TRANSITION_EXIT, elle reçoit un objet ActivityTransitionEvent lorsque l'utilisateur commence à conduire, et un autre lorsqu'il passe à une autre activité.
Ajoutons le code permettant de gérer ces événements.
Dans le module base
, recherchez TODO: Extract activity transition information from listener (TODO : Extraire les informations de transition d'activité de l'écouteur) dans MainActivity.java
, dans onReceive()
du BroadcastReceiver que nous avons créé précédemment. Ajoutez le code ci-dessous après le commentaire.
// TODO: Extract activity transition information from listener.
if (ActivityTransitionResult.hasResult(intent)) {
ActivityTransitionResult result = ActivityTransitionResult.extractResult(intent);
for (ActivityTransitionEvent event : result.getTransitionEvents()) {
String info = "Transition: " + toActivityString(event.getActivityType()) +
" (" + toTransitionType(event.getTransitionType()) + ")" + " " +
new SimpleDateFormat("HH:mm:ss", Locale.US).format(new Date());
printToScreen(info);
}
}
Les informations sont converties en String
et imprimées à l'écran.
Et voilà ! Vous avez terminé. Essayez d'exécuter l'application.
REMARQUE IMPORTANTE: Il est difficile de reproduire les modifications d'activité sur l'émulateur. Nous vous recommandons donc d'utiliser un appareil physique.
Vous devriez pouvoir suivre les modifications d'activité.
Pour de meilleurs résultats, installez l'application sur un appareil physique et faites le tour de votre maison. :)
8. Examiner le code
Vous avez créé une application simple qui suit les transitions d'activités et les liste à l'écran.
N'hésitez pas à lire l'intégralité du code pour examiner ce que vous avez fait et mieux comprendre comment ces éléments fonctionnent ensemble.