Développement d’application Android : les bases et prérequis


Télécharger Développement d’application Android : les bases et prérequis

★★★★★★★★★★3.5 étoiles sur 5 basé sur 1 votes.
Votez ce document:

Télécharger aussi :


Introduction au Développement d’Application Android

Amosse EDOUARD,

Doctorant, INRIA/I3S - UNSA

 

?? Comprendre l’architecture du système Android

?? Comprendre l’organisation d’une application Android 

?? Développer et déployer des applications natives Android

?? Connaitre les bonnes pratiques du développement d’application Android 

2

 

}}L’art du développement Android par Mark L. Murphy

}}Professional NFC application

development for android by Vedat Coskun

}}Android developer :

 

ContraintesMobiles

}}Tenir compte du matériel : 

}}Une puissance processeur faible;

}}Une RAM limitée;

}}Plusieurs type de résolutions de l’écran;

}}Des coûts élevés de transferts de données;

}}Des connexions réseau moins stables;

}}Efficacité : optimiser votre code afin qu’il soit rapide et réactif.

4

Contraintes mobiles

ØØ?La performance;

ØØ?La réactivité;

ØØ?La sécurité;

ØØ?La transparence;

5


 

Plusieurs langages :

 

Multi OS

   

Plusieurs outils : 

Déploiement facile (multi plateforme)

   

}}Android est un système d’exploitation  OPEN

SOURCE pour terminaux mobiles (smartphones, PDA, tablet, …)

}}Conçu à la base par une startup (Android) rachetée par Google en 2005

}}Pour la promotion de ce système Google a fédéré autour de lui une trentaine de partenaires réunis au sein de l’Open Handset Alliance (OHA)

}}C’est aujourd’hui le système d’exploitation mobile le plus utilisé à travers le monde


 

Introduction à Android

Le système d’exploitation Android est basé sur Linux. Au plus bas niveau de ce système se trouve un noyau Linux destiné à la gestion du matériel comme :

}}Drivers de ces terminaux, 

}}La gestion de la mémoire, 

}}La gestion des processus  }}L’accès au réseau

}}…

 

}}Développeurs 

?? Pas besoin de licence 

?? Simple et intuitifs 

?? Modulables 

}}Constructeurs 

?? Tous les constructeurs peuvent utiliser Android  ?? Un ensemble de services sont déjà disponibles dans le core 

?? API disponible pour les accès de bas niveau 

 

}}Android n’est pas un langage de programmation

}}Pour développer sous Android, il existe deux possibilités : 

?? Développement native (Java ou C)

?? Développement hybride 

}}Le SDK Android est développé en Java àà Permet de développer des applications avec un haut niveau d’abstraction 

}}Android a sa propre machine virtuelle (DVM)

}}Ne supporte pas toutes les fonctionnalités de la JRE

}}Une application Android ne peut pas s’exécuter sur une machine virtuelle Java 

}}Une application Java (native) ne peut pas s’exécuter sous Android 

}}Android dispose de sa propre machine virtuelle 


}}Il est possible d’écrire des applications Android en utilisant le langage C/C++ qui seront exécutées directement par le système d’exploitation Linux embarqué  }}Android fournit le kit de développement NDK pour les développements d’application en C/ C++ }}Utilisé dans le développement de jeux 2D/3D se basant fortement sur la librairie OpenGL 

 

}}Android supporte le développement hybride 

?? Titanium 

?? Phonegap 

?? Neomad

}}Framework et langage ?? Android SDK 

?? Java  ?? XML 

}}Outils

?? Eclipse (Intellij ou Netbeans)  ?? Le plugin ADT


 

}}Outil de développement d’application Android

}}Fournit un environnement unifié permettant de développer « facilement » des applications Android

}}Mise à jour automatique via le SDKManager

}}Prise en charge de toutes les versions d’Android

}}Plusieurs Outils et API 

?? Android xx

?? Google API xx 

?? Outils d’administration, de débogage …  

   

}}ADB : Outil en ligne de commande permettant d’administrer un terminal (virtuel, réel)  : 

?? Transférer des fichiers (push / pull)

?? Installer une application (install)

?? Connexion par sockets (forward)

}}dx :  Compilateur Android qui transforme le bytecode java en code Dalvik

}}apkbuilder : Compiler les sources d’une application Android pour constituer une archieve (.apk) directement installable sous un terminal Android

}}DDMS / Monitor : Monitoring sur les activités du terminale 

 

Compilation

ØØ? La compilation sous Android avec le plugin ADT est automatisée.

ØØ? Android SDK utilise aussi ANT pour automatiser la compilation.

ØØ? Android 2.2 Froyo intégre le compilateur JIT(Just

in Time compiler) stable.

20

   

Contraintes Mobiles

ØØ? Les contraintes de test;

ØØ? Le faible nombre d’API disponibles;

ØØ? Les limitations matériel (mémoire, espace disque,…);

ØØ? Migration;

ØØ? Performances;

ØØ? Langage propriétaires

 

ØØLes applications Android sont constitués de composants à couplage 

ØØLes composantes sont liées par un Manifest qui décrit chacun d’eux ainsi que les interactions entre elles. 

   

             1.Activities: Couche de présentation de l’application;

            2.Services: les composants qui tournent en arrière plan;

3.Content providers : Partage de contenus entre applications;

            4.Intents: Framework de communication interapplications.

5.Broadcast receivers : Consommateurs des messages diffusés par les intents.

             6.Widgets: Composant d’application visuels;

             7.Notifications:Framework de notifications aux utilisateurs;


Il existe trois catégories de projets sous Android:

qq? Application Android : Type primaire des applications Android destiné à être executé directement sur un terminal  qqTest Projects ?      : Projet de test d’une application Android 

qqLibrary project ?   : Projet de types librairies, equivalents à une API exposant certaines fonctionnalités pouvant être réutilisé par d’autres applications. 

1.Application de premier plan: c’est une application qui est utilisable uniquement lorsqu’elle est visible et mise en suspens lorqu’elle ne l’est pas;

2.Application d’arrière plan (Services): N’interagit pas avec l’utilsateur, elle s’exécute en tâche de fond. 

3.Intermittente: c’est une application qui présente une certaine interactivité mais effectue l’essentiel de sa tâche en arrière plan. Ces applications notifient l’utilisateur lorsque cela est nécessaire;

4.Widget: ces applications représentées sous forme d’un widget de l’écran d’accueil;


 

ØØChaque projet Android contient un fichier aux format XML nommé manifeste ().

ØØLe manifeste permet de définir la structure et les métadonnées d’une application, ses composants et ses prérequis.

