61
1 Android (Avec Android Studio) J. ROMAGNY I. BASES DE JAVA......................................................................................................................................... 3 1. VARIABLES ..................................................................................................................................................... 3 2. CONDITIONS .................................................................................................................................................. 3 3. BOUCLES ....................................................................................................................................................... 4 4. ENUM........................................................................................................................................................... 4 5. COLLECTIONS ................................................................................................................................................. 5 a. Tableaux ................................................................................................................................................ 5 b. Liste........................................................................................................................................................ 5 c. Map ....................................................................................................................................................... 5 6. METHODES ET FONCTIONS ................................................................................................................................ 5 7. OBJETS ......................................................................................................................................................... 6 II. ANDROID ................................................................................................................................................. 8 1. INSTALLATION (WINDOWS)............................................................................................................................... 8 a. Installation du JDK ................................................................................................................................. 8 b. Android Studio ....................................................................................................................................... 8 c. Problèmes et astuces ........................................................................................................................... 10 d. AVD Manager ...................................................................................................................................... 11 e. Divers ................................................................................................................................................... 12 2.CREER UN NOUVEAU PROJET ANDROID.................................................................................................................... 12 3. ACTIVITES (« ACTIVITY ») ............................................................................................................................... 15 a. Créer une activité ................................................................................................................................. 17 b. Passer des données (Extra) .................................................................................................................. 19 c. Activité avec retour de résultat (« startActivityForResult ») ................................................................ 19 d. Menu.................................................................................................................................................... 20 Création du menu ...................................................................................................................................................... 20 Intercepter le clic sur un élément du menu ............................................................................................................... 20 Créer un eventHandler pour un élément de menu .................................................................................................... 21 Créer un élément de menu par code ......................................................................................................................... 21 Avoir le bouton de « retour » .................................................................................................................................... 21 Menu avec images ..................................................................................................................................................... 22 Menu contextuel........................................................................................................................................................ 22 4. LAYOUTS (« VIEWGROUP ») ................................................................................................................................ 23 a. Designer .................................................................................................................................................... 23 b. Propriétés « partagées » .......................................................................................................................... 24 Tailles ......................................................................................................................................................................... 24 Weight ....................................................................................................................................................................... 24 « wrap_content », « fill_parent » .............................................................................................................................. 24 Gravity et « layout_gravity »...................................................................................................................................... 25 c. LinearLayout ........................................................................................................................................ 26 d. RelativeLayout ..................................................................................................................................... 26 e. GridLayout ........................................................................................................................................... 27 f. TableLayout ......................................................................................................................................... 28 g. Include ................................................................................................................................................. 29 h. Custom View et composant ................................................................................................................. 30 Custom View .............................................................................................................................................................. 30 Custom composant (classe + layout) ......................................................................................................................... 31 Balise « merge » .................................................................................................................................................... 32

1 Android (Avec Android Studio) - romagny13.comromagny13.com/.../uploads/2015/05/android-avec-android-studio.pdf · 8 II. Android Documentation 1. Installation (Windows) a. Installation

Embed Size (px)

Citation preview

1

Android (Avec Android Studio) J. ROMAGNY

I. BASES DE JAVA......................................................................................................................................... 3

1. VARIABLES ..................................................................................................................................................... 3 2. CONDITIONS .................................................................................................................................................. 3 3. BOUCLES ....................................................................................................................................................... 4 4. ENUM ........................................................................................................................................................... 4 5. COLLECTIONS ................................................................................................................................................. 5

a. Tableaux ................................................................................................................................................ 5 b. Liste ........................................................................................................................................................ 5 c. Map ....................................................................................................................................................... 5

6. METHODES ET FONCTIONS ................................................................................................................................ 5 7. OBJETS ......................................................................................................................................................... 6

II. ANDROID ................................................................................................................................................. 8

1. INSTALLATION (WINDOWS) ............................................................................................................................... 8 a. Installation du JDK ................................................................................................................................. 8 b. Android Studio ....................................................................................................................................... 8 c. Problèmes et astuces ........................................................................................................................... 10 d. AVD Manager ...................................................................................................................................... 11 e. Divers ................................................................................................................................................... 12

2.CREER UN NOUVEAU PROJET ANDROID .................................................................................................................... 12 3. ACTIVITES (« ACTIVITY ») ............................................................................................................................... 15

a. Créer une activité ................................................................................................................................. 17 b. Passer des données (Extra) .................................................................................................................. 19 c. Activité avec retour de résultat (« startActivityForResult ») ................................................................ 19 d. Menu .................................................................................................................................................... 20

Création du menu ...................................................................................................................................................... 20 Intercepter le clic sur un élément du menu ............................................................................................................... 20 Créer un eventHandler pour un élément de menu .................................................................................................... 21 Créer un élément de menu par code ......................................................................................................................... 21 Avoir le bouton de « retour » .................................................................................................................................... 21 Menu avec images ..................................................................................................................................................... 22 Menu contextuel........................................................................................................................................................ 22

4. LAYOUTS (« VIEWGROUP ») ................................................................................................................................ 23 a. Designer .................................................................................................................................................... 23 b. Propriétés « partagées » .......................................................................................................................... 24

Tailles ......................................................................................................................................................................... 24 Weight ....................................................................................................................................................................... 24 « wrap_content », « fill_parent » .............................................................................................................................. 24 Gravity et « layout_gravity » ...................................................................................................................................... 25

c. LinearLayout ........................................................................................................................................ 26 d. RelativeLayout ..................................................................................................................................... 26 e. GridLayout ........................................................................................................................................... 27 f. TableLayout ......................................................................................................................................... 28 g. Include ................................................................................................................................................. 29 h. Custom View et composant ................................................................................................................. 30

Custom View .............................................................................................................................................................. 30 Custom composant (classe + layout) ......................................................................................................................... 31

Balise « merge » .................................................................................................................................................... 32

2

i. Fragments ............................................................................................................................................ 33 5. WIDGETS .................................................................................................................................................... 36

a. Accéder à un widget (findViewById) .................................................................................................... 36 b. Utilisation « ImageView » .................................................................................................................... 36

6. VIEW EVENTS ............................................................................................................................................... 37 7. « ARRAYADAPTER » ...................................................................................................................................... 38

a. avec ListActivity ................................................................................................................................... 38 b. Avec ActionBarActivity ......................................................................................................................... 39 c. Personnalisé ......................................................................................................................................... 40

8. CYCLE DE VIE D’ACTIVITE ................................................................................................................................. 42 Sauver/ restaurer les états de contrôles d’une activité ................................................................................ 42

9. RESSOURCES ................................................................................................................................................ 43 10. PREFERENCES PARTAGEES ........................................................................................................................... 45

« PreferenceActivity » ................................................................................................................................... 45 11. FICHIERS ................................................................................................................................................. 47

XML ............................................................................................................................................................... 47 JSON.............................................................................................................................................................. 48

12. SQLITE ................................................................................................................................................... 49 13. HTTP ..................................................................................................................................................... 51

a. AsyncTask ............................................................................................................................................ 51 b. Tester la connexion .............................................................................................................................. 52 c. Avec « HttpURLConnection » ............................................................................................................... 53 d. Parser une réponse au format JSON .................................................................................................... 54 e. POST + passage de paramètre au format JSON ................................................................................... 55 f. Libraires ............................................................................................................................................... 55

