Vous êtes sur la page 1sur 262

Cours

Développement
Android

Enseignant: Mehdi M’tir

1
Introduction à Android

2
Qu'est-ce que Android?
● Système d'exploitation mobile basé sur le noyau Linux
● Interface utilisateur optimisée pour écrans tactiles
● Utilisé sur plus de 80% de tous les smartphones
● Utilisé pour des montres, des téléviseurs et des voitures
● Plus de 2 millions d'applications dans Google Play Store
● Très personnalisable pour les appareils / par les fournisseurs
● Open source

3
L’écran d’accueil Android
● Icônes de lancement pour les applications
● Widgets avec mise à jour automatique
pour le contenu en direct
● Peut être sur plusieurs pages
● Dossiers pour organiser des applications
● "OK Google"

4
Exemples d’applications Android

Pandora Pokemon GO Facebook


Messenger
5
Android Software Developer Kit (SDK)
● Outils de développement (debugger, monitors, editors)
● Bibliothèques utiles (maps, wearables)
● Machines virtuelles (emulators)
● Documentation (developers.android.com)
● Exemples de code

6
Android Studio
● IDE officiel pour Android
● Développer, exécuter,
débuguer, tester, et
déployer les applications
● Moniteurs et outils de
performance
● Machines virtuelles
● Vues de projet
● Mise en page visuelle

7
Google Play store
Publier les applications à travers Google Play :
● App Store officiel pour Android
● Service de distribution numérique exploité par Google

8
Architecture Android

1. Applications (système
& utilisateur)
2. APIs du système
Android
3. APIs natives; env.
d’exécution
4. Expose les capacités
matérielles
5. Linux Kernel
9
Versions Android
Codename Version Released API Level
Ice Cream Sandwich 4.0 - 4.0.4 Oct 2011 14 - 15
Jelly Bean 4.1 - 4.3.1 July 2012 16 - 18
KitKat 4.4 - 4.4.4 Oct 2013 19 - 20
Lollipop 5.0 - 5.1.1 Nov 2014 21 - 22
Marshmallow 6.0 - 6.0.1 Oct 2015 23
Nougat 7.0 – 7.1 Sept 2016 24 - 25
Oreo 8.0 – 8.1 Août 2017 26 - 27

10
Dévelopment d’applications

11
Qu’est-ce qu’une application Android?
● Un ou plusieurs écrans interactifs
● Écrit avec Java ou Kotlin et XML
● Utilise le kit de développement logiciel Android (SDK)
● Utilise les bibliothèques Android et le framework d’applications
Android (Android Application Framework)
● Exécuté par Android Runtime (ART)

12
Challenges du développement Android
● Plusieurs tailles d'écran et résolutions
● Performance: rendre vos applications sensibles et fluides
● Sécurité: garder le code source et les données utilisateur en sécurité
● Compatibilité: fonctionne bien sur les anciennes versions de la plate-
forme
● Marketing: comprendre le marché et vos utilisateurs.

13
Les blocks de construction d’applications

● Ressources : layouts, images, strings, couleurs au format XML


et fichiers multimédias
● Composants : activités, services, …, et classes auxiliaires en tant
que code Java
● Manifest: information à propos de l’application pour le runtime
● Configuration du Build : les versions APK dans les fichiers de
configuration Gradle.
14
Les composants de base

● Activité un écran unique avec une interface utilisateur


● Service effectue des tâches de longue durée en arrière-plan
● Content provider gère un ensemble de données partagé
● Broadcast receiver répond aux évènements à l’échelle du
système.

15
Android Studio

16
Qu’est-ce que Android Studio?
● IDE Android
● Structure de projet
● Templates
● Editeur de Layout
● Outils de test
● Buil basé sur Gradle
● Console de log
● Debugueur
● Moniteurs
● Emulateurs
17
Installation
● Mac, Windows, ou Linux
● Nécessite Java Development Kit (JDK) 1.7 ou plus à partir de
Oracle Java SE downloads page
● Pointer la variable d’environnement JAVA_HOME vers le
dossier d’installation du JDK.
● Télécharger et installer Android à partir de
http://developer.android.com/sdk/index.html

18
Créer une première
application Android

19
Démarrer Android Studio

20
Créer un nouveau projet

21
Nommer l’application

22
Choisir un template pour l’activité
Choisissez Empty
Activity ou Base
Activity pour des
activités simples et
personnalisées.

23
Nommer votre activité
● Une bonne pratique
est de nommer
l’activité principale
MainActivity et son
layout activity_main
● Utiliser AppCompat
● Générer le fichier
file est recommandé

24
Android Studio Panes
Layout
Editor

Project
Files

Android Monitors:
logcat: log messages

25
Les dossiers du project
1. manifests—le fichier Android Manifest
- description de l'application lue par le
moteur d'exécution Android.
2. java—packages de code source Java
3. res—Ressources (XML) - layout,
strings, images, dimensions, colors...
4. build.gradle—Fichier de build Gradle

26
Le système de build Gradle
● Système de build moderne intégré sous Android Studio
● Trois build.gradle:
○ project
○ module
○ settings
● Généralement pas nécessaire de connaître les détails Gradle de
bas niveau
● Pour en savoir plus sur gradle : https://gradle.org/
27
Lancer une application
1. Lancer

2. Sélectionner
un appareil
(physique ou
virtuel)
3. Valider
28 28
Créer un appareil virtuel
Utiliser les emulateurs pour tester l’application sur différentes versions d’Android.

Tools > Android > AVD Manager or:

29
Configure virtual device
1. Utiliser le hardware 2. Sélectionner la version Android
3. Finaliser

30
Lancement sur un appareil virtuel

31
Lancer sur un appareil physique
1. Activer les options pour Développeur:
a. Paramètres > A propos du téléphone
b. Tapper Build number 7 fois consécutives
2. Activer le bébogage USB
a. Paramètres> Option pour les développeurs >
Débogage USB
3. Connect le smartphone à votre ordinateur à l’aide d’un
cable USB

32
Suivre l’exécution de votre application
● Lorsque l’application est lancée, Android Monitor logcat affiche
des informations relatives à l’exécution.
● Vous pouvez ajouter des messages de logs dans le code de votre
application.

33
Ajouter des messages de log
import android.util.Log;

// Use class name as tag


private static final String TAG =
MainActivity.class.getSimpleName();

// Show message in Android Monitor, logcat pane


// Log.<log-level>(TAG, "Message");
Log.d(TAG, “Creating the URI…”);

34
Views, Layouts, et Resources

35
Les views
En regardant l’écran de votre
smartphone, tout élément graphique
que vous voyez est une vue (View).
Views

36
Qu’est qu’une vue (view)
Les Vues sont les blocs de construction de base de toute interface
graphique sous Android.
● Pour le texte TextView, EditText …
● Pour la navigation Button, menus …
● Pour le scroll ScrollView, RecyclerView ..
⇒ Toues les classes des vues héritent de la classe View
⇒ Toute vue offre un ensemble de propriétés (couleur,
dimensions, positionnement …)

37
Exemples de views

Button CheckBox
RadioButton
EditText
Switch
SeekBar

38
Comment créer et positionner une vue?

● Graphiquement avec Android Studio