ØØIl contient des balises pour chacun des composants qui constituent l’application (Activities, Services, Content Providers et

Broadcast Receivers)

ØØLe manifeste fournit aussi des attributs permettant de spécifier les métadonnées d’une application (Exemple son icône, son thème).

ØØIl contient également les paramètres de sécurité, les tests unitaires et la définition des prérequis matériels et de plateforme.

ØØLe fichier manifeste () se trouve à la racine du projet.


Android Manifest

Strucutre du manifeste:

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

<manifest>

    <uses-permission />

    <permission />

    <permission-tree />

    <permission-group />

    <instrumentation />

    <uses-sdk />

    <uses-configuration />  

    <uses-feature />  

    <supports-screens />

    <application>

        <activity>

            <intent-filter>

                <action />

                <category />

                <data />

            </intent-filter>

            <meta-data />

        </activity>

30

Android Manifest

Strucutre du fichier manifeste (suite):

31

Android Manifest

Le plugin ADT eclipse fournit un éditeur visuel permettant de manipuler le Manifest.

 

32

 

}}Une activité décrit les actions que peuvent effectuer un utilisateur.  Elles sont destinées à interagir avec l’utilisateur

}}Classe héritant de la classe Activity d’Android 

}}Doit être déclarée dans le Manifest pour être visible par le système

}}Ne peut être instanciée directement, cette tache se fait par le système 

 

}}L’instanciation d’une activité se fait par les

 

Activity: le cycle de vie

ØØUne bonne compréhension du cycle de vie de l’Activity permet de garantir que votre application satisfait respecte les bonnes pratiques de développement Android.

ØØL’état de chaque Activity est déterminé par sa position dans la pile des Activities:

1.     Active : Quand l’Activity est au sommet de la pile;

2.     En pause : Si l’Activity est visible sans avoir le focus;

3.     Arrêtée: Lorsque l’Activity n’est plus visible;

4.     Inactive : Quand elle est tuée ou qu’elle n’est pas

démarrée;

34

     

public class ExampleActivity extends Activity {

@Override

    public void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);

        // The activity is being created.

    } @Override

    protected void onStart() {         super.onStart();

        // The activity is about to become visible.

    } @Override

    protected void onResume() {         super.onResume();

        // The activity has become visible (it is now "resumed").

    } @Override

    protected void onPause() {         super.onPause();

        // Another activity is taking focus (this activity is about to be "paused").


 

37

èèInterface fournissant des informations

globales sur l’environnement de l’application:  èèC’est une classe abstraite implémentée par 

le système Android  èèIl permet d’accéder aux principales

ressources de l’application  èèObtenir le contexte courant d’une application

                     èèContext?      c = getApplicationContext(): Contexte

global de l’application èèContext? c = / getContext(): Contexte

d’une activité ou un service

 

Description abstraite d’une action à exécuter:  

Action :  Action à exécuter 

Data : Données sur lesquelles l’action va opérer

Exemple : Action_DIAL tel:0641xxxx

Autres attributs : 

Category : Précise la catégorie de l’activité

demandée

Type: Préciser le type de contenus des données de l’intention 

Extras : Informations additionnelles envoyées à l’action (contenu d’un email, par exemple)

 

Il existe deux principaux types d’intentions :

èèExplicite : Spécifie les composants qui

précisent la classe exacte qui doit être exécutée (setComponant (nom) ou setClass(context, class))

èèImplicite : Ne spécifie pas le composant mais fournit assez d’informations permettant au système de déterminer les composants nécessaires correspondant à cette action.

 

}}Intent i = new Intent(); 

}}Intent i = new Intent(action:String) 

}}Intent i = new Intent(action:String, uri:Uri)

}}Intent i = new Intent (context:Context, class:Class<?>)

 

}}Les intentions peuvent être utilisées pour transiter des données entre deux activités 

}}putExtra(nom:String, valeur:Object)

}}getxxxExtra(nom:String) 

}}xxx dépend du type de données: Int, String, StringArray

 

}}addCategory(category: String) 

}}setDataAndType(uri:Uri, mime:String)

 

 

Actions

–   appel téléphonique

–   affichage de données pour édition par l’utilisateur

–   activité principale d’une application

–   affichage de données

–   android.intent.action.WEB_SEARCH recherche sur le WEB

Catégories

–   android.intent.category.DEFAULT activité pouvant être lancée explicitement

–   android.intent.category.BROWSABLE peut afficher une information désignée par un lien

–   android.intent.category.LAUNCHER activité proposée au lancement par Android

–   activité associée dans un onglet d’interface (TabHost)

 

Lancer explicitement une activité Intent demarre = new Intent(context, nomActiviteALancer.class); startActivity(demarre);

Lancer implicitement une activité

–   Exemple : lancer un navigateur sur une page :

Uri chemin = Uri.parse("");

Intent naviguer = new Intent(Intent.ACTION_VIEW, chemin); startActivity(naviguer);

–   Exemple : appeler un n° de téléphone :

Uri numero = Uri.parse("tel:0123456789");

Intent appeler = new Intent(Intent.ACTION_CALL, numero); startActivity(appeler);

 

La classe Intent permet de passer des paramètres à l’activité appelée et d’en récupérer les valeurs en retour

Ajouter des paramètres (types simples ou tableaux) intent.putExtra(String, val) Le 1er paramètre est un nom (clé)

Le second paramètre est la valeur :

•   De type simple (boolean, int, short, long, float, double, char)

•   Tableau de types simples

L’activité appelée pourra récupérer ces paramètres par leur nom

 

L’activité lancée récupère l’objet de classe Bundle contenant les paramètres par : Bundle params = getIntent().getExtras()

•   Les paramètres sont récupérés dans ce Bundle par ses méthodes : – getBoolean(String)

–   getInt(String)

–   getBooleanArray(String)

–   …

Exemple :

String myId = getIntent().getStringExtra(« id»);

 

èèUne application Android n’est pas seulement fait de codes 

mais aussi de ressources statiques (images, sons, text statique,….)

èèTout projet Android a un dossier de ressources (res/) contenant les ressources du projet (bitmap, xml,…) ?? /res/drawable èè images (R.drawable.nom_de_la_ressources) ?? /res/layout èè Design des vues (R.layout.nom_de_la_vue)

?? /res/values/strings èè Chaînes de caractères, tableaux, valeurs numériques … (R.string.nom_chaine, )

?? /res/anim èèdescription d’animations (R.anim.nom_animation_) ?? /res/menus èè Menus pour l’application (R.menu.nom_menu)