14. TOASTS ................................................................................................................................................... 56 15. NOTIFICATIONS ........................................................................................................................................ 56 16. SERVICE ET INTENTSERVICE ......................................................................................................................... 59

a. Service .................................................................................................................................................. 59 b. IntentService ........................................................................................................................................ 60

17. « BROADCAST RECEIVER » ......................................................................................................................... 61 « Dynamic Broadcast Receiver» ................................................................................................................... 61

3

I. Bases de Java IDE : Intellij IDEA , Eclipse

1. Variables Typés primitifs : int, float, double, char, boolean, string (+ byte, short, long)

int myInt =10;

float myFloat = 9.99f;

double myDouble = 9.99;

boolean myBool = true;

String myString = "Bonjour!";

Afficher la sortie System.out.println(myInt);

System.out.println(myString);

// ...

2. Conditions if

int myInt = 10;

if(myInt > 10){

} else if (myInt == 10) {

} else {

}

Opérateur ternaire

int myInt =10;

boolean result = (myInt > 10) ? true : false;

Switch

int myInt = 10;

switch (myInt)

{

case 0 :

// ...

break;

default :

break;

}

4

3. Boucles While

int index = 1;

while(index < 10)

{

index++;

}

For

for (int i = 0; i < 10; i++) {

}

« For each »

int[] myArray = new int[]{1,2,3}; for (int i:myArray) { }

4. Enum public enum myEnum{

One,

Two,

Three

}

Utilisation

myEnum myValue = myEnum.Two;

if(myValue ==myEnum.Two){

}

5

5. Collections

a. Tableaux int[] myArray = new int[3];

Ou

int[] myArray = new int[]{1,2,3}; Accès aux éléments

myArray[1] = 20;

Parcours

for (int i:myArray) {

}

b. Liste import java.util.List;

import java.util.ArrayList;

List<Person> people = new ArrayList<Person>();

people.add(new Person("Jerome","[email protected]"));

people.add(new Person("Marie","[email protected]"));

for (Person person:people){

System.out.println(person.name);

}

c. Map import java.util.HashMap;

Map<Integer,String> myMap = new HashMap<Integer,String>();

myMap.put(10,"ma valeur 1");

myMap.put(20,"ma valeur 2");

String value = myMap.get(20);

6. Méthodes et fonctions public void myMethod(String name){

}

Appel

myMethod("Jerome");

« static »

public static String myMethod(String name){

String message = "Bonjour " + name + "!";

return message;

}

6

7. Objets Menu « File »… « New »… « Java class »

public class Person {

public String name;

private String email;

public Person(String name, String email){

this.name = name;

this.email = email;

}

public void sayHello(){

System.out.println("Bonjour " + name + "!");

}

}

Utilisation

Person marie = new Person("Marie", "[email protected]");

marie.sayHello();

Héritage

Créer une nouvelle classe..

public class Member extends Person{

public Member(String name, String email){

super(name,email);

}

@Override

public void sayHello() {

System.out.println("Bonjour " + name + ", bienvenue !");

}

}

Utilisation

Member jerome = new Member("Jerome","[email protected]");

jerome.sayHello();

On réécrit la méthode de la

classe de base

Appel du constructeur de

la classe de base

Hérite de « Person »

7

Interface

Création d’une interface . Plusieurs possibilités :

- Menu « File » .. « New » … « Java class » … puis sélectionner « Interface » dans la boite de dialogue

- Refactor : Depuis la classe pour laquelle créer une interface … Menu « Refactor » …

« Extract » … « Interface »

public interface IPerson {

void sayHello();

}

La classe implémentant l’interface

public class Person implements IPerson {

// etc.

@Override

public void sayHello(){

}

}

8

II. Android Documentation

1. Installation (Windows)

a. Installation du JDK 1. Télécharger, installer Java SE Development Kit 2. Variables d’environnement

Ajouter :

« JAVA_HOME » sur « C:\Program Files\Java\jdk1.8.0_45 »

Et « Path » sur « C:\Program Files\Java\jdk1.8.0_45\bin »

Vérifier que l’installation est correcte. Depuis une invite de commande (« cmd ») …

b. Android Studio 1. Télécharger et installer Android SDK et Android Studio

On peut changer le chemin

d’installation du SDK si on veut

pouvoir y accéder facilement

9

2. SDK Manager

Depuis l’écran d’accueil … « configure » … »SDK Manager »

Cocher selon les

besoins

HAXM

10

c. Problèmes et astuces

Recommandations : switch vers (« Android M Preview » faisant bugger le

designer)

Erreur : «the following class could not be found… android.support.v7.internal.widget.actionbaroverlaylayout »

Remplacer le thème par

<style name="AppTheme" parent="Base.Theme.AppCompat.Light.DarkActionBar">

<!-- Customize your theme here. -->

</style>

Erreur « app:compileDebugAidl » … dans « Build.gradle » changer

HAXM

Le pc doit supporter la virtualisation mais ne surtout pas activer Hyper-V si on est sous

Windows. Installer HAXM depuis SDK Manager ( « extras ») puis aller dans le dossier du SDK …

Intel… « Hardware_Accelerated_Execution_Manager » … exécuter « intelhaxm-android.exe ».

Avoir une « ActionBar » avec une activité « ListActivity » … Changer le thème

<style name="AppTheme"

parent="@android:style/Theme.DeviceDefault.Light.DarkActionBar"></style>

Probème des chaines de caractères « UTF-8 ». Dans « build.gradle », ajouter …

android {

compileOptions.encoding = 'ISO-8859-1'

Raccourcis utiles

Emulateur

CTRL + F12 (changer orientation de l’émulateur)

Android Studio

ALT + ENTREE pour résoudre les problèmes (imports manquants, etc.)

Commentaires : Ctrl + « / » ou Ctrl + MAJ + « / » (sur plusieurs lignes)

Utiliser les menus « Code » et « Refactor ». Exemple permet de reformater le code et

générer du code (constucteurs, getter/setter, etc.)

Debug

F7 « step into »

F8 « step over »

11

d. AVD Manager Menu « Tools » … « Android » … « AVD Manager »

Tester une application : Appuyer sur le bouton raccourci puis sélectionner un émulateur ouvert ou en lancer un

Il est possible de lancer plusieurs émulateurs en même temps (exemple un pour téléphone et un

autre pour tablette)

Créé par défaut

12

Raccourcis utiles : CTRL + F12 (changer orientation de l’émulateur)

Si l’application ne se lance pas … « swap » ou aller dans les applications

e. Divers AppInventor permet de développer des applications (et jeux) pour Android sans taper une ligne

de code (ne marche qu’avec Chrome et Firefox).

On a une partie Designer et une partie Blocks permettant de définir la logique de l’application.

2.Créer un nouveau projet Android L’écran d’accueil d’Android Studio

13

14

15

3. Activités (« Activity »)

« Navigation » entre activités

Vue « ANDROID »

« Action bar »

Menu (dossier « res\menu »)

« Layout « (dossier « res\layout »)

Intent : passage de paramètres possible

startActivity ou startActivityForResult (retour de « résultat »)

Activités (code JAVA), etc.

Layouts (UI des activités) éditables avec le

Designer

Menus et menus contextuels. Un menu

possible par activité

strings : chaines de caractères

dimens : dimensions (dp)

styles : styles des contrôles, thèmes

etc.

Ressources

Manifest contenant la liste des activités et

un filtre pour l’activité de départ

Images

16

Exemple de code « vide » d’activité

package com.romagny13.androiddemo;

import android.support.v7.app.ActionBarActivity;

import android.os.Bundle;

import android.view.Menu;

import android.view.MenuItem;

public class MainActivity extends ActionBarActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

getMenuInflater().inflate(R.menu.menu_main, menu);

return true;

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

int id = item.getItemId();

if (id == R.id.action_settings) {

return true;

}

return super.onOptionsItemSelected(item);

}

}