● Dans les fichiers XML directement.

● Dans le code Java (non recommandé).

39
Le Layout Editor pour éditer les vues

Visual representation of
what's in XML file.

40
Utiliser le Layout Editor

1. Resizing handle
2. Constraint line and handle
3. Baseline handle
4. Constraint handle

41
Vues définies dans XML
<TextView
android:id="@+id/show_count"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/myBackgroundColor"
android:text="@string/count_initial_value"
android:textColor="@color/colorPrimary"
android:textSize="@dimen/count_text_size"
android:textStyle="bold"
/>
42
Les propriétés des vues dans XML
android:<property_name>="<property_value>"
Example: android:layout_width="match_parent"

android:<property_name>="@<resource_type>/resource_id"
Example: android:text="@string/button_label_next"

android:<property_name>="@+id/view_id"
Example: android:id="@+id/show_count"

43
Créer des Vues dans le code Java
context
Dans une Activité :

TextView myText = new TextView(this);


myText.setText("Display this text!");

44
Qu’est-ce qu’un context?
● Context est une interface pour des informations globales à
propos de l’environnement de l’application.
● Récupérer le context :
Context context = getApplicationContext();
● Une activité a son propre context :
TextView myText = new TextView(this);

45
Les vues personnalisées (custom views)
● Le système Android offre plus de 100 types de vues différentes
toutes héritées de la classe View
● Si nécessaire, Vous pouvez créer des vues personnalisées en
héritant d’une des vues existantes ou directement de la classe
View

46
Les vues ViewGroup
Un ViewGroup (parent) est un type de vues contenant d’autres vues
(enfant)
ViewGroup eat la classe de base pour les layouts et les conteneurs
de vues
● ScrollView—vue scrollable contenant une seule vue enfant
● LinearLayout—arrange le vue horizontalement ou verticalement
● RecyclerView— liste de vues ou groupe de vues scrollables

47
Hiérarchie de viewGroups et de views

ViewGroup La recine est toujours composée


d’un ViewGroup

ViewGroup View View

View View View

48
Bonnes pratiques pour la hiérarchie de vues
● L’arrangement de la hiérarchie des vues affecte les performances
de l’application.
⇒ Utiliser autant que possible un nombre réduit de vues simples
⇒ Garder une hiérarchie aussi plate que possible—limiter les vues et
groupes de vues imbriqués.

49
Layouts

50
Layout Views
Layouts
● Types spéciphiques de groupes de vues
● Sont des sous-classes de ViewGroup
● Contiennent des vues imbriqués
● Pour être organisés en lignes, colomnes, grilles, …

51
Les Layouts les plus connus

LinearLayout RelativeLayout GridLayout TableLayout


Plus récent : ConstraintLayout – Connecter les vues en se basant sur des
contraintes

52
Créer un Layout dans XML
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
... />
<Button
... />
</LinearLayout
53
Créer un Layout dans une activité Java
LinearLayout linearL = new LinearLayout(this);
linearL.setOrientation(LinearLayout.VERTICAL);

TextView myText = new TextView(this);


myText.setText("Display this text!");

linearL.addView(myText);
setContentView(linearL);

54
Configurer largeur et hauteur dans Java
Spécifier la largeur et la hauteur d’un layout :
LinearLayout.LayoutParams layoutParams =
new Linear.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
myView.setLayoutParams(layoutParams);

55
Gestion des
évènements.

56
Événement (event)
Quelque chose qui survient :
● dans l’interface utilisateur (UI): Click, tap, drag …
● dans l’appareil : déplacement, driving, tilting
=> Les évènements sont notifiés par le système Android.

57
Event Handlers
Méthodes répondant à un évènement :
● Une méthode, appelée event handler, est déclanchée par un
évènement spéciphique et réalise une action en réponse à
l’évènement.

58
Gestion d’un clique dans XML & Java
Attacher un handler à la Implémenter le handler dans le
vue dans le layout: code de l’activité:
android:onClick="showToast" public void showToast(View view) {
String msg = "Hello Toast!";
Toast toast = Toast.makeText(
this, msg, duration);
toast.show();
}
}

59
Gestion d’un clique dans Java
final Button button = (Button) findViewById(R.id.button_id);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String msg = "Hello Toast!";
Toast toast = Toast.makeText(this, msg, duration);
toast.show();
}
});

60
Ressources

61
Ressources

● Séparer les données statiques du code dans vos mises en page.


● Chaînes de caractères (strings), dimensions, images, texte de
menu, couleurs, styles
● Utiles pour la localisation

62
Ou trouver les ressources dans le project?

ressources et fichiers de
ressource
Sauvegardés dans le
répertoire res

63
Faire référence aux ressources dans le code
● Layout:
R.layout.activity_main
setContentView(R.layout.activity_main);
● View:
R.id.recyclerview
rv = (RecyclerView) findViewById(R.id.recyclerview);
● String:
In Java: R.string.title
In XML: android:text="@string/title"

64
Unités de mesure
● Device Independent Pixels (dp) – Pour les vues
● Scale Independent Pixels (sp) – Pour le texte

Ne pas utiliser les unités de mesure classiques (indépendantes de


l’appareil) tels que px, in, mm, pt …:

65
Activités

66
Présentation des
activités
(Vue générale)

67
Qu’est-ce qu’une activité?
● Une activité (activity) est un composant de base d’une
application Android
● Représente une fenêtre, une hiérarchie de views
● Typiquement remplit un écran, mais peut être intégrée dans une
autre activité.
● Représentée par une classe Java,
● Une activité / un fichier.

68
Quel est le rôle d’une activité?
● Représenter une tâche (une activité), tel que : afficher la liste des
contacts, envoyer un email, ou lancer un appel …
● Gèrer les intéractions avec l’utilisateur, tels que :
clique sur un bouton, saisie de texte, vérifier les paramètres
d’authentification…
● Lancer d’autres activités (dans la même application ou dans
d’autres applications)
● Elle a un cycle de vie.

69
Exemples d’activités

70
Implémenter
une activité

71
Étapes d’implémentation
1.Définir le layout en XML
2.Définir la classe de l’activité en java
○ extends AppCompatActivity
3.Connecter la classe de l’activité au layout
○ setContentView() dans onCreate()
4.Déclarer l’activité dans le manifeste d’Android.

72
1.Définir le layout en XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Let's Shop for Food!" />
</RelativeLayout>

73
2. Définir la classe de l’activité en Java

public class MainActivity extends AppCompatActivity {


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}

74
3. Connecter l’activité et le layout

public class MainActivity extends AppCompatActivity {


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);
}
} Resource is layout in this XML file

75
4. Déclarer l’activité dans le manifest

<activity android:name=".MainActivity">

76
4. Déclarer l’activité principale
L’activité principale nécessite d’inclure un Intent pour démarrer à
partir de l’icône de lancement (launcher icon)
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

77
Intents

78
Qu’est-ce qu’un intent?
Un intent est une description d'une opération à effectuer.
Un Intent est un objet utilisé pour demander une action à un autre
composant de l'application via le système Android.

Originator App component

Intent Action
Android
System