?? /res/values/color èè Code de couleurs (R.color.nom_couleur) ?? …

   

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

<resources>

<string name="app_name">Mon application</string>

<string name="server_url"></ string>

<integer-array name=“codes_postaux“>

<item>64100</item>

<item>33000</item>

</integer-array>

<string-array name= “planetes“>

<item>Mercure</item>

<item>Venus</item>

</string-array>

<dimen name “taille“>55px</dimen>

</resources>

 

}}L’ensemble ressources sont modélisés par la classe « R.java »  et les sous dossiers par des classes internes  à R

}}Chaque ressource est un attribut de la classe

représentant le sous dossier dans lequel il est déclaré


}}Dans le code (java), on obtient une instance de cette classe par getResources() 

}}Principales méthodes de la classe Resources (le paramètre est un identifiant défini dans R de la forme ) :

?? boolean getBoolean(int)

?? int getInteger(int) ?? int[] getArray(int)

?? String getString(int)

?? String[] getStringArray(int)

?? int getColor(int)

?? float getDimension(int)

?? Drawable getDrawable(int)

Exemple : String titre = context.getResources().getString(R.string.ma_chaine);

Mais dans une activité on peut faire plus simplement : 

String titre = getString(R.string.ma_chaine);

Accéder aux vues :

getResources().getLayout(R.layout.nom_layout);

}}Accéder aux valeurs : 

String chaine = getResources().getString (R.string.nom_string); String[] tableau= getResources(). getStringArray(R.string.nom_array);

}}Accéder aux images : 

Drawable monImage =

getResources().getDrawable(R.drawable.nom_image)

Référencement d’une ressource dans une autre ressource. La forme générale est : "@type/identificateur" Exemple : 

@string/string_name  @drawable/icon @color/ma_couleur


Les interfaces (Layout) permettent de dessiner la vue tel qu’elle doit s’afficher à l’utilisateur. 

Il existe deux possibilités de développer des interfaces :  èèCode java  èèFichier XML 

Android recommande l’utilisation des fichiers XML pour définir les interfaces.  èèUne interface XML peut être associée à une

activité (vue) grâce à la méthode setContentView (identifiant) 

Exemple : setContentView(R.layout.login);

ØØActivity = Ecran Android (GUI). Il représente les fenêtres ou les écrans affichés. Une Activity contient des views.

ØØView = composant graphique (Widget). C’est la classe de base, tous les contrôles d’interface sont dérivés de View.

ØØView Group : c’est une extension de la classe View. Il contient plusieurs Views enfants. Son extension permet de :

            1.Créer?                        des contrôles composites interconnectées;

2.Fournir?  les gestionnaires de layouts pour disposer les contrôles dans une Activities;

 

Identifiant : android:id="@+id/mon_ident"

android:layout_height, android:layout_width : fill_parent / match_parent / wrap_content 

fill_parent : Remplit toute la place du parent  wrap_content : remplit la place que nécessite le contenu

match_parent : remplit la place qui reste dans

le parent 

android:background: "@color/blue/#000FFFF"  android:visibility  : visible / invisible/gone 


 

Marges internes android:layout_paddingBottom , android:layout_paddingLeft , android:layout_paddingRight ,  

android:layout_paddingTop

Marges externes  android:layout_marginBottom , android:layout_marginLeft , android:layout_marginRight , android:layout_marginTop

 

Ce sont des vues permettant de définir une prédisposition pour d’autres vues qu’ils contiennent: 

-  FrameLayout

-  AbsoluteLayout

-  LinearLayout

-  TableLayout

-? RelativeLayout

 

-? LinearLayout: dispose les éléments de façon linéaire (vertical ou horizontal) -? RelativeLayout: Dispose les vues enfants les uns par rapport aux autres -? TableLayout: disposition matricielle (ref:table HTML)


üüLes interfaces sont définies généralement

dans des fichiers XML (cela nous évite d’avoir à créer des instances explicitement) üüADT génère automatiquement une

ressource correspondant à l’interface dans le fichier R.java  ( ! R.layout.accueil)

üüUne interface peut être associée comme vue graphique à une activité. 

public    class    MainActivity extends     Activity    {    

    @Override   

    protected     void onCreate(Bundle    savedInstanceState)    {     

           super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_accueil);   

    }    

}     

Les interfaces peuvent êtres récupérées et modifiées dynamiquement. 

    LinearLayout l    =    (LinearLayout)findViewById(R.id.id_accueil); l.setBackgroundColor(Color.BLACK);      


Réutilisation d’interfaces : Une interface peut inclure une autre interface 

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

 <LinearLayout     xmlns:android=";    

                  android:layout_width="fill_parent"     

                     android:layout_height="fill_parent"    

                     android:orientation="vertical"     >   

                     <include      

                                         android:id="@+id/include01"   

                                         android:layout_width="wrap_content"     

                                         android:layout_height="wrap_content"    

                                         layout="@layout/acceuil"      >    

                     </include>    

</LinearLayout>         

Définit le positionnement linéaire (horizontall ou vertical) des vues filles 

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

<LinearLayout xmlns:android=" android"     

                   android:layout_width="match_parent"

                   android:layout_height="match_parent"

                   android:orientation="vertical" >   

                   <TextView

                                       android:id="@+id/textView1"

                                       android:layout_width="wrap_content"

                                       android:layout_height="wrap_content"

                                       android:text="@string/label_nom"

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

                   <EditText

                                       android:id="@+id/editText1"

                                       android:layout_width="match_parent"

                                       android:layout_height="wrap_content"

                                       android:ems="10"

                                       android:inputType="textPersonName" >   

                                       <requestFocus />      

                   </EditText>

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

<LinearLayout xmlns:android=" android"     

                   android:layout_width="match_parent"

                   android:layout_height="match_parent"

                   android:orientation=« horizontal"    >       

                   <TextView

                                       android:id="@+id/textView1"

                                       android:layout_width="wrap_content"

                                       android:layout_height="wrap_content"

                                       android:text="@string/label_nom"

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

                   <EditText

                                       android:id="@+id/editText1"

                                       android:layout_width="match_parent"

                                       android:layout_height="wrap_content"

                                       android:ems="10"

                                       android:inputType="textPersonName" >    

                                       <requestFocus />      

                   </EditText>

</LinearLayout>

Positionner les éléments de  l’interface  les uns par rapport aux autres

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

<RelativeLayout xmlns:android=";

                   android:layout_width="match_parent"                   android:layout_height="match_parent"



                   android:orientation=« horizontal"    >       

                   <TextView

                                       android:id="@+id/textView1"

                                       android:layout_width="wrap_content"                                        android:layout_height="wrap_content"

                                       android:text="@string/label_nom"

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

                   <EditText

                                       android:id="@+id/editText1"

                                       android:layout_width="match_parent"

                                       android:layout_height="wrap_content"

                                       android:ems="10«      

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

 