On définit le layout (xml) de l’activité avec

la méthode « setContentView »

17

a. Créer une activité 1. Menu « File » … « New » … « Activity » … puis « Blank Activity » par exemple

2. Lancer la seconde activité (depuis l’activité de départ)

import android.content.Intent;

On ajoute un bouton et un événement sur le click du bouton

public void startSecondActivity(View view) {

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

startActivity(intent);

}

3. Fermer la seconde activité

On ajoute par exemple un bouton à la seconde activité et un event click

public void closeActivity(View view) {

finish();

}

18

4. Manifest

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.romagny13.androiddemo" >

<application

android:allowBackup="true"

android:icon="@mipmap/ic_launcher"

android:label="@string/app_name"

android:theme="@style/AppTheme" >

<activity

android:name=".MainActivity"

android:label="@string/app_name" >

<intent-filter>

<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

<activity

android:name=".SecondActivity"

android:label="@string/title_activity_second" >

</activity>

</application>

</manifest>

Filtre indiquant que

c’est l’activité de

départ Une

activité

Une

autre

activité

19

b. Passer des données (Extra) public static final String MY_MESSAGE = "MY_MESSAGE!" ;

public void startSecondActivity(View view) {

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

intent.putExtra(MY_MESSAGE,"Bonjour!");

startActivity(intent);

}

Récupérer les données passées dans la seconde activité

public class SecondActivity extends ActionBarActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_second);

String received_message = getIntent().getStringExtra(MainActivity.MY_MESSAGE);

}

// etc.

c. Activité avec retour de résultat (« startActivityForResult ») Activité de départ

static final int SECOND_ACTIVITY_REQUEST_CODE = 1000 ;

public void startSecondActivity(View view) {

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

startActivityForResult(intent,SECOND_ACTIVITY_REQUEST_CODE);

}

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent

data) {

if(requestCode == SECOND_ACTIVITY_REQUEST_CODE){

if(resultCode == RESULT_OK){

String name = data.getStringExtra("name");

// etc.

}

}

}

Seconde activité

public void closeActivity(View view) {

handleDone();

finish();

}

private void handleDone(){

EditText nameText = (EditText) findViewById(R.id.editText);

String name = nameText.getText().toString();

Intent intent = new Intent();

intent.putExtra("name",name);

setResult(RESULT_OK,intent);

}

Récupération dans « onCreate ». On peut

ensuite faire ce que l’on veut, l’afficher

dans une TextView par exemple

Utilisation de la méthode

« startActivityForResult »

Méthode appelée au

retour

Code de succès, on pourrrait

aussi utiliser RESULT_CANCELED

On teste si le code de résultat

est OK et on récupère les

données passées

20

d. Menu Chaque activité peut avoir ou non un menu.

Création du menu

Un menu (fichier *.xml) est automatiquement ajouté lors de la création d’une activité.

On peut toutefois en ajouter … sur le dossier « menu »… « New »… « Menu Resource File »

<menu xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

tools:context=".MainActivity">

<item

android:id="@+id/action_showSecondActivity"

android:title="Deuxième activité"

app:showAsAction="always" />

<item

android:id="@+id/action_close"

android:title="Quitter"

app:showAsAction="always" />

</menu>

Intercepter le clic sur un élément du menu

(Dans le code de l’activité)

@Override

public boolean onOptionsItemSelected(MenuItem item) {

int id = item.getItemId();

if (id == R.id.action_showSecondActivity) {

startSecondActivity();

return true;

}

if (id == R.id.action_close) {

finish();

return true;

}

return super.onOptionsItemSelected(item);

}

« Always » élément de menu

toujours visible, sinon il faut

appuyer sur le bouton

« Hamburger » pour le faire

apparaitre

On pourrait aussi utiliser

un « Switch »

21

Créer un eventHandler pour un élément de menu

Il est possible également de créer un « eventHandler » pour le clic sur un élément de menu

(Menu *.xml)

<item

android:id="@+id/action_close"

android:title="Quitter"

app:showAsAction="always"

android:onClick="exitApp"/>

(Activité correspondante)

public void exitApp(MenuItem item) {

}

Créer un élément de menu par code

Dans le code de l’activité

@Override

public boolean onCreateOptionsMenu(Menu menu) {

getMenuInflater().inflate(R.menu.menu_main, menu);

MenuItem item = menu.add(Menu.NONE,Menu.NONE,103,"Nouveau menu ...");

item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);

return true;

}

Avoir le bouton de « retour »

Dans le manifest

<activity

android:name=".SecondActivity"

android:label="@string/title_activity_second"

android:parentActivityName=".MainActivity">

Par code

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_second);

getSupportActionBar().setDisplayHomeAsUpEnabled(true);

}

On définit le nom de

l’activité parente

22

Menu avec images <item

android:id="@+id/action_youtube"

android:icon="@drawable/youtube"

android:title="Youtube"

app:showAsAction="always" />

Menu contextuel

1. On ajoute un nouveau menu (*.xml) au dossier « menu »

Sur le dossier « menu » … Menu « New » … « menu Resource File » <?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android">

<group android:id="@+id/group1">

<item android:id="@+id/item1" android:title="Option 1"></item>

<item android:id="@+id/item2" android:title="Option 2"></item>

</group>

</menu>

2. Code de l’activité @Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

Button button = (Button) findViewById(R.id.button2);

registerForContextMenu(button);

}

@Override

public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo

menuInfo) {

super.onCreateContextMenu(menu, v, menuInfo);

getMenuInflater().inflate(R.menu.my_context_menu, menu);

}

@Override

public boolean onContextItemSelected(MenuItem item) {

Boolean result= true;

int id = item.getItemId();

switch (id)

{

case R.id.item1:

// do something

break;

case R.id.item2:

break;

default: result = super.onContextItemSelected(item);

}

return result;

}

Quand on clique sur le bouton

cela ouvre le menu contextuel

Quand on clique sur les

éléments du menu

contextuel

23

4. Layouts (« ViewGroup »)

a. Designer

Vue « Design » et « Text » (xml) Designer Propriétés de

l’élément sélectionné

Vue en « arbre »

des composants

Composants « glissables »

sur l’interface

Permet d’avoir des

prévisualisations à

différentes résolutions

Version du device

dans l’aperçu

Changer

l’orientation

Changer le thème Permet de switch

directement vers le code

java de l’activité

API Version

Permet de mettre en forme

l’élément sélectionné

(« wrap_content », etc.)

Zoom

24

Différents layouts