79
Que peuvent faire les intents?
● Lancer les activités
○ Un clic sur un bouton lance une nouvelle activité pour la saisie de texte
○ Cliquer sur Partager ouvre une application qui vous permet de poster une
photo
● Démarrer les services
○ Lancer le téléchargement d'un fichier en arrière-plan
● Délivrer des broadcasts
○ Le système informe toutes les application qu’un appel arrive.

80
Intents explicites et implicites
Intent Explicite
● Lance une activité spécifique

Intent Implicite
● Demande au système de trouver une activité capable de traiter la
requête demandée.

81
Lancer une
activité

82
Lancer une activité avec un intent explicite

Pour lancer une activité spécifique, utiliser un intent explicite


1.Créer un intent
○ Intent intent = new Intent(this, ActivityName.class);
2.Utiliser l’intent pour lancer l’activité
○ startActivity(intent);

83
Lancer une activité avec un intent implicite
Pour demander à Android de trouver une activité pour gérer votre
demande, utilisez un intent implicite
1.Créer un intent
○ Intent intent = new Intent(action, uri);
2.Utiliser l’intent pour lancer l’activité
○ startActivity(intent);

84
Intents Implicites - Exemples
Lancer une page web
Uri uri = Uri.parse("http://www.google.com");
Intent it = new Intent(Intent.ACTION_VIEW,uri);
startActivity(it);
Composer un numéro de téléphone
Uri uri = Uri.parse("tel:8005551234");
Intent it = new Intent(Intent.ACTION_DIAL, uri);
startActivity(it);
85
Comment fonctionnent les activités?
● Toutes les activités sont gérées par Android runtime
● Lancées par un "intent", un message vers Android runtime pour
lancer une activité

User clicks MainActivity FoodListActivity OrderActivity


launcher icon What do you want to do? Choose food items...Next Place order

Intent: Start app Start main Intent: Shop Start choose Intent: order Start finish
Android activity Android food activity Android order activity
System System System

86
Envoyer et
recevoir des
données

87
Deux types d’envoi de données avec les
intents
● Data — une information dont la localisation des données peut
être représentée par un URI
● Extras — une ou plusieurs informations sous la forme d'une
collection de paires clé-valeur dans un Bundle

88
Envoyer et recevoir les données
Dans la première activité (d'envoi) :
1.Créer l'objet Intent
2.Mettre des datas ou extras dans l’intent
3.Lancer l’activité avec startActivity()

Dans la deuxième activité (réception) :


1.Obtenir l'objet intent avec lequel l'activité a été démarrée
2.Récupérer les datas ou les extras de l'objet Intent
89
Mettre un URI comme data d’intent
// URL d’une page web
intent.setData(
Uri.parse("http://www.google.com"));

// URI d’un fichier


intent.setData(
Uri.fromFile(new File("/sdcard/sample.jpg")));

90
Mettre des informations dans des extras
● putExtra(String name, int value)
⇒ intent.putExtra("level", 406);
● putExtra(String name, String[] value)
⇒ String[] foodList = {"Rice", "Beans", "Fruit"};
intent.putExtra("food", foodList);
● putExtras(bundle);
⇒ si beaucoup de données, d'abord créer un bundle puis le passer à putExtras.

91
Envoi de données avec putExtras
public static final String EXTRA_MESSAGE_KEY =
"com.example.android.twoactivities.extra.MESSAGE";

Intent intent = new Intent(this, SecondActivity.class);


String message = "Hello Activity!";
intent.putExtra(EXTRA_MESSAGE_KEY, message);
startActivity(intent);

92
Récupérer les données à partir de l’intent
● getData();
⇒ Uri locationUri = intent.getData();
● int getIntExtra (String name, int defaultValue)
⇒ int level = intent.getIntExtra("level", 0);
● Bundle bundle = intent.getExtras();
⇒ Récupérer toutes les données dans un seul bundle.

93
Renvoyer les données à l'activité de départ
1.Utiliser startActivityForResult() pour lancer la deuxième activité
2.Pour retourner les données à partir de la deuxième activité :
● Créer un nouvel Intent
● Mettre les données de réponse dans l'intent en utilisant putExtra()
● Affecter le résultat dansActivity.RESULT_OK ou RESULT_CANCELED,
si l'utilisateur a annulé
● Appeler finish() pour fermer l’activité

3. Implémenter onActivityResult() dans la première activité

94
1.startActivityForResult() - Exemple

public static final int CHOOSE_FOOD_REQUEST = 1;

Intent intent = new Intent(this, ChooseFoodItemsActivity.class);


startActivityForResult(intent, CHOOSE_FOOD_REQUEST);

95
2.Retourner les données
// Create an intent
Intent replyIntent = new Intent();

// Put the data to return into the extra


replyIntent.putExtra(EXTRA_REPLY, reply);

// Set the activity's result to RESULT_OK


setResult(RESULT_OK, replyIntent);

// Finish the current activity


finish();
96
3.Implémenter onActivityResult()
public void onActivityResult(int requestCode,
int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == TEXT_REQUEST) { // Identify activity
if (resultCode == RESULT_OK) { // Activity succeeded
String reply = data.getStringExtra(SecondActivity.EXTRA_REPLY);
// … do something with the data
}}}

97
Navigation

98
Pile d’activités (Activity stack)
● Lorsqu'une nouvelle activité est démarrée, l'activité précédente est
arrêtée et poussée sur la pile d'activités
● Last-in-first-out-stack — lorsque l'activité en cours se termine ou
que l'utilisateur appuie sur le bouton Retour , la dernière
activité est retirée de la pile et l'activité précédente reprend

99
Pile d’activités (Activity Stack)
Après avoir consulté le
panier, l'utilisateur décide
d'ajouter plus d'articles,
puis passe la commande.

OrderActivity
Place order
CartActivity CartActivity
View shopping cart View shopping cart
FoodListActivity FoodListActivity FoodListActivity
Choose food items Choose food items Choose food items
MainActivity MainActivity MainActivity MainActivity
What do you want to do? What do you want to do? What do you want to do? What do you want to do?

100
Deux formes de navigation
Navigation temporelle ou arrière
● fourni par le bouton retour de l'appareil
● Contrôlée par le système Android et la pile d’activités.

Navigation ancestrale ou hiérarchique


● fourni par la barre d'action (Action Bar) de l'application
● Contrôlée en définissant les relations parent-enfant entre les
activités dans le manifeste Android
101
Cycle de vie
d’une activité

102
Qu’est-ce qu’un cycle de vie de l'activité?

● L'ensemble d'états qu'une activité peut avoir, depuis sa


création jusqu'à sa destruction

Plus formellement:
● Un graphique orienté de tous les états dans lesquels
une activité peut se trouver, et les callbacks associés au
passage de chaque état au suivant

103
Qu’est-ce qu’un cycle de vie de l'activité?

104
États d'activité et visibilité de l'application
● Created (pas encore visible)
● Started (visible)
● Resume (visible)
● Paused(partiellement invisible)
● Stopped (cachée)
● Destroyed (supprimée de la mémoire)
Les modifications d'état sont déclenchées par l'action de l'utilisateur,
les modifications de configuration telles que la rotation du
périphérique ou l'action du système