èèTableau de positionnement des vues en ligne

de TableRow (similaire au <table> <tr>

<td> de HTML)

èèTableRow hérite de LinearLayout avec

alignement automatique des colonnes sur chaque ligne

èèPropriétés de TableRow.LayoutParams

?? layout_column: indice de départ de la colonne

(à partir de 0)

?? layout_span: nombre de colonnes occupées

§§? TextView : pour les labels texte;

§§? EditText : Champ de saisie;

§§? ListView : Liste de vues horizontales;

§§? Button : bouton standard;

§§? CheckBox : case à cocher;

§§? Spinner : Liste déroulante 

§§? ImageView : image 

§§? RadioButton : radio (choix exclusif)

§§? TimePicker : Choix de date 

§§? ProgressBar : Bar de progression

Une vue peut être déclarée dans un fichier

   

Identifiant        de        la               vue     

XML 

<TextView   

android:id="@+id/le_texte"     android:layout_width="wrap_content"    android:layout_height="wrap_content"      android:text="@string/hello"      

Texte à          afficher          référencé      dans       les       ressources

android:layout_gravity="center"   

/>           

Alignement       de la         vue      dans    le         gabarit          

Une vue peut être aussi créée

dynamiquement 

public    class    Activity2 extends      Activity     {   

         public       void onCreate(Bundle      savedInstanceState)       {   

          super.onCreate(savedInstanceState);     

        LinearLayout                      gabarit      =    new LinearLayout(this);                    

              gabarit.setGravity(Gravity.CENTER);      // centrer      les     éléments     graphiques    

               gabarit.setOrientation(LinearLayout.VERTICAL);    // disposi-­tion    horizontal       !   

        TextView    texte    = new     TextView(this);     

        texte.setText("Programming creation       of      interface                              !");    

           gabarit.addView(texte);     

           setContentView(gabarit);     

         }   

    }    

Les instances de vues déclarées dans les fichiers XML sont créées automatiquement par le système et peuvent être récupérées dans le code Java. 

View    v    = findViewById(R.id.myView);     

Sachant le type de la vue 

   Button    b    =   

(Button)findViewById(R.id.btnCancel);         

Il est possible d’accéder aux propriétés des widgets en lecture et/ou en écriture 

                  EditText edit    =    (EditText)findViewById(R.id.nom);          

                  //On y    met     une     valeur       en      dure           

  edit.setText("Voici    ta    nouvelle valeur");     

  //on    y    met     une      valeur dans    les     ressources                                  

edit.setText(R.string.hello_world);        

  //On    récupère    le      contenue      

                                              edit.getText();     

Les évènements permettent de gérer les actions utilisateurs sur les vues: 

Pour gérer les évènements sur les vues, il suffit d’ajouter un écouteur 

button.setOnClickListener(new View.OnClickListener()        

@Override     

publicvoid    onClick(DialogInterface dialog,    int     which)     {      

//     Du      code    ici    

}     

});   

edit.addTextChangedListener(new TextWatcher()      {     

@Override    

publicvoid onTextChanged(CharSequence    s,      int   start,     int    before,    int    count)    {

//    do     something here   

}     

);    

 

Il    est    possible    de valider    le     contenu    

des     champs    d’un formulaire   

TextUtils.isDigitsOnly(edit.getText()); 

TextUtils.isEmpty(edit.getText());


 

75


 

Les     groupes     sont    des vues    permettant     de     définir    un    pattern     d’affichage    pour les    collections    d’objets    :         

Ils     permettent     de faire    des    choix     sur    un     ensemble     d’éléments     :         

-  ListView

-  Gridview

-  RadioGroupe

-  Galery

-? Spinner 

 

Les      groupes    utilisent     des      adapters pour     insérer    automatiquement     les      objets     (Java)      comme item     dans     la    liste.            

La    source     de    données    est      une liste    d’objets    pouvant    provenir    :           

}}? D’une     base de    données    locale            

}}? D’un service    web            

}}? D’une collection    statique   

}}? ….    

Les      collections    peuvent    être:       

}}? De     type simple     :     String,    Double,    Integer,    …    

}}? De     type complexe    :     Instance    de    classe     java     Les    groupes utilisent     des      adapters    pour     insérer    automatiquement     les objets     (Java)      comme    item     dans     la    liste.            

La    source     de    données    est      une liste    d’objets    pouvant    provenir    :           

}}? D’une     base de    données    locale            

}}? D’un      service web            

}}? D’une collection    statique   

}}? ….    

Les      collections    peuvent    être:       

}}? De     type simple     :     String,    Double,    Integer,    …    

}}? De     type complexe    :     Instance    de   classe     java    

Les adapters peuvent être considérés comme un pont entre une source de données et une vue de groupe. 

Ils fournissent les accès aux éléments de la source de données 

Ils sont aussi responsables de générer des vues pour chaque élément d’un groupe 


Il existe trois type d’adapter sous Android : 

}}? ArrayAdapter         

}}? CursorAdapter      

}}? SimpleCursorAdapter

Android    propose     des    implémentations génériques    pour    chacun    de     ces    types    

Peuvent    être    étendus     en     fonction des    besoins     de    l’application         

 

Adapter   concret    s’appuyant sur    une     liste      d’objets     arbitraires.         

Par     défaut     Android utilise    un    textview     pour    afficher     le    contenu    de chaque     Objet         

Vous    pouvez     passer     la référence     à    un   

Textview      que     vous    avez défini          

Chaque     objet      est représenté    par     sa    représentation     (toString())   

 

L’affichage    peut    être personnalisé    :         

ImageView         

EditText    

ListView          

…   

Il    faut    redéfinir    pour cela    surcharger     la     méthode    getView     de     la     classe         


<string-array name="country_arrays"> <item>Malaysia</item> 

<item>United States</item> <item>Indonesia</item> <item>France</item> <item>Italy</item> <item>Singapore</ item> 

<item>New Zealand</item> <item>India</item> 

</string-array>  

 </resources>

Layout

<Spinner android:id="@+id/spinner1" android:layout_width="match_parent"

android:layout_height="wrap_content" android:entries="@array/ country_arrays" android:prompt="@string/country_prompt" />

Spinner sp = (Spinner)

         findViewById(R.id.spinner1);       

         ArrayAdapter<String> dataAdapter = new