LinearLayout : alignement horizontal ou vertical des éléments

RelativeLayout : éléments positionnés les uns par rapport aux autres

GridLayout (seulement à partir API Level 14)

FrameLayout : pour n’afficher qu’un élément

TableLayout

b. Propriétés « partagées »

Tailles

- « dp » (« ratio », exemple 1dp = 1px sur un écran à 160px)

- et « sp » pour la taille des fonts

Weight

<Button

android:id="@+id/button3"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_weight="1"

android:text="Un" />

<Button

android:id="@+id/button4"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_weight="4"

android:text="Deux" />

« wrap_content », « fill_parent »

On peut régler la hauteur et la largeur :

- « fill_parent » occupe toute l’espace disponible

- (« match_parent » presque comme fill_parent) - « wrap_content » n’occupe que l’espace nécessaire au contenu

Bouton de poids « 4 » occupera 80% de

l’espace total du parent

1 + 4 = 5 (100%)

25

Gravity et « layout_gravity »

Appliqué au contrôle (TextView par exemple) : centre le contenu

<TextView

android:id="@+id/textView2"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:gravity="center_horizontal"

android:text="Mon texte"

android:textAppearance="?android:attr/textAppearanceLarge" />

« layout_gravity » appliqué au contrôle par rapport à son parent

(Avec orientation « verticale » pour le conteneur « LinearLayout »)

<TextView

android:id="@+id/textView2"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center_horizontal"

android:text="Mon texte"

android:textAppearance="?android:attr/textAppearanceLarge" />

« fill_parent » sur la

hauteur et largeur de

la TextView

« wrap_content » sur

la hauteur et largeur de

la TextView

26

c. LinearLayout Eléments disposés sur une ligne horizontalement ou verticalement

Exemple

<LinearLayout

android:orientation="horizontal"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_gravity="center_horizontal">

</LinearLayout>

Exemple de conteneur de base

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

tools:context="com.romagny13.androiddemo.ThirdActivity">

</LinearLayout>

d. RelativeLayout Eléments placés les uns par rapport aux autres.

Par défaut les éléments sont placés en haut à gauche.

<TextView

android:id="@+id/textView1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Nom" />

<EditText

android:id="@+id/editText1"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_toRightOf="@+id/textView1" />

<Button

android:id="@+id/button1"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_below="@+id/editText1"

android:text="OK" />

Orientation « horizontal » par défaut

« layout_toRightOf » de la TextView

« layout_below » de l’EditText

27

A cela on peut ajouter : les propriétés d’alignement, « alignBaseligne » (pour aligner le texte), la

visibilié (« visibility » et « alignWithParentIfMissing »), les marges

Le designer offre des aides pour bien placer les éléments

e. GridLayout Même exemple que précédemment avec une grille (à partir API Level 14).

<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="horizontal"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

tools:context="com.romagny13.androiddemo.ThirdActivity"

android:columnCount="2"

android:rowCount="2">

<TextView

android:id="@+id/textView1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Nom" />

<EditText

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:id="@+id/editText1"

android:layout_row="0"

android:layout_column="1" />

<Button

android:id="@+id/button1"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_row="1"

android:layout_column="0"

android:layout_columnSpan="2"

android:text="OK" />

</GridLayout>

La grille a 2 colonnes et

2 lignes

Placement dans la grille.

L’index commence à 0

« ColumnSpan »

28

f. TableLayout

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent" >

<TableRow

android:layout_width="wrap_content"

android:layout_height="wrap_content" >

<TextView

android:id="@+id/textView1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Nom" />

<EditText

android:id="@+id/editText1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:ems="10" >

<requestFocus />

</EditText>

</TableRow>

<View android:layout_height="2dip" android:background="#000000"/>

<TableRow

android:layout_width="wrap_content"

android:layout_height="wrap_content">

<Button

android:id="@+id/button1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Button" />

</TableRow>

</TableLayout>

29

g. Include Création d’un layout (exemple « youtube.xaml » dans le dossier « layouts » affiche une image)

<?xml version="1.0" encoding="utf-8"?>

<ImageView xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:src="@drawable/youtube" />

Utilisation (dans le layout par ex de l’activité principale)

<RelativeLayout

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

tools:context=".MainActivity">

<!-- etc. -->

<include layout="@layout/youtube"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_centerHorizontal="true" />

</RelativeLayout>

On pourrait également utiliser « ViewStub » pour gérer la visibilité

Propriété « layout » pointe sur le

layout créé, on peut également

réglé le positionnement

30

h. Custom View et composant

Custom View

Exemple avec une « custom TextView ».

1. On crée une classe héritant de la View désirée (dans l’exemple « TextView »)

public class CustomTextView extends TextView {

public CustomTextView(Context context) {

super(context);

init();

}

public CustomTextView(Context context, AttributeSet attrs) {

super(context, attrs);

init();

}

public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

init();

}

private void init(){

this.setText("Bonjour!");

this.setBackgroundColor(Color.DKGRAY);

this.setTextColor(Color.WHITE);

}

}

2. Utilisation

En code, exemple on définit le contenu d’une activité

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

CustomTextView view = new CustomTextView(this);

setContentView(view);

}

XML (à préférer car cela permet d’avoir accès à toutes les propriétés depuis le Xml)

<RelativeLayout

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

tools:context=".MainActivity">

<!-- etc. -->

<com.romagny13.androiddemo.CustomTextView

android:layout_width="fill_parent"

android:layout_height="wrap_content" />

</RelativeLayout>

31

Custom composant (classe + layout)

On définit composant comprenant par exemple une boite de texte (EditText) et un bouton.

Lorsque l’utilisateur clique sur le bouton, un toast « bonjour …» apparait.

1. layout

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="horizontal">

<EditText

android:id="@+id/nameText"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_weight="4"

android:inputType="textPersonName"

android:text="Name" />

<Button

android:id="@+id/okButton"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_weight="1"

android:text="Go" />

</LinearLayout>

2. classe

public class CustomCompound extends LinearLayout {

private EditText nameText;

private Button okButton;

public CustomCompound(Context context) {

super(context);

init();

}

public CustomCompound(Context context, AttributeSet attrs) {

super(context, attrs);

init();

}

public CustomCompound(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

init();

}

private void init(){

LayoutInflater inflater = LayoutInflater.from(getContext());

inflater.inflate(R.layout.custom_compound,this);

nameText = (EditText) findViewById(R.id.nameText);

okButton = (Button) findViewById(R.id.okButton);

okButton.setOnClickListener(new View.OnClickListener(){

@Override

public void onClick(View v) {

String message = "Bonjour " + nameText.getText() + "!";

Toast.makeText(getContext(), message, Toast.LENGTH_LONG).show();

}

});

}

}

On pourrait utiliser le tag

« Merge »

32

3. Utilisation

<RelativeLayout

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

tools:context=".MainActivity">

<!-- etc. -->

<com.romagny13.androiddemo.CustomCompound

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_below="@+id/imageView2">

</com.romagny13.androiddemo.CustomCompound>

</RelativeLayout>

Balise « merge »

Permet d’éviter d’avoir une « imbrication » de plusieurs « LinearLayout »

<?xml version="1.0" encoding="utf-8"?>

<merge xmlns:android="http://schemas.android.com/apk/res/android">