105
Callbacks
onCreate(Bundle savedInstanceState)—initialisation statique
onStart()—Lorsque l’activité (écran) commence à devenir visible
onRestart()—appelé si l'activité a été arrêtée (appelle onStart ())
onResume()—commencer à interagir avec l'utilisateur
onPause()—sur le point de reprendre l'activité précedente
onStop()—n'est plus visible, mais toutes les informations d'état sont conservées
onDestroy()—dernier appel avant que le système Android détruit l'activité

106
Graphique des états d'activité et des callbacks

107
Implémenter et redéfinir les callbacks
● Seule onCreate() est obligatoire.
● Redéfinir les autres callbacks pour modifier le comportement
par défaut

108
Etat de
l'instance
d'activité

109
Quand est-ce que la configuration change?
Les modifications de configuration invalident la mise en page
actuelle ou d'autres ressources de votre activité lorsque l'utilisateur :
● Faire pivoter l'appareil
● Choisir une langue du système différente, donc les changements
affectent les paramètres régionaux
● Entrer en mode multi-fenêtres(Android 7)

110
Que se passe-t-il lors du changement de configuration?

Lorsque la configuration change, Android:

1. Ferme l’activité en appelant : 2. Relance l’activité en appelant:

● onPause() ● onCreate()
● onStop() ● onStart()
● onDestroy() ● onResume()

111
Etat de l'instance d'activité
● Les informations d'état sont créées pendant l'exécution de
l'activité, telles qu'un compteur, un texte utilisateur, une
progression de l'animation
● L'état est perdu lorsque l'appareil est pivoté, la langue
change, le bouton arrière est enfoncé ou le système
efface la mémoire

112
Etat de l'instance d'activité
● Le système enregistre seulement :
○ Etat des vues avec ID unique (android: id) tel que le texte
saisi dans EditText
○ Intent ayant démarré l'activité et les données dans ses extras

● Vous êtes responsable de la sauvegarde des autres données


d'activité et de progression de l'utilisateur

113
Sauvegarder l’état de l’instance

Implémenter onSaveInstanceState() dans votre activité

● Appelée par Android runtime lorsque l’activité risque d’être


détruite.
● enregistre les données uniquement pour cette instance de
l'activité pendant la session en cours

114
onSaveInstanceState(Bundle outState)
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// Add information for saving HelloToast counter
// to the to the outState bundle
outState.putString("count",
String.valueOf(mShowCount.getText()));
}

115
Restorer l’état de l’instance
Deux solutions possibles :
● Dans onCreate(Bundle mySavedState)
Préférée, pour garantir que votre interface utilisateur, y compris
tout état enregistré, est de nouveau opérationnelle le plus
rapidement possible
● Implémenter le callback (appelé après onStart())
onRestoreInstanceState(Bundle mySavedState)

116
Restorer dans onCreate()
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mShowCount = (TextView) findViewById(R.id.show_count);

if (savedInstanceState != null) {
String count = savedInstanceState.getString("count");
if (mShowCount != null)
mShowCount.setText(count);
}
}
117
onRestoreInstanceState(Bundle state)

@Override
public void onRestoreInstanceState (Bundle mySavedState) {
super.onRestoreInstanceState(mySavedState);

if (mySavedState != null) {
String count = mySavedState.getString("count");
if (count != null)
mShowCount.setText(count);
}
}

118
Etat de l'instance et redémarrage de l'application

Lorsque vous arrêtez et redémarrez une nouvelle session


d'application, les états d'instance d'activité sont perdus et vos
activités retrouvent leur apparence par défaut
Si vous devez enregistrer des données utilisateur entre des
sessions d'applications, utilisez des préférences partagées
ou une base de données.

119
Recycler View

120
Qu’est ce qu’un Recycler View?
Conteneur défilable pour les grands ensembles de
données

Efficace
utilise et réutilise un nombre limité de vues
Mises à jour changeant rapidement les données

121
Composants
d’un
RecyclerView

122
Components de tous les composants
Présentation
● Données (Data)
● RecyclerView liste déroulante pour les éléments de la liste
● Layout pour un seul élément—fichier XML
● Layout manager gère l'organisation des composants de l'interface utilisateur dans une
vue—Recyclerview.LayoutManager
● Adapter connecte les données au RecyclerView—RecyclerView.Adapter
● View holder a des informations d'affichage pour afficher un élément—
RecyclerView.ViewHolder

123
Components
Comment les composants s'emboîtent

124
Implémenter un
RecyclerView

125
Implementation
Résumé des étapes
1.Ajoutez la dépendance RecyclerView au fichier app / build.gradle
2.Ajouter RecyclerView au layout
3.Créer une mise en page XML pour un élément
4.Étendre RecyclerView.Adapter
5.Étendre RecyclerView.ViewHolder
6.Dans onCreate de l’activité, créer un RecyclerView avec un
adapter et layout manager
126
app/build.gradle
Ajoutez la dépendance à app/build.gradle

dependencies {
...
compile 'com.android.support:recyclerview-v7:24.1.1'
...
}

127
Activity RecyclerView
Ajouter layout au layout XML

<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>

128
Item layout
Créer un layout pour 1 élément de la liste
<LinearLayout …>
<TextView
android:id="@+id/word"
style="@style/word_title" />
</LinearLayout>

129
Adapter: Create
Implémenter l’adapter
public class WordListAdapter
extends RecyclerView.Adapter<WordListAdapter.WordViewHolder> {

public WordListAdapter(Context context,


LinkedList<String> wordList) {
mInflater = LayoutInflater.from(context);
this.mWordList = wordList;
}
}
130
Adapter: onCreateViewHolder()
L’Adapter a 3 méthodes obligatoires

● onCreateViewHolder()
● inBindViewHolder()
● getItemCount()

131
Adapter: onCreateViewHolder()
onCreateViewHolder()
@Override
public WordViewHolder onCreateViewHolder(
ViewGroup parent, int viewType) {
// Create view from layout
View mItemView = mInflater.inflate(
R.layout.wordlist_item, parent, false);
return new WordViewHolder(mItemView, this);
}
132
Adapter: onBindViewHolder()
onBindViewHolder()
@Override
public void onBindViewHolder(
WordViewHolder holder, int position) {
// Retrieve the data for that position
String mCurrent = mWordList.get(position);
// Add the data to the view
holder.wordItemView.setText(mCurrent);
}

133
Adapter: getItemCount()
getItemCount()

@Override
public int getItemCount() {
// Return the number of data items to display
return mWordList.size();
}

134
Créer le view
Adapter: holder dans Class
ViewHolder la classe de l’adapter

class WordViewHolder extends RecyclerView.ViewHolder {}

Si vous voulez gérer les clics de souris:

class WordViewHolder extends RecyclerView.ViewHolder


implements View.OnClickListener {}

135
ViewHolder: Constructor
Constructeur du View holder
public WordViewHolder(View itemView, WordListAdapter adapter) {
super(itemView);
// Get the layout
wordItemView = (TextView) itemView.findViewById(R.id.word);
// Associate with this adapter
this.mAdapter = adapter;
// Add click listener, if desired
itemView.setOnClickListener(this);
}
// Implement onClick() if desired

136
Créer
Createle RecyclerView
RecyclerView dans onCreate() de l’activité