ArrayAdapter<String>(this,

android.R.layout.simple_spinner_item,

R.array-string. country_arrays);         dataAdapter.setDropDownViewResource(android.

R.layout.simple_spinner_dropdown_item);  

sp.setAdapter(dataAdapter );          

public class CategorieAdapter extends BaseAdapter {                

    private Context mContext;        

    List<Categorie> categories;                   

     public CategorieAdapter(Context c, List<Categorie> categories) {                

mContext = c;                     this.categories = categories;        

    }                  

             // create a new ImageView for each item referenced by the Adapter   

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

        LayoutInflater inflater = (LayoutInflater) mContext         

                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);        

            View gridView;               

            Categorie c = categories.get(position);                

            if (convertView == null) {                 

                gridView = new View(mContext);             

// get layout       

                gridView = inflater.inflate(R.layout.line_categorie, null);   

// set value into textview       

                TextView nom = (TextView) gridView   

                        .findViewById(R.id.nom);        

                TextView desc = (TextView) gridView                

                        .findViewById(R.id.desc);     

nom.setText(c.getNom());                             desc.setText(c.getDescription());             


}}Une listview est une vue de groupe qui peut afficher des éléments sous forme d’une liste déroulante horizontale 

}}Une listview utilise un Adapter pour remplir son contenu en fonction de la collection d’objets qui lui est fournie 

 

<RelativeLayout xmlns:android=";

              xmlns:tools=";

              android:id="@+id/id_accueil"

              android:layout_width="match_parent"

              android:layout_height="match_parent">

                  <ListView

                              android:id="@+id/listView1"

                              android:layout_width="match_parent"  

                              android:layout_height="wrap_content"

                              android:layout_alignParentLeft="true"

                              android:layout_alignParentTop="true"

                              android:layout_marginTop="16dp" >                   </ListView>

}}SimpleAdapter 

ListView lst = (ListView) findViewById(R.id.listview1);    

ArrayAdapter<Categorie> dataAdapter = new

ArrayAdapter<Categorie>(this, android.R.layout.simple_spinner_item, categories);  lst.setAdapter(dataAdapter );

}}Adater personnalisé

CategorieAdapter myAdaptor = new CategorieAdapter(context, categories); 

Lst.setAdapter(myAdaptor )

}}La déclaration d’une listview peut être omise en utilisatant une ListActivity 

public class ListViewLoader extends ListActivity

{

@Override?

    protected void onCreate(Bundle savedInstanceState) {?

        super.onCreate(savedInstanceState);?

        // Create a progress bar to display while the list loads?

        ProgressBar progressBar = new ProgressBar(this);?

        progressBar.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,?

                LayoutParams.WRAP_CONTENT, Gravity.CENTER));?

        progressBar.setIndeterminate(true);?

        getListView().setEmptyView(progressBar);

     ArrayAdapter<Categorie> dataAdapter = new ArrayAdapter<Categorie>(this, android.R.layout.simple_spinner_item, categories); ?

        // Must add the progress bar to the root of the layout?

        ViewGroup root = (ViewGroup) findViewById(.content);?        root.addView(progressBar);

        setListAdapter(dataAdapter );?

    }

}


}}Une gridview est une vue de groupe disposant des éléments déroulantes de manière bi dimensionnel dans une interface

}}Une gridview utilise des adapters pour remplir son contenu en fonction de la collection d’objets qui lui est fournie. 

 

Une griview peut être utilisée comme racine d’une interface

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

<GridView xmlns:android="; ?

android:id="@+id/gridview"?

android:layout_width="fill_parent" ?

android:layout_height="fill_parent"?    android:columnWidth="90dp"?

android:numColumns="auto_fit"?    android:verticalSpacing="10dp"?

android:horizontalSpacing="10dp"?

android:stretchMode="columnWidth"?

android:gravity="center"?

/>

Peut être utilisée comme sous vue d’un gabarit

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

<RelativeLayout    xmlns:android=";

                  xmlns:tools=";

                  android:id="@+id/id_accueil"

                  android:layout_width="match_parent"

                  android:layout_height="match_parent">

<GridView xmlns:android="; ?

android:id="@+id/gridview"?

android:layout_width="fill_parent" ?

android:layout_height="fill_parent"?

    android:columnWidth="90dp"? Duplique l’importation       android:numColumns="auto_fit"? de l’espace de nom

android:verticalSpacingandroid:horizontalSpacing="10dp"="10dp"?      ? android sous la même         android:stretchModeandroid:gravity="center"="columnWidth? "?        référence!  />

</RelativeLayout>

}}SimpleAdapter 

GridView grd = (GridView) findViewById(R.id.gridview1);    

ArrayAdapter<Categorie> dataAdapter = new

ArrayAdapter<Categorie>(this, android.R.layout.simple_spinner_item, categories);  grd.setAdapter(dataAdapter );

}}Adater personnalisé

CategorieAdapter myAdaptor = new CategorieAdapter(context, categories); grd.setAdapter(myAdaptor )


 

Les groupes permettent la gestion d’évènement sur les éléments qu’ils contiennent 

gridview.setOnItemClickListener(new OnItemClickListener()    {   

                              publicvoid onItemClick(AdapterView<?>    parent,      View     v,       int    position,    long     id)      {

                                          // Ce       qui    se       passe    quand    on       clique      sur      un élément         

                              }   

              });     

gridview.setOnLongClickListener(new OnLongClickListener()    {   

@Override      

publicboolean onLongClick(View      v)       {   

//Ce    qui      se       passe quand    on       reste    appuyé      sur      un       élément         

}     

});

 

}}Elles renseignent le système sur les besoins de l’application en terme de ressources sur le terminal; 

}}Mécanisme de sécurité permettant au système de garantir la transparence sur les données de l’utilisateur 

}}Elles apparaissent dans le fichier Android Manifest et sont visibles par l’utilisateur au moment de l’installation de l’application 

                }}Exemple:"

–  Capteurs (GPS, NFC, Bluetooth,…)"

–  Les accès aux contacts et à l'agenda du téléphone"

–  Les modifications de paramètres (orientation, fond d’écran …)"

–  Les appels téléphoniques" –Le réseau (dont l’accès à Internet)" – Le matériel (Caméra, …)

 

La déclaration des permissions doit se faire explicitement dans le fichier manifest. 

<uses-permission

android:name="android.permission.CALL_PHONE" />

<uses-permission

android:name="android.permission.INTERNET " />

Si une permission a été omise et vous essayez d’utiliser la ressource correspondante, vous aurez une erreur à l’exécution! 