<EditText

android:id="@+id/nameText"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_weight="4"

android:inputType="textPersonName"

android:text="Name" />

<Button

android:id="@+id/okButton"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_weight="1"

android:text="Go" />

</merge>

Si on avait besoin de définir l’orientation on le ferait dans le code

public class CustomCompound extends LinearLayout {

// etc.

private void init(){

LayoutInflater inflater = LayoutInflater.from(getContext());

inflater.inflate(R.layout.custom_compound,this);

setOrientation(LinearLayout.HORIZONTAL);

}

}

33

i. Fragments 1. Créer le « layout » (xml) du fragment

Sur le dossier « layouts » … Menu « New » … « Layout Resource File ». Commencer le nom du

fragment par « fragment_ »

Définition du contenu du fragment

2. Créer la classe (java) du fragment

Menu « File » … « New » … « Java class »

public class MyFragment extends Fragment {

@Nullable

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle

savedInstanceState) {

View view = inflater.inflate(R.layout.fragment_my_fragment, container,false);

return view;

}

}

3. Ajouter un fragment à une activité

XML

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

tools:context=".MainActivity">

<fragment

android:id="@+id/my_fragment"

android:name="com.romagny13.fragmentdemo.MyFragment"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

tools:layout="@layout/fragment_my_fragment" />

</RelativeLayout>

Donner un id, un nom,…

On définit le contenu (le layout du fragment)

34

Ou en code

Ne pas oublier de donner un id au layout « conteneur » (ici pour « activity_main.xml »)

<RelativeLayout

xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/my_container"

public class MainActivity extends ActionBarActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

if (savedInstanceState == null) {

getFragmentManager().beginTransaction()

.add(R.id.my_container, new MyFragment())

.commit();

}

}

// etc.

Communication entre fragments d’une même activité

Créer une interface : Menu « File » … « New » … « Java class » … puis sélectionner « Interface »

public interface OnPersonSelectionChangeListener {

public void onPersonSelectionChanged(int index);

}

Déclenchement au changement d’élément sélectionné

public class PeopleListFragment extends ListFragment {

private PeopleData peopleData = new PeopleData();

// etc.

@Override

public void onActivityCreated(Bundle savedInstanceState) {

super.onActivityCreated(savedInstanceState);

List<String> people = peopleData.getPeopleNames();

ArrayAdapter<String> adapter =

new ArrayAdapter(getActivity(),android.R.layout.simple_list_item_1, people);

setListAdapter(adapter);

}

@Override

public void onListItemClick(ListView l, View v, int position, long id) {

OnPersonSelectionChangeListener listener =

(OnPersonSelectionChangeListener) getActivity();

listener.onPersonSelectionChanged(position);

}

}

Ajout d’une instance du fragment

au conteneur

35

Activité

public class MainActivity extends ActionBarActivity

implements OnPersonSelectionChangeListener{

// etc.

@Override

public void onPersonSelectionChanged(int index) {

FragmentManager manager = getFragmentManager();

PersonDetailsFragment fragment =

(PersonDetailsFragment) manager.findFragmentById(R.id.fragment_person_details);

fragment.setPerson(index);

}

}

Fragment « abonné »

public class PersonDetailsFragment extends Fragment {

private PeopleData peopleData = new PeopleData();

// etc.

public void setPerson(int index){

Person person = peopleData.getOne(index);

TextView textView =(TextView) getView().findViewById(R.id.nameText);

textView.setText(person.name);

}

}

36

5. Widgets

Les Widgets dérivent de la classe de base View Méthodes findViewById, getRootView

TextView (Label)

Button (sous classe de TextView) ImageView

EditText (champ de saisie)

o andoid :autoText (correction automatique active ou non)

o andoid :capitalize (Majuscule première lettre)

o andoid :digits (inique si le champ n’accepte que certains chiffres)

o andoid :singleLine (une seule ligne)

o Méthodes setText,getText

CheckBox

o andoid :isChecked

o Méthodes setChecked et toggle (inverse l’état de la case)

RadioButton (dans un RadioGroup)

o Méthodes check(), clearCheck(), getCheckedRadionButtonId()

Etc.

a. Accéder à un widget (findViewById) Button button = (Button) findViewById(R.id.button1);

b. Utilisation « ImageView » Copier d’images dans le dossier « drawable »

Utilisation de la ressource : on définit la propriété « src » (par code ou depuis le panneau

propriétés du Designer)

<ImageView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:id="@+id/imageView"

android:src="@drawable/twitter"

android:layout_below="@+id/checkBox1"

android:layout_centerHorizontal="true" />

Par code

int resource = getResources().getIdentifier("youtube","drawable",getPackageName());

ImageView imageView = (ImageView) findViewById(R.id.imageView2);

imageView.setImageResource(resource);

37

6. View Events

public class MainActivity extends ActionBarActivity implements View.OnClickListener{

// etc.

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

Button button = (Button) findViewById(R.id.button2);

button.setOnClickListener(this);

}

@Override

public void onClick(View v) {

}

Ou plus simplement

Button button = (Button) findViewById(R.id.button2);

button.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

}

});

38

7. « ArrayAdapter »

a. avec ListActivity Exemple « ArrayAdapter »

<RelativeLayout

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

tools:context=".MainActivity">

<ListView

android:id="@android:id/list"

android:layout_width="fill_parent"

android:layout_height="wrap_content"></ListView>

</RelativeLayout>

public class MainActivity extends ListActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

String[] fruits = new String[]{"Pomme","Poire","Banane"};

ArrayAdapter<String> adapter =

new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, fruits);

setListAdapter(adapter);

}

On ajoute une

« ListView » dans le

layout de l’activité.

Attention à l’id

L’activité hérite de « ListActivity »

Contexte (« this »)

39

Autre exemple

List<Person> people = peopleService.getAll();

ArrayAdapter<Person> adapter =

new ArrayAdapter<Person>(this,android.R.layout.simple_list_item_1, people);

setListAdapter(adapter);

public class Person {

private String name;

// etc.

@Override

public String toString() {

return name;

}

}

b. Avec ActionBarActivity On pourrait également ajouter une « ListView » à une activité de « base »

public class MainActivity extends ActionBarActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

List<Person> people = peopleService.getAll();

ArrayAdapter<Person> adapter =

new ArrayAdapter<Person>(this,android.R.layout.simple_list_item_1, people);

ListView list = (ListView) findViewById(android.R.id.list);

list.setAdapter(adapter);

}

// etc.

La listView affichera le nom de chaque

personne

On récupère la ListView du layout et on définit l’ « adapter »

40

c. Personnalisé

1. On crée un layout (« person_item » par ex)

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:padding="10dp">

<ImageView

android:id="@+id/imageView"

android:layout_width="50dp"

android:layout_height="50dp"

android:layout_weight="1" />

<TextView

android:id="@+id/nameText"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_toEndOf="@+id/imageView"

android:layout_toRightOf="@+id/imageView"

android:layout_weight="3" />

<ImageButton

android:id="@+id/deleteButton"

android:layout_width="50dp"

android:layout_height="50dp"

android:layout_toEndOf="@+id/nameText"

android:layout_toRightOf="@+id/nameText"

android:src="@drawable/close"

android:scaleType="fitCenter"/>