mRecyclerView = (RecyclerView)
findViewById(R.id.recyclerview);
mAdapter = new WordListAdapter(this, mWordList);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setLayoutManager(new
LinearLayoutManager(this));

137
AsyncTask
&
AsyncTaskLoader

138
Threads

139
Le thread principal
● Chemin d'exécution indépendant dans un programme en cours
● Le code est exécuté ligne par ligne
● L’application fonctionne sur le thread Java appelé "principal" ou
"thread UI"
● Dessine l'interface utilisateur sur l'écran
● Répond aux actions de l'utilisateur en gérant les événements de
l'interface utilisateur

140
Le thread principal doit être rapide
● Le Hardware met à jour l’écran toutes les 16 millisecondes
● UI thread a 16 ms pour faire tout son travail
● S’il prend trop de temps, l'application se bloque

WAIT

141
What is a qu'une
Qu'est-ce long running
tâche de
task?
longue durée?
● Opérations de réseau
● Calculs longs
● Chargement / téléchargement de fichiers
● Traitement des images
● Chargement des données

142
Background threads
Exécuter les tâches de longue durée dans un background thread

Main Thread (UI Thread)


Update UI

● AsyncTask
● Le Loader Framework
● Services
Worker Thread Do some work

143
AsyncTask

144
Qu’est-ce qu’un AsyncTask?
Utiliser AsyncTask pour implémenter des tâches de fond basiques.

Main Thread (UI Thread)


onPostExecute()

Worker Thread
doInBackground()

145
Méthodes d’un AsyncTask

Main Thread (UI Thread)


onPreExecute() onProgressUpdate() onPostExecute()

Worker Thread publishProgress()

doInBackground()

146
Créer un AsyncTask
1.Créer une classe qui hérite d’AsyncTask
2.Fournir le type de données envoyé à doInBackground()
3.Fournit le type de données des unités de progression pour
onProgressUpdate()
4.Fournir le type de données du résultat pour onPostExecute()

private class MyAsyncTask


extends AsyncTask<URL, Integer, Bitmap> {...}

147
Limitations
Limites d’unofAsyncTask
AsyncTask
● Lorsque la configuration de l'appareil change, l'activité est
détruite AsyncTask ne peut plus se connecter à l’activité
● Nouvel asyncTask créé pour chaque changement de
configuration
● Les vieux asyncTasks restent dans la mémoire
● L'application peut manquer de mémoire ou se bloquer

148
Quand utiliser AsyncTask
● Tâches courtes ou interruptibles
● Tâches qui n'ont pas besoin de rapporter à l'interface utilisateur
ou à l'utilisateur
● Tâches moins prioritaires qui peuvent être laissées inachevées
● Utiliser AsyncTaskLoader sinon

149
Loaders

150
Qu’est-ce qu’un Loader?
● Fournit un chargement asynchrone des données
● Se reconnecte à l'activité après le changement de configuration
● Peut surveiller les changements dans la source de données et
fournir de nouvelles données
● Callbacks implémentés dans l’activité
● Plusieurs types de loaders disponibles
○ AsyncTaskLoader, CursorLoader

151
Pourquoi utiliser les loaders?

● Exécuter des tâches en dehors du UI thread


● Le LoaderManager gère les changements de configuration pour
vous
● Efficacement mis en œuvre par le framework
● Les utilisateurs n'ont pas besoin d'attendre le chargement des
données

152
Se connecter à Internet

153
Étapes pour se connecter à Internet
1. Ajouter les permissions dans le ficher Manifest d’Android
2. Vérifier la connexion réseau
3. Créer un thread de travail
4. Implémenter une tâche en background
a. Créer l’URI
b. Ouvrir une connexion HTTP
c. Se connecter et récupérer les données
5. Traiter les résultats
a. Parser les résultats

154
Permissions

155
Permissions dansAndroidManifest
Internet
<uses-permission android:name="android.permission.INTERNET"/>

Vérifier la connexion au réseau


<uses-permission
android:name="android.permission.ACCESS_NETWORK_STATE"/>

156
Gérer la
connexion au
réseau

157
Récupérer les informations sur le réseau
ConnectivityManager
Répond aux questions sur l'état de la connectivité réseau
Notifie les applications en cas de changement
NetworkInfo
Décrit l'état d'une interface réseau d'un type donné
Mobile ou Wi-Fi

158
Vérifier si la connexion est disponible
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);

NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();

if (networkInfo != null && networkInfo.isConnected()) {


// Create background thread to connect and get data
new DownloadWebpageTask().execute(stringUrl);
} else {
textView.setText("No network connection available.");
}

159
Vérifier pour WiFi & Mobile
NetworkInfo networkInfo =
connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
boolean isWifiConn = networkInfo.isConnected();

networkInfo =
connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
boolean isMobileConn = networkInfo.isConnected();

160
Thread de
travail (Worker
Thread)

161
Utiliser un Worker Thread

● AsyncTask—Tâche très courte ou aucun résultat renvoyé à l’IU


● AsyncTaskLoader—pour les tâches plus longues, les résultats
sont retournés à l’UI
● Background Service—chapitre suivant

162
Travail en background

Dans le background task (par exemple dans doInBackground())


1.Créer l’URI
2.Ouvrir une connexion HTTP
3.Récupérer les données

163
Créer l’URI

164
URI = Uniform Resource Identifier

Chaîne qui nomme ou localise une ressource particulière


● file://
● http:// and https://
● content://

165
Une URL simple pour Google Books API
https://www.googleapis.com/books/v1/volumes?
q=pride+prejudice&maxResults=5&printType=books
Constantes pour les Paramèters
final String BASE_URL =
"https://www.googleapis.com/books/v1/volumes?";
final String QUERY_PARAM = "q";
final String MAX_RESULTS = "maxResults";
final String PRINT_TYPE = "printType";

166
Construire un URI pour la requête

Uri builtURI = Uri.parse(BASE_URL).buildUpon()


.appendQueryParameter(QUERY_PARAM, "pride+prejudice")
.appendQueryParameter(MAX_RESULTS, "10")
.appendQueryParameter(PRINT_TYPE, "books")
.build();
URL requestURL = new URL(builtURI.toString());

167
Connexion au
client HTTP

168
How to
Faire une
connect
connexion
to theà Internet?
partir de zéro

Utiliser HttpURLConnection
Doit être fait sur un thread séparé
Requiert des flux d'entrée et des blocs try/catch

169
Créer une HttpURLConnection

HttpURLConnection conn =
(HttpURLConnection) requestURL.openConnection();

170
Configurer la connexion

conn.setReadTimeout(10000 /* milliseconds */);


conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);

171
Se connecter et récupérer la résponse
conn.connect();
int response = conn.getResponseCode();

InputStream is = conn.getInputStream();
String contentAsString = convertIsToString(is, len);
return contentAsString;

172
Fermer la connexion et le flux

} finally {
conn.disconnect();
if (is != null) {
is.close();
}
}

173
Convertir la
résponse en
String

174
Convertir un input stream en string
public String convertIsToString(InputStream stream, int len)
throws IOException, UnsupportedEncodingException {

Reader reader = null;


reader = new InputStreamReader(stream, "UTF-8");
char[] buffer = new char[len];
reader.read(buffer);
return new String(buffer);
}
175
BufferedReader est plus efficace
StringBuilder builder = new StringBuilder();
BufferedReader reader =
new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line + "\n");
}
if (builder.length() == 0) {
return null;
}
resultString = builder.toString();