Les permissions peuvent être ajoutées en utilisant l’outil graphique d’édition du Manifest fourni par ADT


 

}}Android fournit des mécanismes permettant aux applications d’utiliser la connectivité pour accomplir certaines taches : 

?? Internet (WIFI, 3G,…) 

?? Bluetooth 

?? NFC 

}}Pour accéder à ces ressources, il est obligatoire de demander explicitement la permission associée 

 

}}Une application Android peut utiliser la connexion réseau du téléphone pour échanger par HTTP des informations avec une application distante (web service, web application,..)

}}Permission pour utiliser internet : 

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

}}Android utilise la bibliothèque Apache Components pour les communications par http 

HttpClient client     =new    DefaultHttpClient();           

HttpGet request    =new    HttpGet(url);         

HttpResponse    response    =       client.execute(request);     

…     

Réf    :         

}}La UIThread est le thread principal de gestion de l’interface utilisateur. L’exécution des processus longs dans ce thread comme l’accès au réseau doit se faire dans un thread secondaire.  

}}Android génère une exception pour tout opération longue s’exécutant dans le thread principal. 

}}L’exécution des tâches asynchrones peut se faire de deux manières: 

?? L’utilisateur crée explicitement un thread auquel il délègue l’exécution des processus longs 

?? Utiliser la classe AsyncTask du SDK qui se chargera de la création du thread secondaire

protectedclass    LongTask extends       AsyncTask<String,        Void,    Void> {

                                         @Override

                                         protectedvoid     onPreExecute() {   

                                                             super.onPreExecute();

                                                        //Avant l'execution    du        processus     long     (Thread       principal)

                                         }   

                                         @Override

                                         protectedvoid onPostExecute(Void       resp)    {   

                                                             super.onPostExecute(resp);

                                                             //Apres l'execution    du        processus     long     (Thread       principal)

                                         }

   @Override   

   protected    Void doInBackground(String    arg0)       {   

            //Execution                                   du processus     long    (Thread                          secondaire)       

                                   returnnull;   



 

}}Le SDK offre au développeur la possibilité d’ajouter les fonctionnalités liées à la géolocalisation dans leurs applications. 

?? Position géographique de l’utilisateur 

?? Places 

?? Géocodage (Geocoding, Reverse Geocoding)

}}Android.location : Package contenant un ensemble de classes et d’interfaces supportant la gélocalisation : 

}}Interfaces :GpsStatus.Listener, LocationListener 

}}Classes: Address, Criteria, Geocoder, Location, LocationManager, LocationProvider

}}Deux possibilités  

?? GPS

?? NETWORK (WIFI, 3G)

}}Permissions :          

<uses-­?permission

android:name="android.permission.ACCESS_COARSE_

LOCATION"    />

<uses-­?permission



android:name="android.permission.ACCESS_FINE_LO

CATION"                      />


LocationListener:

}}Interface vous permettant d’abonner aux évènements de géolocalisation 

?? Détection d’une nouvelle position 

?? Changement de statut du fournisseur (activation, désactivation,…

}}Disposer d’une classe implémentant cette interface 

1.   Vous créez une nouvelle classe

2.   Votre activité implémente cette interface 

class MyListener implements public class HomeActivity LocationListener{   extends Activity implements

……                                        LocationListener {

//Implémenter les méthodes                       …..

}                                                                                           }

LocationManager : 

}}dispose d’APIS vous permettant d’accéder au service de location du terminal 

}}Ne peut être instanciée directement (comme c’est le cas pour la plupart des services système Android) 

}}Une instance est obtenue par l’appel à la méthodes getSystemService (Context.Location_Service) qui retourne une instance de LocationManager

}}lm = (LocationManager) this.getSystemService(LOCATION_SERVICE); Demandez la position courante de l’utilisateur : 

if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER))  lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 0, locationListener);  else  lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 0, locationListener);

}}Quand une nouvelle position est disponible, le système appelle la méthode onLocationChanged du Listener 

@Override public void onLocationChanged(Location location)

{ // TODO Auto-generated method stub Toast.makeText(this, "My

Location " + location.getLongitude(),

Toast.LENGTH_LONG).show(); }


Address

Permettant de représenter une adresse (rue, ville, code postal,….) 

}}Geocoder : Convertit une positon GPS en adresse et reciproquement 

Geocoder geocoder = new Geocoder(context, Locale.getDefault());

List<Address> addresses = geocoder.getFromLocation(loc.getLatitude(),?

loc.getLongitude(), 1);

}}Bonne pratique 

?? Lancer les requêtes  de mises à jour de la position dans onResume 

?? Stopper les demandes de mises à jour quand l’activité n’est plus visible (onPause, onStop)

?? Faites le géocodage dans un thread secondaire car cette opération est déléguée par la suite aux serveurs de Google

Android supporte également les fonctionnalités de Google Maps et met à disposition des développeurs un ensemble d’APIs permettant d’ajouter des fonctionnalités liées à ce service à leurs applications 

?? Afficher la MAPS ??? MapsView

??? Markers

}}Ces fonctionnalités sont disponibles via Google Play Library 

}}L’utilisation de Google MAPS nécessite d’ajouter une référence à cette librairie à votre projet èè Ces fonctionnalités ne sont pas natives dans le SDK, ce sont des services de Google 

Permissions

<permission android:name=« .permission.MAPS_RECEIVE" android:protectionLevel="signature" />

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

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

<uses-permission

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

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

}}Capacité du terminal  :

<uses-feature android:glEsVersion="0x00020000" android:required="true" />

}}Metadonnées de l’activité : 

<meta-data android:name=" (2,3).API_KEY"   android:value="your_apikey" />

Android offre plusieurs possibilités de persistance de données : 

?? Système de fichiers (xml, .txt, doc, …)

?? Préférences

?? SQLite 


SQLite est une base de données relationnelles disponible sur tous les terminaux Android et le SDK fournit des API permettant au développeur de créer/gérer sa base de données privées. 

}}Une application peut disposer de plusieurs bases de données (il n’y a pas de limitation à priori) . 

Toutes les bases de données sont sauvegardées sous : 

?? /data/data/<package_name>/databases

}}Le SDK dispose d’un outil permettant de manipuler les bases de données du téléphone via une fenêtre de commande 

?? tools/sql3

Les types de données supportées : 

         ??    INTEGER  : Valeur entière signée sur 1 à 8 bytes 

         ??    REAL : Valeur flottante 

         ??    TEXT : Chaine de caractère formatée (UTF-8, UTF-16BE or UTF-16LE)

         ??    NUMERIC: données blob stockées comme elle a été entrée

         ??    NONE : Type non précisé

}}SQLite propose un tableau d’affinité permettant de mapper un type de données dans les langages avancés à l’un des types supportés dans le framework. 

}}INT , INTEGER, TINYINT, SMALLINT, MEDIUMINT, BIGINT,