</LinearLayout>

Chaque élément aura une

image, un texte et un

bouton « delete »

41

2. On crée une classe pour l’adapter personnalisé

public class PeopleArrayAdapter extends ArrayAdapter<Person> {

Context context;

List<Person> objects;

PeopleRepository peopleRepository;

public PeopleArrayAdapter(Context context, int resource, List<Person> objects) {

super(context, resource, objects);

this.context = context;

this.objects = objects;

peopleRepository = new PeopleRepository(context);

}

@Override

public View getView(final int position, View convertView, ViewGroup parent) {

LayoutInflater inflater =

(LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);

View view = inflater.inflate(R.layout.person_item, null);

Person person = objects.get(position);

ImageView imageView = (ImageView) view.findViewById(R.id.imageView);

TextView nameText = (TextView) view.findViewById(R.id.nameText);

ImageButton deleteButton = (ImageButton) view.findViewById(R.id.deleteButton);

int id =

context.getResources().getIdentifier("avatar1", "drawable", context.getPackageName());

imageView.setImageResource(id);

nameText.setText(person.getName());

deleteButton.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Person person = objects.get(position);

peopleRepository.open();

int result = peopleRepository.delete(person);

if (result == 1) {

objects.remove(position);

notifyDataSetChanged();

}

}

});

return view;

}

3. Utilisation

ArrayAdapter<Person> adapter = new PeopleArrayAdapter(this,0, people);

On définit la

vue

On « remplit » les

contrôles

Gestion du clic sur

le bouton

suprrimer

42

8. Cycle de vie d’activité Lancement de l’activité … onCreate…onStart…onResume…onPause…onStop…onDestroy

On peut suivre le cycle de vie d’une activité par exemple (dans « MainActivity »)

@Override

protected void onStart() {

super.onStart();

Log.i("MainActivity","onStart");

}

@Override

protected void onResume() {

super.onResume();

Log.i("MainActivity", "onResume");

}

@Override

protected void onPause() {

super.onPause();

Log.i("MainActivity", "onStart");

}

@Override

protected void onStop() {

super.onStop();

Log.i("MainActivity", "onStop");

}

@Override

protected void onDestroy() {

super.onDestroy();

Log.i("MainActivity", "onDestroy");

}

Sauver/ restaurer les états de contrôles d’une activité Par exemple on ajoute une case à cocher et on sauvegarde son état (coché ?)

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

if (savedInstanceState != null) {

restoreState(savedInstanceState);

}

}

private void restoreState(Bundle savedInstanceState) {

boolean isChecked = savedInstanceState.getBoolean("checkBox1Checked");

CheckBox checkBox = (CheckBox) findViewById(R.id.checkBox1);

checkBox.setChecked(isChecked);

}

@Override

public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {

super.onSaveInstanceState(outState, outPersistentState);

CheckBox checkBox = (CheckBox) findViewById(R.id.checkBox1);

outState.putBoolean("checkBox1Checked", checkBox.isChecked());

}

Sauvegarde clé et

valeur

Récupération de la

valeur sauvegardée et

Restauration de l’état

On pourrait créer des

constantes

43

9. Ressources Dossier « res » : toutes les ressources … accessibles avec « R » (classe générée).

o res/drawable : images (PNG, JPEG et GIF)

o res/layout : interfaces utilisateurs

o res/values :

string.xml : chaines de caractères

dimens.xml : dimensions (dp, sp)

arrays.xml définit les tableaux

o res/xml : fichiers xml supplémentaires (préférences, etc.)

o res/menu : menus

o res/raw ressources empaquetées sans aucun traitement

o assets : ressources « brutes » accessibles par un flux de données

o Styles

Ajout d’une ressource (« strings.xml ») … avec le Refactor

44

« strings.xml »

<resources>

<!-- etc. -->

<string name="my_title">Activité de départ</string>

</resources>

Il serait bien sur possible d’ajouter les ressources « à la main ».

Utilisation de la ressource

<TextView

android:id="@+id/textView"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:gravity="center_horizontal"

android:text="@string/my_title" />

Par code … R.string.my_title

On accède aux ressources par l’intermédiaire du fichier R généré (documentation)

45

10. Préférences partagées Sauvegarder de préférences

SharedPreferences preferences =

PreferenceManager.getDefaultSharedPreferences(this);

SharedPreferences.Editor editor = preferences.edit();

editor.putString("MyPreference", "ma valeur de préférence");

// autres variables

editor.commit();

Ou

SharedPreferences preferences = getPreferences(MODE_PRIVATE); // etc.

Retrouver des préférences

SharedPreferences preferences =

PreferenceManager.getDefaultSharedPreferences(this);

String myPreference = preferences.getString("MyPreference",null);

if(myPreference!=null){

// utilisation

}

« PreferenceActivity » On peut également créer une activité dédiée aux préférences. Menu « File » … « New » …

« Activity » … « Settings Activity »

On lance l’activité au clic sur un élément de menu

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

startActivity(intent);

… On peut également ajouter les éléments un par un… sur le dossier « xml » … « New » … « Xml

Resource File »

<?xml version="1.0" encoding="utf-8"?>

<PreferenceScreen

xmlns:android="http://schemas.android.com/apk/res/android">

<PreferenceCategory android:title="General settings" >

<EditTextPreference

android:key="pref_email"

android:title="Email" />

</PreferenceCategory>

</PreferenceScreen>

Préférences de l’activité

uniquement et « private »

accessible qu’à l’application

Préférences partagées

46

Ajout d’une activité nommée « SettingsActivity » par ex

public class SettingsActivity extends PreferenceActivity {

@Override

public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {

super.onCreate(savedInstanceState, persistentState);

addPreferencesFromResource(R.xml.settings);

}

}

Ajouter l’activité au Manifest

<application

android:allowBackup="true"

android:icon="@mipmap/ic_launcher"

android:label="@string/app_name"

android:theme="@style/AppTheme" >

<!-- ect -->

<activity

android:name=".SettingsActivity"

android:label="Préférences" >

</activity>

</application>

Et on lance l’activité comme précédemment depuis le menu de l’activité de départ

Retrouver la préférence

SharedPreferences preferences =

PreferenceManager.getDefaultSharedPreferences(this);

String prefEmail = preferences.getString("pref_email", "Non trouvé");

47

11. Fichiers private void saveFile(String text, String fileName) throws IOException {

FileOutputStream fos = openFileOutput(fileName, MODE_PRIVATE);

fos.write(text.getBytes());

fos.close();

}

private String readFile(String fileName) throws IOException {

FileInputStream fis = openFileInput(fileName);

BufferedInputStream bis = new BufferedInputStream(fis);

StringBuffer result = new StringBuffer();

while (bis.available() != 0) {

char c = (char) bis.read();

result.append(c);

}

bis.close();

fis.close();

return result.toString();

}

Utilisation au clic sur boutons

public void read(View view) {

try{

String text = readFile("myfile.txt");

Toast.makeText(this, text, Toast.LENGTH_LONG).show();

}

catch (Exception e){

e.printStackTrace();

}

}

public void write(View view) {

try{

saveFile("Bonjour!","myfile.txt");

}

catch (Exception e){

e.printStackTrace();

}

}

XML Utiliser XmlPullParser ou Document (DOM)