176
Les
bibliothèques de
connexion à un
client HTTP

177
Faire
How une connexion
to connect to àthe
l’aide d’une bibliothèque
Internet?

Utiliser une bibliothèque tierce comme OkHttp ou Volley


Peut être appelé sur le fil principal
Beaucoup moins de code

178
How to connect to the Internet?
Volley
RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://www.google.com";

StringRequest stringRequest = new StringRequest(Request.Method.GET, url,


new Response.Listener<String>() {
@Override
public void onResponse(String response) {
// Do something with response
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {}
});
queue.add(stringRequest);

179
OkHttp
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt").build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onResponse(Call call, final Response response)
throws IOException {
try {
String responseData = response.body().string();
JSONObject json = new JSONObject(responseData);
final String owner = json.getString("name");
} catch (JSONException e) {}
}
});

180
Parser les
résultats

181
Parser les résultats
● Implémenter une méthode pour recevoir et traiter les résultats
( onPostExecute())
● La réponse est souvent en JSON ou XML
Parser les résultats en utilisant des classes utilitaires
● JSONObject, JSONArray
● XMLPullParser—parse XML

182
Les bases JSON

{
"population":1,252,000,000,
"country":"India",
"cities":["New Delhi","Mumbai","Kolkata","Chennai"]
}

183
Les bases de JSONObject

JSONObject jsonObject = new JSONObject(response);


String nameOfCountry = (String) jsonObject.get("country");
long population = (Long) jsonObject.get("population");
JSONArray listOfCities = (JSONArray) jsonObject.get("cities");
Iterator<String> iterator = listOfCities.iterator();
while (iterator.hasNext()) {
// do something
}

184
Un autre exemple avec JSON
{"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}

185
Traitement de l’exemple précédent
Répérer la valeur de "onclick" du 3éme élément du tableau
"menuitem”
JSONObject data = new JSONObject(responseString);
JSONArray menuItemArray =
data.getJSONArray("menuitem");
JSONObject thirdItem =
menuItemArray.getJSONObject(2);
String onClick = thirdItem.getString("onclick");

186
Broadcast Receivers

187
Broadcast
Intents

188
Broadcast vs. Activity
Implicit Intents
Utiliser des intents implicites pour envoyer des broadcasts ou lancer
des activités
Envoyer des broadcasts Lancer des activités

- Utiliser sendBroadcast() - Utiliser startActivity()


- Peut être reçu par n'importe quelle - Trouver une seule activité pour
application enregistrée pour l'intent accomplir une tâche
- Utilisé pour notifier toutes les - Accomplir une action spécifique
applications d'un événement

189
Broadcast
Receivers

190
Qu’est-ce qu’un broadcast receiver?
● Écoute les intents envoyés par sendBroadcast()
○ En background
● Les Intents peuvent être envoyés
○ Par le système, lorsqu'un événement, susceptible de modifier le
comportement d'une application, se produit
○ Par une autre application, y compris la vôtre

191
Broadcast receiver répond toujours

● Répond même lorsque votre application est fermée


● Indépendant de toute activité
● Lorsqu'un broadcast intent est reçu et transmis à onReceive (),
elle a 5 secondes pour s’exécuter, puis le récepteur (receiver) est
détruit

192
System broadcasts

Envoyé automatiquement lorsque certains événements se


produisent
Une fois le démarrage du système terminé
android.intent.action.BOOT_COMPLETED

Lorsque l'état du wifi change


android.net.wifi.WIFI_STATE_CHANGED

193
Custom broadcasts

Livrer tout intent personnalisée en tant que broadcast


sendBroadcast() méthode—asynchrone
sendOrderedBroadcast()—synchrone
android.example.com.CUSTOM_ACTION

194
sendBroadcast()

Tous les récepteurs du broadcast sont exécutés dans un ordre


indéfini
Peuvent être en même temps
Efficace
Utiliser pour envoyer des custom broadcasts
195
sendOrderedBroadcast()
Livré à un récepteur à la fois
Le récepteur peut propager le résultat au destinataire suivant
ou annuler la diffusion
Ordre contrôlé par android:priority du filtre d'intent correspondant
Les destinataires ayant la même priorité s'exécutent dans l'ordre arbitraire

196
Implémenter un
Broadcast
Receivers

197
Étapes pour la création d’un broadcast
receiver
1.Créer une classe qui hérite de BroadcastReceiver
2.Implémenter la méthode onReceive()
3.S’enregistrer pour recevoir le broadcast
○ Statiquement, dans AndroidManifest
○ Dynamiquement, avec registerReceiver()

198
File > New > Other > BroadcastReceiver
public class CustomReceiver extends BroadcastReceiver {
public CustomReceiver() {
}

@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver
// is receiving an Intent broadcast.
throw new UnsupportedOperationException("Not yet implemented");
}
}

199
S’enregistrer dans Android Manifest
<receiver> element inside <application>
<intent-filter> registers receiver for specific intents

<receiver
android:name=".CustomReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>

200
S’enregistrer dynamiquement

In onCreate() or onResume()
Use registerReceiver() and pass in the intent filter
Must unregister in onDestroy() or onPause()

registerReceiver(mReceiver, mIntentFilter)
unregisterReceiver(mReceiver)

201
Intents disponibles
ACTION_TIME_TICK ACTION_PACKAGE_DATA_CLEARED

ACTION_TIME_CHANGED ACTION_PACKAGES_SUSPENDED

ACTION_TIMEZONE_CHANGED ACTION_PACKAGES_UNSUSPENDED

ACTION_BOOT_COMPLETED ACTION_UID_REMOVED

ACTION_PACKAGE_ADDED ACTION_BATTERY_CHANGED

ACTION_PACKAGE_CHANGED ACTION_POWER_CONNECTED

ACTION_PACKAGE_REMOVED ACTION_POWER_DISCONNECTED

ACTION_PACKAGE_RESTARTED ACTION_SHUTDOWN

202
Implémenter onReceive()
@Override
public void onReceive(Context context, Intent intent) {
String intentAction = intent.getAction();
switch (intentAction){
case Intent.ACTION_POWER_CONNECTED:
break;
case Intent.ACTION_POWER_DISCONNECTED:
break;
}
}

203
Services

204
Qu’est-ce qu’un service?

Un Service est un composant d'application qui peut effectuer des


opérations de longue durée en arrière-plan et ne fournit pas
d'interface utilisateur

205
A quoi servent les services?

● Transactions de réseau
● Jouer de la musique
● Manipuler des fichiers
● Interagir avec un fournisseur de contenu (content provider)

206
Characteristiques d’un service
● Lancé avec un intent
● Peut rester en cours d'exécution lorsque l'utilisateur change d'application
● Cycle de vie - que vous devez gérer
● D'autres applications peuvent l’utiliser – Il faut gérer les permissions
d’accès
● Fonctionne dans le thread principal de son processus d'hébergement

207
Formes de services: started

Démarré avec startService()