UNSIGNED BIG INT, INT2, INT8 èèINTEGER 

CHARACTER(20) , VARCHAR(255), VARYING CHARACTER(255),

NCHAR(55), NATIVE CHARACTER(70), NVARCHAR(100), TEXT,

CLOB èèTEXT  èè…..

}}L’application embarque les commandes nécessaires pour la manipulation de la base de données : création, suppression,…. 

}}Le développeur se doit de créer les scripts de création de la base de données et les intégrer à l’application au moment de la compilation. 

}}

}}La base de donnée est automatiquement créée par le système qui dispose d’un mécanisme permettant de vérifier l’état de la base. 

}}Lors du premier appel à la base, si celle-ci n’existe pas le système exécutera alors les scripts de création des tables. 

}}La base de données n’est pas créée tant qu’on y fait pas référence 

}}La base de données est générée au runtime 


}}Syntax SQL 

CREATE TABLE categorie( nom TEXT, description TEXT,  id INTEGER PRIMARY KEY AUTOINCREMENT,);

}}insert into categorie values ("Mathématique", "Livre de mathématiques");

}}update categorie set description="Description des livres de Mathématiques" where nom like

%théma%;

}}Packages  

android.database : Encapsule les classes nécessaires pour travailler avec les bases de données 

android.database.sqlite : Classes pour les fonctionnalités liées à SQLite 

}}Manipuler la base de données  

SQLiteOpenHelper permet de manipuler les bases de données SQLite : création, évolution… onCreate() :  à la création de la base 

onUpgrade() : Evolution de la base 

}}SQLiteOpenHelper est appelé à chaque requête d’accès à la base, elle est chargée de la création et de la mise à jour de la BD. 

}}Créer une classe qui implémente SQLiteOpenHelper afin d’indiquer au système la structure de la base de données de l’application. 

public class myDB extends SQLiteOpenHelper {  public myDB(Context context, String name, CursorFactory factory, int version)  { super(context, name, factory, version); 

// TODO Auto-generated constructor stub } 

@Override public void onCreate(SQLiteDatabase db) {  //Script de Création de la base 

}  @Override  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 

{ 

// Script de ise à jour de la base 

}}SQLiteDatabase : Classe permettant de manipuler une base de données SQLite sous Android.  Elle dispose d’un ensemble de  méthodes  permettant d’accéder à la base en lecture et en écriture: 

?? Open() : Ouvrir la base de données en lecture ou en écriture 

?? Query() : Pour exécuter des requêtes SQL 

?? Update () : Fermer dla base 

?? Close() : Fermer une connection à la base 

}}Plus spécifiquement elle propose des méthodes génériques pour les requêtes CRUD : Create, read, update, delete.

}}En addition elle propose execSQL permettant d’exécuter des requêtes SQL natives. 


Création d’une table dans la base de données

@Override 

public void onCreate(SQLiteDatabase db) 

{

 String script = "CREATE TABLE categorie( "

 + " nom TEXT, " + 

 "description TEXT" + 

 "id INTEGER PRIMARY KEY AUTOINCREMENT);";  db.execSQL(script); 

}

}}Accéder à la base : 

}}Ouvrir la base de données en écriture  SQLiteDatabase db = db.getWritableDatabase();

}}Ouvrir la base de données en lecture  SQLiteDatabase db = db.getReadableDatabase();

}}Ajouter un nouvel objet dans la base de données

?? Utiliser les requêtes natives SQL 

?? Utiliser les méthodes génériques de la classe SQLDatabase 

}}Les méthodes génériques permettent d’effectuer les requêtes CRUD plus simplement. 

ContentValues ct = new ContentValues(); Categorie c = new Categorie(); c.description = "Description of categorie"; c.nom = "Mathématiques";  ct.put("nom", c.description);  ct.put("nom", c.nom); 

db.insert("categorie", null, ct);  

Forcer une colonne à      HashMap contenant recevoir une valeur    les colonnes de la nulle      table et leur valeurs

ContentValues

}}Classe de type HashMap permettant de passer les valeurs à insérer dans la base de données aux méthodes génériques 

}}Les clefs sont les noms des colonnes des tables telles qu’elles ont été nommées à la création de la table 

}}Les valeurs sont les valeurs à insérer pour chaque colonne 


Requêtes natives SQL 

}}myBase.execSQL("insert into categorie values (" + c.nom + ", " + c.description

+ "");

}}myBase.execSQL("insert into categorie values ( ?, ?", new String[] {c.nom, c.description});

}}myBase.execSQL("delete from categorie");

}}myBase.execSQL("delete from categorie where id=?", new Integer[] {18}); Curseur « SQLiteCursor »

}}Un curseur est une classe permettant d’exposer les réponses d’une requête SQLite en Android. 

}}Les curseurs peuvent être considérés comme des ResultSet 

}}Utilisés dans les requêtes de lecture sur la base

}}Cursor est une classe dérivée de SQLCursor exposant les des méthodes permettant de manipuler plus simplement les curseurs Cursor cursor = myBase.query("categorie", null, null, null, null, null, null);

}}Renvoie toutes les lignes et toutes les colonnes de la table 

}}Ouverture explicite 

}}Parcourir le curseur : 

Cursor cursor = myBase.query("categorie", null, null, null, null, null, null);  while (cursor.moveToNext()){  nom = cursor.getString(cursor.getColumnIndex("nom")); description = cursor.getString(cursor.getColumnIndex("description")); 

.. 

}  


Obtenir le nombre de lignes dans un curseur : 

 cursor.getCount();

}}Obtenir le nombre de colonnes : 

 cursor.getColumnCount();

}}Se deplacer dans un curseur 

(-­?1);     //remonter    d’un niveau    (2);        //Descendre     de    deux      niveaux     

}}? Fermer     le cursor    :        

cursor.close();

Bonnes pratiques 

?? Utiliser une classe statique dans laquelle vous déclarerez le nom de la base de données, des tables ainsi que les colonnes des tables.  Ce qui vous permettra de vous embrouiller dans les noms des tables ainsi que les colonnes. 

?? N’oubliez jamais de fermer la base de données après chaque utilisation 

?? Toujours fermer les curseurs  

?? Vérifiez toujours qu’un curseur a au moins une ligne avant de  le parcourir. 

?? Evitez d’accéder à la base de données dans le thread principal de l’application 