48

JSON (Utiliser les classes « JSONArray » et « JSONObject »)

private JSONArray readJSON(String fileName) throws JSONException, IOException {

String text = readFile(fileName);

JSONArray data = new JSONArray(text);

return data;

}

Utilisation

public void read(View view) {

try{

JSONArray array = readJSON("people.json");

Toast.makeText(this, array.toString(), Toast.LENGTH_LONG).show();

}

catch (Exception e){

e.printStackTrace();

}

}

public void write(View view) {

try{

String json = "[\n" +

" {\n" +

" \"name\": \"Jerome\",\n" +

" \"email\": \"[email protected]\"\n" +

" },\n" +

" {\n" +

" \"name\": \"Marie\",\n" +

" \"email\": \"[email protected]\"\n" +

" }\n" +

"]";

saveFile(json,"people.json");

}

catch (Exception e){

e.printStackTrace();

}

}

Créer un objet JSON

Person person = new Person(1,"jerome","[email protected]");

JSONObject json = new JSONObject();

json.put("id", person.getId());

json.put("name", person.getName());

json.put("email", person.getEmail());

Avec « json.toString() » on obtient

{"id":"1","name":"jerome","email":"[email protected]"}

On peut également utiliser JSONArray.

49

12. SQLite Base de données « légère » ne demandant pas de serveur. Documentation

DbHelper

public class DbHelper extends SQLiteOpenHelper {

public DbHelper(Context context, String name, SQLiteDatabase.CursorFactory factory,

int version) {

super(context, name, factory, version);

}

@Override

public void onCreate(SQLiteDatabase db) {

String request ="Create table Person (" +

"Id integer primary key autoincrement," +

"Name text not null," +

"Email text not null" +

");";

db.execSQL(request);

}

@Override

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

String request = "Drop table Person;";

db.execSQL(request);

}

}

Le « model »

public class Person {

private long id;

private String name;

private String email;

public Person(){ }

public Person(String name, String email){

this.name = name;

this.email = email;

}

public void setId(long id){ this.id = id; }

public void setName(String name){ this.name = name; }

public void setEmail(String email){ this.email = email; }

public long getId(){ return id; }

public String getName(){ return name; }

public String getEmail(){ return email; }

public String toString() {

return name;

}

}

« Service »

On peut utiliser la méthode « execSQL » dans le cas de requêtes ne retournant pas de résultat.

Lecture : on utilise la méthode « query » de « SQLiteDatabase » et un « Cursor » pour parcourir

les données retournées

Ecriture : utilisation des méthodes « insert », « update », « delete » de « SQLiteDatabase

Création de la table

si elle n’existe pas

50

Utilisation : On ouvre la connexion dans « onCreate » de l’activité et la ferme dans « onResume »

ou « onStop »

public class PeopleRepository {

DbHelper dbHelper;

SQLiteDatabase db;

public PeopleRepository(Context context) {

dbHelper = new DbHelper(context, "dbPeople", null, 1);

}

public void open() {

db = dbHelper.getWritableDatabase();

}

public void close() {

dbHelper.close();

}

public List<Person> getAll() {

List<Person> people = new ArrayList<>();

String[] columns = new String[]{"Id", "Name", "Email"};

Cursor cursor = db.query("Person", columns, null, null, null, null, null);

while (cursor.moveToNext()) {

Person person = new Person();

person.setId(cursor.getLong(cursor.getColumnIndex("Id")));

person.setName(cursor.getString(cursor.getColumnIndex("Name")));

person.setEmail(cursor.getString(cursor.getColumnIndex("Email")));

people.add(person);

}

cursor.close();

return people;

}

public Person insert(Person person) {

ContentValues values = new ContentValues();

values.put("Name", person.getName());

values.put("Email", person.getEmail());

long newId = db.insert("Person", null, values);

person.setId(newId);

return person;

}

public int update(Person person) {

ContentValues values = new ContentValues();

values.put("Name", person.getName());

values.put("Email", person.getEmail());

String where = "Id = " + person.getId();

return db.update("Person", values,where,null);

}

public int delete(Person person) {

String where = "Id = " + person.getId();

return db.delete("Person", where,null);

}

}

Clause « where »

Récupération de l’id

(autoincrement)

On pourrait créer des

constantes (avec nom de table,

colonnes) réutilisables dans

toutes les requêtes

51

13. HTTP

a. AsyncTask Ajouter la classe à l’activité (« nested class »)

private class MyTask extends AsyncTask<String,String,String>{

@Override

protected void onPreExecute() {

progressBar.setVisibility(View.VISIBLE);

displayMessage("Starting task");

}

@Override

protected String doInBackground(String... params) {

for(int i=0;i < params.length; i++){

publishProgress(params[i]);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

}

}

return "Tâche terminée.";

}

@Override

protected void onPostExecute(String result) {

progressBar.setVisibility(View.INVISIBLE);

displayMessage(result);

}

@Override

protected void onProgressUpdate(String... values) {

displayMessage(values[0]);

}

}

Exécution de la tâche (au clic sur l’élément de menu « Tasks »)

MyTask task = new MyTask();

task.execute("message 1", "message 2", "message 3");

Si on utilise « Thread.sleep » lancer la tâche avec task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "message 1",

"message 2", "message 3");

Exécution de la tâche.

« publishProgress » appelle

« onProgressUpdate »

Avant que la tâche

soit exécutée

A la fin de la tâche

Types : Params, Progress,

result

On a une TextView dans laquelle on

affiche les messages et une

ProgressBar visible durant

l’exécution de la tâche

Pour la démo

52

Code de l’activité

public class MainActivity extends ActionBarActivity {

TextView messagesText;

ProgressBar progressBar;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

messagesText = (TextView) findViewById(R.id.messagesText);

messagesText.setMovementMethod(new ScrollingMovementMethod());

progressBar = (ProgressBar) findViewById(R.id.progressBar);

progressBar.setVisibility(View.INVISIBLE);

}

// etc.

public void displayMessage(String message){

messagesText.append(message + "\n");

}

private class MyTask extends AsyncTask<String,String,String>{

// code de la tâche

}

}

b. Tester la connexion private boolean isOnline(){

ConnectivityManager manager = (ConnectivityManager)

getSystemService(CONNECTIVITY_SERVICE);

NetworkInfo info = manager.getActiveNetworkInfo();

return(info!=null && info.isConnectedOrConnecting());

}

Permissions à ajouter au manifest

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

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

53

c. Avec « HttpURLConnection » Documentation