Fonctionne indéfiniment jusqu'à ce qu'il
s'arrête
Habituellement ne met pas à jour
l'interface utilisateur

208
Formes de services: bound
Offre une interface client-serveur qui permet aux
composants d'interagir avec le service
Les clients envoient des demandes et obtiennent
des résultats
Lancé avec bindService ()
Se termine lorsque tous les clients sont détachés

209
Services et threads

Bien que les services soient séparés de l'interface utilisateur, ils


s'exécutent toujours sur le thread principal par défaut (sauf
IntentService)

Décharger le travail gourmand en ressources processeur en un


thread distinct au sein du service

210
Mette à jour l’application

Si le service ne peut pas accéder à l'interface utilisateur, comment


mettez-vous à jour l'application pour afficher les résultats?

Utilisez un broadcast receiver!

211
Services de premier plan (Foreground)

Fonctionne en arrière-plan, mais nécessite que l'utilisateur soit


conscient qu'il existe, par exemple - lecteur de musique utilisant un
service de musique
• Priorité plus élevée que les services d'arrière-plan, car
l'utilisateur remarquera son absence, ce qui le rend peu
susceptible d'être détruit par le système
• Doit fournir une notification que l'utilisateur ne peut pas ignorer
pendant l'exécution du service
212
Créer un service
● <service android:name=".ExampleService" />
● Gérer les permissions
● Créer une classe qui hérite de IntentService ou Service
● Implémenter les méthodes du cycle de vie
● Lancer le service à partir d’une activité
● S’assurer que le service peut être arrêté

213
Arrêter un service
● Un started service doit gérer son propre cycle de vie
● Sil n’est pas arrêté, il continue à fonctionner et à consommer des
ressources.
● Un service doit s’arrêter lui même en appelant stopSelf()
● Un autre composant peut l’arrêter en appelant stopService()
● Bound service est détruit lorsque tous les clients se détachent
● IntentService est détruit après le retour de onHandleIntent()

214
8.1 Notifications

215
Qu’est-ce qu’une notification?

Message affiché à l'utilisateur en dehors de l'interface utilisateur


habituelle de l'application

■ Petite icône
■ Titre
■ Description textuelle

216
Comment sont utilisées les notifications?
● Android émet une notification qui apparaît sous
la forme d'une icône
● Pour voir les détails, l'utilisateur ouvre le tiroir
de notification (notification drawer)
● L'utilisateur peut voir les notifications à tout
moment dans le tiroir de notification

217
Créer des
Notifications

218
Building
Deux classes
a Notification

NotificationCompat.Builder
Spécifie l’IU et les actions
NotificationCompat.Builder.build() crée la Notification
NotificationManager / NotificationManagerCompat
NotificationManager.notify() émet la notification

219
Buildingles
Définir a variables
Notification

private NotificationCompat.Builder mNotifyBuilder;

private NotificationManager mNotifyManager;

private static final int NOTIFICATION_ID = 0

220
Building a le
Instantier Notification
NotificationManager

Dans onCreate() de l’activité

mNotifyManager = (NotificationManager)

getSystemService(NOTIFICATION_SERVICE);

221
Building
Créer et envoyer
a Notification
la notification

mNotifyBuilder = new NotificationCompat.Builder(this)


.setContentTitle("You've been notified!")
.setContentText("This is your notification text.")
.setSmallIcon(R.drawable.ic_android_black_24dp);

Notification myNotification = mNotifyBuilder.build();

mNotifyManager.notify(NOTIFICATION_ID, myNotification);

222
Persistance de données

223
Les options de
persitance de
données

224
Persistance des données

● Shared Preferences—Données primitives privées dans des paires clé-valeur


● Internal Storage—Données privées sur la mémoire de l'appareil
● External Storage—Données publiques sur l'appareil ou le stockage externe
● SQLite Databases—Données structurées dans une base de données privée
● Content Providers—Stocker en privé et rendre public

225
Stocker des données au-delà d'Android

● Network Connection—Sur le web avec votre propre serveur


● Cloud Backup—Sauvegarder l'application et les données
utilisateur dans le cloud
● Firebase Realtime Database—Stocker et synchroniser des
données avec la base de données cloud NoSQL sur des clients
en temps réel

226
Fichiers

227
Le système de fichiers Android

● External storage – Dossiers publics


● Internal storage – Dossiers privés pour l’application seulement

Les applications peuvent parcourir la structure du répertoire


Structure et opérations similaires à Linux et java.io

228
Internal storage
● Toujours disponible
● Utilise le système de fichiers de l'appareil
● Seule votre application peut accéder aux fichiers, à moins qu'elle
ne soit explicitement définie pour être lisible ou inscriptible
● Lors de la désinstallation de l'application, le système supprime
tous les fichiers de l'application du stockage interne

229
External storage

● Pas toujours disponible, peut être retiré


● Utilise le système de fichiers de l'appareil ou un stockage
physique externe comme une carte SD
● Lecteur lisible par tout le monde, de sorte que toute application
peut lire
● Lors de la désinstallation, le système ne supprime pas les fichiers
privés de l'application

230
Quand utiliser internal/external storage
Internal est meilleur quand
● vous voulez être sûr que ni l'utilisateur ni d'autres applications
peuvent accéder à vos fichiers
External est meilleur pour les fichiers
● qui ne nécessitent pas de restrictions d'accès
● et que vous voulez partager avec d'autres applications
● que l'utilisateur peut accéder à partir de son ordinateur

231
Le stockage partagé

● Enregistrer les nouveaux fichiers que l'utilisateur acquiert via


votre application vers un répertoire public où d'autres
applications peuvent y accéder et que l'utilisateur peut
facilement les copier à partir de l'appareil
● Enregistrer les fichiers externes dans les répertoires publics

232
Shared
Preferences
& SQLite
Database

233
SQLite Database

● Idéal pour les données répétées ou structurées, telles que les


contacts
● Android fournit une base de données semblable à SQL
● Aucune installation nécessaire

234
Shared Preferences

● Lecture et écriture de petites quantités de données primitives en


tant que paires clé / valeur dans un fichier du stockage de
l'appareil

235
Autres options
de stockage

236
Utiliser Firebase
Stocker et synchroniser des données avec
la base de données cloud Firebase

Les données sont synchronisées sur tous


les clients et restent disponibles lorsque
votre application est hors connexion
firebase.google.com/docs/database/

237
Firebase Realtime Database

● Les applications connectées partagent des


données
● Hébergée dans le cloud
● Les données sont stockées en tant que
JSON
● Les données sont synchronisées en temps
réel avec chaque client connecté

238
Connexion réseau