Vous pouvez utiliser les curseurs pour créer des adaptateurs pour les vues de groupes

public class CategorieAdapter extends CursorAdapter {  public CategorieAdapter(Context context, Cursor c, boolean autoRequery)

{     super(context, c, autoRequery); 

}  @Override public void bindView(View view, Context context, Cursor cursor) 

{ 

//Les informations à ajouter dans la vue du groupe 

} 

 @Override public View newView(Context context, Cursor cursor, ViewGroup parent)  { 


Vous pouvez utiliser les curseurs pour créer des adaptateurs pour les vues de groupes

@Override  public void bindView(View view, Context context, Cursor cursor) 

{ 

TextView textViewPersonName = (TextView) view.findViewById(R.id.nom); textViewPersonName.setText(cursor.getString(cursor.getColumnIndex("nom"))); 

TextView textViewPersonPIN = (TextView) view.findViewById(R.id.description); textViewPersonPIN.setText(cursor.getString(cursor.getColumnIndex("description"))); 

} 

@Override  public View newView(Context context, Cursor cursor, ViewGroup parent) {  // TODO Auto-generated method stub 

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

View retView = inflater .inflate(R.layout.line_categorie, parent, false);  return retView; 

Vous pouvez utiliser les curseurs pour créer des adaptateurs pour les vues de groupes

@Override  public void bindView(View view, Context context, Cursor cursor) 

{ 

TextView textViewPersonName = (TextView) view.findViewById(R.id.nom); textViewPersonName.setText(cursor.getString(cursor.getColumnIndex("nom"))); 

TextView textViewPersonPIN = (TextView) view.findViewById(R.id.description); textViewPersonPIN.setText(cursor.getString(cursor.getColumnIndex("description"))); 

} 

@Override  public View newView(Context context, Cursor cursor, ViewGroup parent) {  // TODO Auto-generated method stub 

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

View retView = inflater .inflate(R.layout.line_categorie, parent, false);  return retView; 

Adaptateur générique permettant de mapper les colonnes d’un curseur à des vues puis les attacher à une vue de groupe 

SimpleCursorAdapter adapter = new SimpleCursorAdapter(

HomeActivity.this, R.layout.line_categorie,  cursor, new String[] { "nom", "description" },  new int[] { R.id.nom, R.id.description}); setListAdapter(adapter );

èèCette méthode est dépréciée à partir de l’API 11 car s’exécutant dans le thread principal 

èèPour un projet avec une version minimum 11, utilisez : 

SimpleCursorAdapter adapter = new SimpleCursorAdapter(

HomeActivity.this, R.layout.line_categorie,  cursor, new String[] { "nom", "description" },  new int[] { R.id.nom, R.id.description}, 1);


Un service est une composante d’une application ne nécessitant pas d’interaction avec les utilisateurs et dans lequel une application peut effectuer des processus longs de manière transparente pour l’utilisateur final. 

}}Un service doit être déclaré dans le Manifest du projet en utilisant la balise <service> 

}}Un service n’est pas un processus séparé, il s’exécute dans le contexte de l’application 

}}Un service n’est pas un thread 

Il existe deux façons de démarrer un service 

?? Le client appelle la méthode startService auquel cas le système récupère le service en question et appelle sa méthode onCreate si nécessaire sinon il appelle la méthode onStartCommand.  Le service s ’exécute tant qu’il ne s’arrête lui-même (stopSelf()) ou le client ne l’arrête (Context.stopService()). 

?? On peut aussi obtenir une connection persistante à un service en appelant sa méthode Context.bindService(), auquel cas le système récupère le service et renvoie un objet IBinder au client.  Par cette approche, le service est démarré mais le système n’appelle pas la méthode onStartCommand().   Le service tourne tant qu’il existe au moins une connexion. 

public class MyService extends Service 

{  public MyService() 

{  }  private final IBinder mBinder = new LocalBinder();  public class LocalBinder extends Binder { MyService getService() {  return MyService.this; } 

} 

@Override public IBinder onBind(Intent intent) 

{  return mBinder; 

} @Override  public void onCreate() {  //Nous faisons notre travail ici }  @Override public int onStartCommand(Intent intent, int flags, int startId) {  return START_STICKY; }

 }

Démarrer le service en mode interactif : 

private MyService mBoundService;  private ServiceConnection mConnection = new ServiceConnection() 

{ 

public void onServiceConnected(ComponentName className, IBinder service) {

 }  public void onServiceDisconnected(ComponentName className) { 

} };  void doBindService() { }  void doUnbindService() { } 

@Override  protected void onDestroy() { }

}


Démarrer le service sans maintenir une connexion :  

Intent i = new Intent(this, MyService.class); startService(i);

Dans ce cas, le système démarre le service s’il n’a pas encore été démarré

Les notifications sont des mécanismes permettant d’alerter l’utilisateur sur des évènements s’effectuant en tâche de fond. 

}}Elles apparaissent dans la barre de taches et peuvent être de trois types:  

?? Une icone persistante dans la barre de statut et accessible via le lanceur (the launcher)! Quand l’utilisateur le sélectionne une intention peut être déclenchée 

?? Clignote les LEDs de notifications 

?? Alerter l’utilisateur en allumant son écran, jouer une sonnerie ou vibrer le terminal 

Créer une notification 

}}Méthode dépréciée à partir de l’API 11

private void showNotification() {?

// In this sample, we'll use the same text for the ticker and the expanded notification?        CharSequence text = getText(R.string.notif_message);?

// Set the icon, scrolling text and timestamp?

        Notification notification = new Notification(R.drawable.my_icon, text,?                System.currentTimeMillis());?

// The PendingIntent to launch our activity if the user selects this notification?

PendingIntent contentIntent = PendingIntent.getActivity(this, 0,?                new Intent(this, LocalServiceActivities.Controller.class), 0);?

// Set the info for the views that show in the notification panel.?

notification.setLatestEventInfo(this, getText(R.string.notif_mesage),?                       text, contentIntent);?

        // Send the notification.?

        manager.notify(NOTIFICATION, notification);?    }


Créer une notification 

}}Nouvelle approche

Notification notif = new

Notification.Builder(this) .setContentTitle(getString (R.string.app_name)) .setContentText(getString(R.stri ng.app_name)) .setSmallIcon(R.drawable.ic_launcher) 

.build();

Les notificationManagers sont utilisés pour gérer les notifications : 

}}Afficher une notification 

}}Enlever une notification dans la barre des statuts 

NotificationManager manager = (NotificationManager)getSystemService(NOTIFICATION_SE

RVICE);  manager.notify(CODE, notif);  manager.cancel(0);?



12