public class HttpManager {

public static String getData(String uri) {

BufferedReader reader = null;

try {

URL url = new URL(uri);

HttpURLConnection connection =

(HttpURLConnection) url.openConnection();

StringBuilder builder = new StringBuilder();

reader =

new BufferedReader(new InputStreamReader(connection.getInputStream()));

String line = "";

while ((line = reader.readLine()) != null) {

builder.append(line + "\n");

}

return builder.toString();

} catch (Exception e) {

e.printStackTrace();

return null;

}

finally {

try {

reader.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

54

d. Parser une réponse au format JSON

[{"id":1,"name":"Marie","email":"[email protected]"},{"id":2,"name":"Jerome","email":"[email protected]"}]

On créé une classe « JSONParser » par exemple qui renvoie une liste de personnes à partir du

json reçu

public class JSONParser {

public static List<Person> getPeople(String content) {

try {

JSONArray array = new JSONArray(content);

List<Person> people = new ArrayList<>();

for (int i = 0; i < array.length() ; i++) {

JSONObject object = array.getJSONObject(i);

Person person = new Person();

person.setId(object.getInt("id"));

person.setName(object.getString("name"));

person.setEmail(object.getString("email"));

people.add(person);

}

return people;

} catch (Exception e) {

e.printStackTrace();

return null;

}

}

}

Utilisation dans l’activité (au clic sur un menu par exemple)

if(isOnline()){

MyTask task = new MyTask();

task.execute("http://monservice123.com/people");

}

La tâche

private class MyTask extends AsyncTask<String,String,String>{

@Override

protected void onPreExecute() {

progressBar.setVisibility(View.VISIBLE);

}

@Override

protected String doInBackground(String... params) {

String content = HttpManager.getData(params[0]);

return content;

}

@Override

protected void onPostExecute(String result) {

List<Person> people = JSONParser.getPeople(result);

displayPeople(people);

progressBar.setVisibility(View.INVISIBLE);

}

}

On peut adapter la méthode affichant la sortie

public void displayPeople(List<Person> people){

for(Person person : people){

messagesText.append(person.getName() + "\n");

}

}

55

e. POST + passage de paramètre au format JSON public static String postData(Person person,String uri) {

BufferedReader reader = null;

try {

// json

JSONObject json = new JSONObject();

json.put("id", person.getId());

json.put("name", person.getName());

json.put("email", person.getEmail());

URL url = new URL(uri);

HttpURLConnection connection = (HttpURLConnection) url.openConnection();

connection.setDoOutput(true);

OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());

writer.write(json.toString());

writer.flush();

// réponse

StringBuilder builder = new StringBuilder();

reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));

String line = "";

while ((line = reader.readLine()) != null) {

builder.append(line + "\n");

}

return builder.toString();

} catch (Exception e) {

e.printStackTrace();

return null;

}

finally {

try {

reader.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

f. Libraires OkHttp, Retrofit, Volley

« fabrication » de la chaine

de caractères json à partir

d’un objet « personne »

56

14. Toasts Documentation

import android.widget.Toast;

Toast.makeText(this, "Mon message!", Toast.LENGTH_LONG).show();

15. Notifications 1. On définit les propriétés de la notification (« NotificationCompat.Builder »)

2. On déclenche la notification avec « NotificationManager »

Propriétés de base

String title = "Mon titre";

String contentText = "Message ...";

NotificationCompat.Builder builder = new NotificationCompat.Builder(this);

builder .setSmallIcon(R.drawable.message)

.setContentTitle(title)

.setContentText(text)

Affichage

Notification notification = builder.build();

NotificationManager manager =

(NotificationManager) getSystemService(NOTIFICATION_SERVICE);

manager.notify(1,notification);

57

Avec activité

On créé une activité qui sera affichée au clic sur la notification

String title = "Mon titre";

String contentText = "Message ...";

NotificationCompat.Builder builder = new NotificationCompat.Builder(this);

builder .setSmallIcon(R.drawable.message)

.setContentTitle(title)

.setContentText(text)

// intent

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

intent.putExtra("Title",title);

intent.putExtra("ContentText",contentText);

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,0);

builder.setContentIntent(pendingIntent);

//

Notification notification = builder.build();

NotificationManager manager =

(NotificationManager) getSystemService(NOTIFICATION_SERVICE);

manager.notify(1,notification);

Plus de propriétés …

Définir une grande icone en plus d’une petite icone

builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.myimage))

Définir un nombre

builder.setNumber(100)

Activité affichée au clic sur

la notification

58

« BigTextStyle »

String title = "Mon titre";

String contentText = "Message ...";

NotificationCompat.Builder builder = new NotificationCompat.Builder(this);

builder.setSmallIcon(R.drawable.message);

NotificationCompat.BigTextStyle style = new NotificationCompat.BigTextStyle();

style.setBigContentTitle(title)

.setSummaryText(text)

.bigText("Lorem ipsum dolor sit …");

builder.setStyle(style);

// etc.

« BigPictureStyle »

String title = "Mon titre";

String contentText = "Message ...";

NotificationCompat.Builder builder = new NotificationCompat.Builder(this);

builder.setSmallIcon(R.drawable.message);

NotificationCompat.BigPictureStyle style = new NotificationCompat.BigPictureStyle();

style.setBigContentTitle(title)

.setSummaryText(text)

.bigPicture(BitmapFactory.decodeResource(getResources(),R.drawable.foodies));

builder.setStyle(style);

// etc.

59

« addAction »

Peut-être couplé à un service par exemple pour stopper celui-ci

builder.addAction(R.drawable.close,"Stop",pendingIntent);

16. Service et IntentService

a. Service Menu « File » … « New » … « Service »

public class MyService extends Service {

public MyService() {

}

@Override

public void onCreate() {

super.onCreate();

}

@Override

public void onDestroy() {

super.onDestroy();

}

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

for (int i = 0; i < 5; i++) {

try {

Thread.sleep(1000);

Log.i("MyIntentSerice", "valeur de i : " + i);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

return 0;

}

@Override

public IBinder onBind(Intent intent) {

// TODO: Return the communication channel to the service.

throw new UnsupportedOperationException("Not yet implemented");

}

}

Problème : ici le service est bloquant

Pour la

démo

60

b. IntentService … pour un service en tâche de fond (le service s’exécute sur son propre thread ce qui n’est pas

bloquant)

Menu « File » … « New » … « Service » … « IntentService »

public class MyIntentService extends IntentService {

public MyIntentService() {

super("MyIntentService");

}

@Override

protected void onHandleIntent(Intent intent) {

if (intent != null) {

for (int i = 0; i < 5; i++) {

try {

Thread.sleep(1000);

Log.i("MyIntentSerice", "valeur de i : " + i);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

}

Lancement du service

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

startService(intent);

Pour la démo

On passe le nom du thread

61

17. « Broadcast Receiver » Sorte de « Messenger »

Abonnement (dans activitié par exemple)

IntentFilter filter = new IntentFilter("MyFilter");

MyReceiver receiver = new MyReceiver();

registerReceiver(receiver, filter);

Envoi de message (service par exemple)

Intent dointent = new Intent();

dointent.setAction("MyFilter");

sendBroadcast(dointent);

Menu « File »… « New »… « Other »… « Broadcast Receiver »

public class MyReceiver extends BroadcastReceiver {

public MyReceiver() {

}

@Override

public void onReceive(Context context, Intent intent) {

Toast.makeText(context, "Tâche finie", Toast.LENGTH_LONG).show();

}

}

« Dynamic Broadcast Receiver» Au lieu de créer une classe héritant de « BroadcastReceiver » … on définit directement le code

dans son activité (dans « onCreate » par exemple)

IntentFilter filter = new IntentFilter("MyFilter");

BroadcastReceiver receiver = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

Toast.makeText(getApplicationContext(), "Tâche finie", Toast.LENGTH_SHORT).show();

}

};

registerReceiver(receiver, filter);

Se désenregistrer dans « onDestroy » par exemple

unregisterReceiver(receiver);