● Vous pouvez utiliser le réseau (lorsqu'il est disponible) pour


stocker et récupérer des données sur vos propres services Web.

● Utiliser des classes dans les packages suivants


○ java.net.*
○ android.net.*

239
Les capteurs

240
Android sensor framework

● Déterminer quels capteurs sont disponibles sur l'appareil


● Déterminer les capacités d'un capteur individuel :
- Portée maximale, fabricant, puissance requise, résolution

● Acquérir des données de capteur brutes


- Définir également le débit minimum pour l'acquisition des données du capteur

● Enregistrer et désinscrire des écouteurs d'événements de


capteurs

241
Les principales classes du framework (1)

SensorManager
● Accéder aux capteurs et les écouter
● Enregistrer et désinscrire des écouteurs d'événements des capteurs
● Acquérir des informations d'orientation
● Fournir des constantes pour la précision, les taux d'acquisition de
données et l'étalonnage

242
Les principales classes du framework (2)

● Sensor: Déterminer les capacités spécifiques du capteur


● SensorEvent: Informations sur l'événement, y compris les
données de capteur brutes
● SensorEventListener: Reçoit des notifications sur les
événements de capteur
○ Quand le capteur a de nouvelles données
○ Quand la précision du capteur change

243
Types de classes de capteurs et leur utilisation
TYPE_ACCELEROMETER Détection de mouvement (shake, tilt, etc.)

TYPE_AMBIENT_TEMPERATURE Surveillance de la température de l'air


TYPE_GRAVITY Détection de mouvement (shake, tilt, etc.)
TYPE_GYROSCOPE Détection de la rotation (spin, turn, etc.)
TYPE_LIGHT Contrôle de la luminosité de l'écran
TYPE_LINEAR_ACCELERATION Contrôle de l'accélération sur un seul axe
TYPE_MAGNETIC_FIELD Créer une boussole

244
Types de classes de capteurs et leur utilisation
TYPE_ORIENTATION Détermination de la position de l'appareil

TYPE_PRESSURE Surveillance des changements de pression


atmosphérique
TYPE_PROXIMITY Détermination de la position du téléphone
pendant un appel
TYPE_RELATIVE_HUMIDITY Surveillance de l'humidité ambiante (relative
et absolue) et du point de rosée
TYPE_ROTATION_VECTOR Détecter le mouvement et la rotation
TYPE_TEMPERATURE Surveillance des températures
245
Découverte de
capteurs et de
capacités

246
Identifier les capteurs

Créer une instance de SensorManager


● Appeler getSystemService()
● Passer SENSOR_SERVICE en argument

mSensorManager = (SensorManager)
getSystemService(Context.SENSOR_SERVICE);

247
Obtenir la liste des capteurs

Utiliser getSensorList()
● Pour récupérer la liste de tous les capteurs, utiliser la constante
TYPE_ALL
List<Sensor> deviceSensors =
mSensorManager.getSensorList(Sensor.TYPE_ALL);

● Pour obtenir les capteurs d’un type spécifique, Utiliser :


TYPE_PROXIMITY, TYPE_GYROSCOPE, TYPE_GRAVITY …

248
Obtenir un objet capteur

● Utiliser getDefaultSensor() et passer en argument le type


de capteur souhaité
● Si plusieurs capteurs pour un type donné, le système en désigne
un comme capteur par défaut
● Si aucun capteur de ce type n'existe, la méthode retourne null

249
Example: Get magnetometer object
private SensorManager mSensorManager;
// ...
mSensorManager = (SensorManager)
getSystemService(Context.SENSOR_SERVICE);
if (mSensorManager.getDefaultSensor
(Sensor.TYPE_MAGNETIC_FIELD) != null){
// Success! There's a magnetometer.
} else {
// Failure! No magnetometer.
}

250
Identifier les caractéristiques du capteur
Les méthodes de la classe Sensor
● getResolution() pour la résolution du capteur
● getMaximumRange() pour une plage de mesure maximale
● getPower() pour les exigences de puissance du capteur
● getVendor() et getVersion() optimiser pour différents
capteurs ou différentes versions de capteur

251
Options de gestion des configurations
● Détecter des capteurs lors de l'exécution pour désactiver les
fonctionnalités de l'application, le cas échéant
● Google Play filtre les configurations de capteurs spécifiques
○ Filtrer les applications d'appareils n'ayant pas de configuration de
capteur
○ <uses-feature> dans Android manifest
<uses-feature
android:name="android.hardware.sensor.accelerometer"
android:required="true" />

252
Surveiller les événements du capteur
1. Implémenter l’interface SensorEventListener avec les
callbacks
○ onSensorChanged(SensorEvent event)
○ onAccuracyChanged(Sensor sensor, int accuracy)
2. Enregistrer l'écouteur d'événements de capteur pour un capteur
spécifique
3. Obtenir les types et les valeurs de capteurs de l'objet SensorEvent
4. Mettre à jour l'application en conséquence
253
Les arguments de onAccuracyChanged()
● onAccuracyChanged() appelé lorsque la précision change
● L'objet Sensor identifie le capteur qui a changé
● Les canstantes de Accuracy :
○ SENSOR_STATUS_ACCURACY_LOW
○ SENSOR_STATUS_ACCURACY_MEDIUM
○ SENSOR_STATUS_ACCURACY_HIGH
○ SENSOR_STATUS_UNRELIABLE
○ SENSOR_STATUS_NO_CONTACT

254
SensorEventListener et callback
public class SensorActivity extends Activity
implements SensorEventListener {
// ...
@Override
public final void onAccuracyChanged
(Sensor sensor, int accuracy) {
// Do something if sensor accuracy changes.
}
// ...
}

255
Exemple avec onSensorChanged()

onSensorChanged() appelé lorsque le capteur signale de


nouvelles données en transmettant un événement SensorEvent

@Override
public void onSensorChanged(SensorEvent sensorEvent) {
// Do something here if sensor data changes.
}

256
Enregistrer un écouteur pour un événement de capteur

● L'application doit enregistrer l’écouteur (listener) pour


l'événement du capteur
● S'inscrire dans la méthode onStart() de l’activité et se
désinscrire dans onStop()
○ Ne pas s’inscrire dans onCreate(), onResume(), ou onPause()
○ S’assure que les capteurs utilisent l'énergie uniquement lorsque
l'application est au premier plan
○ Les capteurs continuent à fonctionner même si l'application est en mode
multi-fenêtre
257
Enregister un listener dans onStart()

@Override
protected void onStart() {
super.onStart();
if (mIsLightSensorPresent) {
mSensorManager.registerListener(this, mSensorLight,
SensorManager.SENSOR_DELAY_UI);
}
}

258
Désinscrire un listener dans onStop()

@Override
protected void onStop() {
super.onStop();
mSensorManager.unregisterListener(this);
}

259
Traiter les changements de données du capteur

● Override onSensorChanged()
○ Passer en argument l’objet SensorEvent avec les infos de l’event

● Objet SensorEvent transmis :


○ sensor: Capteur ayant généré l'événement (objet Sensor)
○ values: Données générées par le capteur, sous forme de tableau de
valeurs flottantes. Différents capteurs fournissent différentes quantités
et types de données.

260
Example: Changes to light sensor
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
int sensorType = sensorEvent.sensor.getType();
float currentValue = sensorEvent.values[0];
if (sensorType == Sensor.TYPE_LIGHT) {
// Get light sensor string and fill data placeholder.
String str_current = getResources().getString(
R.string.label_light, currentValue);
mTextSensorLight.setText(str_current);
}
}

261
Pour aller plus loin

● Cours officiel en anglais sur lequel est basé ce support de


formation : Android Developer Fundamentals
https://developers.google.com/training/courses/android-
fundamentals
● Support de formation Android avancé : Advanced Android
Development
https://developers.google.com/training/courses/android-advanced

262