Post on 08-Oct-2020
APPLICATIONSJAVA
AndroidPartie V
Ivan MADJAROV - 2016
IntentBroadcastServiceAsyncTaskSQLite
Interface graphique avec XML IvMad, 2011-2016 2
L'objectif principal de ce cours est de découvrir la programmation sousAndroid, sa plate-forme de développement et les spécificités du développementembarqué sur smartphone et tablette.
Android et XML : Intent (1)• Intent : Le sandboxing (bac à sable) est une sécurité dans la téléphonie
mobile pour interagir avec les composants internes et externes àl'application.
• Android exécute une application en limitant les actions autorisées(accès mémoire, accès sur les capteurs, etc…).
• Pour contourner cette difficulté de communication entre applicationson utilise les Intent (Intentions).
• Un Intent permet d’envoyer et recevoir des messages (avec ou sans lesdonnées) pour déclencher une action, dans un composant d’une mêmeapplication (Activity) voir même dans une autre application.
• Android support deux types d'Intent : explicit et implicit.• Si l'activité définie le composant cible directement dans l'Intent (implicite);• Si l'activité lance une classe externe alors c'est un explicite Intent.
Interface graphique avec XML IvMad, 2011-2016 3
Android et XML : Intent (2)Interface graphique avec XML IvMad, 2011-2016 4
La figure illustre la manière dont un Intent implicite est délivré à travers lesystème pour démarrer une autre activité. L'activité A crée un Intent parstartActivity(). Le système Android cherche les applications dont l'Intent filtercorrespond. Si une correspondance est trouvée le système démarre l'activitéB en appelant la méthode onCreate().
Android et XML : Intent (3)• Une utilisation simple des Intents est de passer par un bouton pour
activer le navigateur Internet avec une adresse de page Web.
Interface graphique avec XML IvMad, 2011-2016 5
Android et XML : Broadcasting• Dans un contexte informatique, le broadcasting désigne une méthode de
transmission de données à l'ensemble des machines d'un réseau.• Pour recevoir des Intent, Android crée une classe qui implémente
BroadcastReceiver avec une seule méthode onReceive().• Le système Android envoie l'intention (Intent) à tous les BroadCast
Receiver abonnés par ordre de priorité (AndroidManifest.xml).• Un BroadCastReceiver est un composant Android qui écoute et
enregistre tout changement dans le mobile:• la reception de messages SMS,• appels téléphoniques,• statut de la batterie,• accès au réseau Wi-Fi,• Bluetooth, etc.
Interface graphique avec XML IvMad, 2011-2016 6
Android et XML : Intent (4)• L'exemple suivant démontre le passage d'un message à partir d'une
activité vers une autre activité.• On crée un projet IntentProject. L'interface graphique de l'activité
compte un TextView, un EditText et un Button.• Dans le champ de texte on saisie le message qui sera traité par l'Intent.• Le traitement est initié par le "click" du bouton qui déclenche la
méthode onClick(View v). Pour la mise en place de la méthode la classeOnClickListener est instancié comme écouteur du bouton.
• Le texte saisie est récupéré par la méthode getText() de la classeEditText.
• Un Intent est instancié pour emmètre le message avec la méthodeputExtra(strName, keyIdentifer)
• Le processus est initié avec l'appel: startActivity(intent);
Interface graphique avec XML IvMad, 2011-2016 7
Android et XML : Intent (5)Interface graphique avec XML IvMad, 2011-2016 8
Activitéprincipalequiémetlemessage"Intent"
Interfacegraphiquedansres/layout pourl'activité
principale
Android et XML : Intent (6)• L'activité secondaire, initiée par l'activité principale est une classe à
part créée dans le même projet.• L'activité possède sa propre interface graphique décrite dans le
répertoire res/layout.• Le message de type Intent est récupéré par la méthode
getStringExtra(strMsg) et affiché dans un objet de type TextView à l'écrande l'activité secondaire.
• Le fichier AndroidManifest.xml doit contenir la description de l'activitésecondaire avec le nom de la classe et le titre de l'activité:<activity
android:name=".DisplayActivity"android:label="@string/title_activity_display"
/>
Interface graphique avec XML IvMad, 2011-2016 9
Android et XML : Intent (7)Interface graphique avec XML IvMad, 2011-2016 10
L'activitéestactivéparun"Intent"etreçoitlemessageenvoyé GUIXMLdel'activité
secondaire
Strings.xmlcontientlesStringdes
deuxactivités
Android et XML : Intent (8)Interface graphique avec XML IvMad, 2011-2016 11
AndroidManifest.xmlestcommunauxdeuxactivitésetdécritlesressourcesàmettre
enœuvre
L'activitésenséerecevoirl'Intent del'activitéprincipale
estdécriteici
Android et XML : Intent (9)Interface graphique avec XML IvMad, 2011-2016 12
Android : Explicite Intent (eMail) • Comment envoyer un e-Mail à partir d'une activité Android ?• La technique de l'explicite Intent peut faire appel à un client e-Mail sous
Android en faisant passer toutes les données nécessaires pour l'envoidu message:
Intent emailIntent = new Intent(Intent.ACTION_SEND);
• En utilisant les Intent et l’intention ACTION_SEND, il est possible dedémarrer une intention d’envoi de données (mail, sms, …).
• Pour envoyer le mail il faut spécifier le URI pour le "mailto:", c.à.d.l'adresse du destinataire, ainsi que les attributs d'un e-mail:• TO, SUBJECT, CC, TEXT.
• L'activité lancera la recherche et le choix d'un client e-mail (par défaut)de préférence GMail:startActivity(Intent.createChooser(emailIntent,
"Envoie du e-mail..."));
Interface graphique avec XML IvMad, 2011-2016 13
Android : Explicite Intent (eMail) Interface graphique avec XML IvMad, 2011-2016 14
strings.xml
activity_intent_send_mail_main.xmlActivitéprincipale
Android : Explicite Intent (eMail) Interface graphique avec XML IvMad, 2011-2016 15
Android : Envoi de SMS (1)• Il y a deux façons d'envoyer un SMS avec une activité Android:
1. A l'aide du SmsManager installé sous Android en s'adressant directement àsa méthode statique:
SmsManager smsManager = SmsManager.getDefault();
• La référence vers le SMS manager donne accès à la méthode d'envoi desdonnées nécessaires. Un message est à compléter du type:smsManager.sendTextMessage("phoneNo", null,
"SMS text", null, null);
2. Par la technique des Intent. Il faut instancier un objet Intent avec l'actionACTION_VIEW:Intent smsIntent = new Intent(Intent.ACTION_VIEW);
• Pour l'envoi il faut spécifier smsto avec l'URI et la méthode setData():smsIntent.setData(Uri.parse("smsto:"));smsIntent.setType("vnd.android-dir/mms-sms");
• La suite fait appel au client SMS Android.
Interface graphique avec XML IvMad, 2011-2016 16
Android : Envoi de SMS (2) Interface graphique avec XML IvMad, 2011-2016 17
Activitéprincipale
res/layout/activity_send_sms.xml
Android : Envoi de SMS (3) Interface graphique avec XML IvMad, 2011-2016 18
strings.xml
AndroidManifest.xml
Android : Envoi de SMS (4) Interface graphique avec XML IvMad, 2011-2016 19
Android : Appel téléphonique (1)• Une activité Android peut emmètre un appel téléphonique par
l'intermédiaire des Intent.• On utilise l'action ACTION_CALL pour basculer vers la
fonctionnalité téléphone de l'unité Android.Intent phoneIntent = new Intent(Intent.ACTION_CALL);
• Pour effectuer un appel téléphonique pour un numéro donné on doitspécifier tel: comme URI avec la méthode setData().
phoneIntent.setData(Uri.parse("tel:04.91.17.79.20"));
Interface graphique avec XML IvMad, 2011-2016 20
Android : Appel téléphonique (2)Interface graphique avec XML IvMad, 2011-2016 21
Activitéprincipale
PermissionsàajouterdansAndrdoidManifest.xml
activity_phone_call.xml
strings.xml
Android : Appel téléphonique (3)Interface graphique avec XML IvMad, 2011-2016 22
Android : NFC (Near Field Communication)• NFC est une technologie de communication en champ proche basée
sur la fréquence radio 13.56 MHz.• La portée de la communication est de l'ordre de 10 cm en théorie mais
effective à 1-4 cm pour des bandes passantes de 106 / 216 / 414 kbps.• La communication permet l'envoi et la lecture de données sous forme
de "Tags" entre deux terminaux ou entre un terminal et une puce.• On peut échanger des données simplement en rapprochant le
Smartphone d'une borne pour effectuer un paiement par exemple.• Android gère les messages NFC avec le format NDEF (NFC Data
Exchange Format).• Pour l'échange d'information NFC l'activité Android a besoin de la
permission dans le fichier AndroidManifest.xml :<user-permission android:name="android.permission.NFC" />
Interface graphique avec XML IvMad, 2011-2016 23
Android : NFC (Near Field Communication)Interface graphique avec XML IvMad, 2011-2016 24
Le mobile devient lecteur NFC qui s’affranchit de la
connexion avec l'unité NFC..
Android : NFC (Near Field Communication)Interface graphique avec XML IvMad, 2011-2016 25
L'activité test la présence du service NFC et son statut.
L'affichage se fait à partir du fichier strings.xml.
Pour extraire une chaine de caractère on précise son
identifiant comme paramètre de la méthode getText()
Android: AsyncTask (Thread )• Un Thread est un fil d'exécution ou tâche utilisé avec l'interface
graphique d'un programme Java ou par des programmes de calculintensif.
• Une application Android consommatrices de ressources (requêtes http,calculs lourds, …) doit faire appel à un thread séparé pour "déconnecter" leGUI du calcul. Ainsi, les deux tâches fonctionnent de manièreasynchrone (AsyncTask) sans provoquer l'arrêt de l'Activité principalesi elle est bloquée trop longtemps.• Créer un nouveau projet appelé AsyncTache qui prend en charge un
traitement long de manière asynchrone.• Modifier le res/layout/main.xml en ajoutant un Button qui sert à lancer le
traitement et une ProgressBar pour afficher la progression du traitement(voir le transparent suivant).
Interface graphique avec XML IvMad, 2011-2016 26
Android: AsyncTask (Thread )• Le code XML à mettre dans res/layout/main.xml :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical" >
<Button android:layout_marginTop="10dp"
android:id="@+id/btnLaunch" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Lancer la tâche" />
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Progression de la tâche asynchrone:" />
<ProgressBar android:id="@+id/pBAsync"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_margin="10dp" android:layout_height="wrap_content" />
</LinearLayout>
Interface graphique avec XML IvMad, 2011-2016 27
Android: AsyncTask (Thread )• Le code Java pour l'Activité principale:
public class AsyncTacheActivity extends Activity {
private ProgressBar mProgressBar;
private Button mButton;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_async_big_calcul);
// On récupère les composants de notre layout
mProgressBar = (ProgressBar) findViewById(R.id.pBAsync);
mButton = (Button) findViewById(R.id.btnLaunch);
// On met un Listener sur le bouton
mButton.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
LaTache tache = new LaTache();
tache.execute(); // On lance la tache séparée
}
});
}
Interface graphique avec XML IvMad, 2011-2016 28
Android: AsyncTask (Thread )• Ecriture de la classe LaTache, qui hérite d’AsyncTaskprivate class LaTache extends AsyncTask<Void, Integer, Void>
• Les trois paramètres attendus sont des types génériques :• Le premier est le type des paramètres fournis à la tâche• Le second est le type de données transmises durant la progression du traitement• Le troisième est le type du résultat de la tâche
• Une AsyncTask implémente la méthode doInBackground, qui réalise letraitement de manière asynchrone dans un thread séparé.
• Trois méthodes appelées depuis l'UI thread, capables de le modifier:• onPreExecute est appelée avant le traitement;• onProgressUpdate est appelée pour afficher la progression de la tache• onPostExecute est appelée après le traitement sont optionnelles.• Un appel à la méthode publishProgress permet la mise à jour de la progression. On
ne doit pas appeler la méthode onProgressUpdate directement.
Interface graphique avec XML IvMad, 2011-2016 29
Android: AsyncTask (Thread )private class LaTache extends AsyncTask<Void, Integer, Void> {
protected void onPreExecute() {super.onPreExecute();
Toast.makeText(getApplicationContext(), "Début du traitement asynchrone", Toast.LENGTH_LONG).show(); }
protected void onProgressUpdate(Integer... values){super.onProgressUpdate(values);
// Mise à jour de la ProgressBar
mProgressBar.setProgress(values[0]); }
protected Void doInBackground(Void... arg0) {
int p;for (p=0; p<=100; p++) {
for (int i=0; i<1000000; i++) { /* vide */ }
// la méthode publishProgress met à jour l'interface en // invoquant la méthode onProgressUpdate
publishProgress(p); }
return null; }
protected void onPostExecute(Void result) {
Toast.makeText(getApplicationContext(), "Le traitement asynchrone est terminé", Toast.LENGTH_LONG).show();
} }
Interface graphique avec XML IvMad, 2011-2016 30
Android: AsyncTask (Thread )Interface graphique avec XML IvMad, 2011-2016 31
Ecran 1 au lancement de l'activité
Ecran 2 fin de l'activité Ecran 3 résultat de l'activité : tri par
sélection
Android: AsyncTask (Thread )• Appliquer un traitement lourd comme le tri par sélection d'un certain
nombre d'entiers générés aléatoirement:int[] tbl = new int[100];......................tbl[i] = (int)(Math.random()*128);.......................protected void triSelection(int[] tbl, int N) {
int min, t, i;for (i=0; i<N-1; ++i) {
min = i;for (int j=i+1; j<N; ++j) {
if (tbl[j] < tbl[min]) {min = j;
}}t = tbl[min];tbl[min] = tbl[i];tbl[i] = t;
}}
Interface graphique avec XML IvMad, 2011-2016 32
Android : SQLite base de données (1) • SQLite est Open Source Database accessible dans chaque unité mobile
avec le système Android.• L'utilisation d'une BD SQLite ne demande aucune installation ou
administration.• SQLite supporte le type TEXT (String en Java), INTEGER (long en Java)
et REAL (double en Java). Tous les autres types doivent être convertivers un reconnu SQLite.
• Si une application Android crée une BD elle est alors sauvegardée par défaut dans le dossier : DATA/data/APP_NAME/databases/FILENAME.
• Le package android.database contient les classes nécessaires à lamanipulation d'une BD.
• Le package android.database.sqlite contient des classes spécifiques àSQLite.
Interface graphique avec XML IvMad, 2011-2016 33
Android : SQLite (2) • Pour créer et modifier une BD dans une activité on étend (hérite) la
sous-classe SQLiteOpenHelper.• Le constructeur de l'activité fait appel à la méthode super():
• super(context, DATABASE_NAME, null, DATABASE_VERSION);
• Dans cette classe les méthodes onCreate() et onUpgrade() sont à réécrire.• onCreate() est appelé pour la création de la BD si elle n'existe pas.• onUpgrade() est appelé pour modifier le schéma de la BD.• Les deux méthodes prennent en paramètre la référence de la BD.
• La classe SQLiteOpenHelper fourni les méthodes getReadableDatabase()et getWriteableDatabase() pour accéder à un objet de typeSQLiteDatabase en lecture ou en écriture.
• Une table de BD doit être identifiée par un _id qui est prisautomatiquement pour une clé primaire.
Interface graphique avec XML IvMad, 2011-2016 34
Android : SQLite (3) • SQLiteDatabase est la classe de base pour opérer avec une BD sous
Android.• Elle fournie les méthodes pour ouvrir, interroger, modifier ou fermer une
BD : insert(), update() et delete() et la méthode execSQL(), quiexécute une requête SQL.
• L'objet ContentValues fourni le binôme key/values.• "key" est l'attribut d'une colonne et "values" représente son contenu.• ContentValues peut être utilisé pour insérer ou modifier des
enregistrements dans la BD.• Les requêtes sont créées via les méthodes rawQuery() ou query() de la
classe SQLiteQueryBuilder.• rawQuery() accepte directement la requête SQL en paramètre.• query() propose une interface structurée pour la requête SQL.• SQLiteQueryBuilder est la classe qui facilite la création des requêtes SQL.
Interface graphique avec XML IvMad, 2011-2016 35
Android : SQLite (4) public class MaBaseDeDonneesAndroid extends SQLiteOpenHelper {
// Version de la BDprivate static final int DATABASE_VERSION = 1;// Nom de la BDprivate static final String DATABASE_NAME = "contactsManager";// Nom de la table dans la BDprivate static final String TABLE_CONTACTS = "contacts";
// Noms des colonnes dans la tableprivate static final String KEY_ID = "id";private static final String KEY_NAME = "name";private static final String KEY_PH_NO = "phone_number";
public MaBaseDeDonneesAndroid(Context context) {// Ouverture et création de la BD si n'existe passuper(context, DATABASE_NAME, null, DATABASE_VERSION);
}
Interface graphique avec XML IvMad, 2011-2016 36
Android : SQLite (5) // Création de la table@Overridepublic void onCreate(SQLiteDatabase db) {String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_CONTACTS + "("
+ KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"+ KEY_PH_NO + " TEXT" + ")";
db.execSQL(CREATE_CONTACTS_TABLE);}
// Effacer ou modifier une table@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existeddb.execSQL("DROP TABLE IF EXISTS " + TABLE_CONTACTS);
// Create tables againonCreate(db);
}
Interface graphique avec XML IvMad, 2011-2016 37
Android : SQLite (6) // Ajouter un 'contact' dans la tablevoid addContact(Contact contact) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();// Prendre le nomvalues.put(KEY_NAME, contact.getName());// Prendre le numéro de téléphonevalues.put(KEY_PH_NO, contact.getPhoneNumber());
// Insérer une ligne dans la tabledb.insert(TABLE_CONTACTS, null, values);// Fermer la BDdb.close();
}
Interface graphique avec XML IvMad, 2011-2016 38
Android : SQLite (7) // "Afficher" le contenu de la tablepublic List<Contact> getAllContacts() {
List<Contact> contactList = new ArrayList<Contact>();// Sélectionner toutes les lignes de la tableString selectQuery = "SELECT * FROM " + TABLE_CONTACTS;SQLiteDatabase db = this.getWritableDatabase();Cursor cursor = db.rawQuery(selectQuery, null);// On boucle pour ajouter les lignes à la listeif (cursor.moveToFirst()) {
do {Contact contact = new Contact();contact.setID(Integer.parseInt(cursor.getString(0)));contact.setName( cursor.getString(1) );contact.setPhoneNumber( cursor.getString(2) );contactList.add(contact); // Ajouter un contact à la liste
} while (cursor.moveToNext());}return contactList; // Retourne une liste de contacts
}
Interface graphique avec XML IvMad, 2011-2016 39
Android : connexion à MySQL (1)• Une application Java peut se connecter à une BD MySQL avec un
connecteur JDBC. Ceci est juste pour Java2SE et JSP.• Le pilote JDBC est l'interface de liaison entre l'application et le SGBD.• Les récentes version d'Android préconisent l'utilisation d'un Service
Web et une connexion basée HTTP par l'intermédiaire de scripts PHPou JSP pour accéder au contenu de la BD et pour recevoir sur l'unitémobile sous Android le résultat d'une requête SQL.
• Néanmoins, il est possible de réussir une connexion avec une BDbasée MySQL en se servant d'un connecteur JDBC anciennegénération beaucoup plus adapté aux connexions lentes d'unSmartphone ou une Tablette.
• Ainsi, dans les transparents qui suivent je présente une connexion réussie avec le connecteur JDBC dans le contexte de la DOSI : mysql-connector-java-3.0.17-ga-bin.jar
Interface graphique avec XML IvMad, 2011-2016 40
Android : connexion à MySQL (2)public void listDB() {
// Renseigner les champs nécessaires à la connexionString url = "jdbc:mysql://dbs-perso.luminy.univmed.fr:3306/nom_BD";String user = "nom_utilisateur";String pass = "mot_de_passe";try {
// Instancier le driver JDBCClass.forName("com.mysql.jdbc.Driver").newInstance();// Effectuer la connexion avec le serveur de la BDConnection con = DriverManager.getConnection(url, user, pass);// Confirmer la connexionToast.makeText(getApplicationContext(),"Connexion OK!",Toast.LENGTH_SHORT).show();// Préparer la requete SQLString result = "";Statement st = con.createStatement();ResultSet rs = st.executeQuery("select * from contact");// Recuperer le résultat de la requeteResultSetMetaData rsmd = rs.getMetaData();// Extraire les éléments propres à chaque champswhile(rs.next()) {
result += rsmd.getColumnName(1) + ": " + rs.getInt(1) + "\n";result += rsmd.getColumnName(2) + ": " + rs.getString(2) + "\n";result += rsmd.getColumnName(3) + ": " + rs.getString(3) + "\n";result += rsmd.getColumnName(4) + ": " + rs.getString(4) + "\n";
}rs.close(); con.close();// Afficher le résultatToast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
} catch(Exception e) { e.printStackTrace(); } }
Interface graphique avec XML IvMad, 2011-2016 41
Toast affiche un contenu dans un cadre temporaire en fonction de trois paramètres:
context, text, duration
Android : connexion à MySQL (3)• Dans l'IDE Eclipse le connecteur JDBC doit être rajouté au projet qui
gère les classes de la connexion.• Télécharger dans un dossier le connecteur à partir de l'adresse:
http://139.124.26.245/ic4/pilot/mysql-connector-java-3.0.17-ga-bin.jar• Par simple glisser dans l'interface
Eclipse: copier/coller mettre le pilote dans le répertoire 'libs'
• Bouton droit sur le projet pour choisir 'Properties' -> 'Java buil Path' -> Libraries -> 'Add Jars' ->Ajouter dans Libs du projet.
Interface graphique avec XML IvMad, 2011-2016 42
Android : connexion à MySQL (4)// Insérer des données dans une table public void insertDB() {try {
// Instancier le connecteur Class.forName("com.mysql.jdbc.Driver").newInstance();// Etablir la connexion avec le serveur de la BDConnection con = DriverManager.getConnection(url, user, pass);// Construire la requête d'insertion de données requises à partir // d'une interface utilisateur sur l'unité mobileString sSQL = "";sSQL += "INSERT INTO Contact(prenom,nom,tel)";sSQL += " VALUES ('"+lastNameText.getText().toString()+
"','"+firstNameText.getText().toString()+"','"+telNumberText.getText().toString()+"');";
// Créer l'opérateurStatement st = con.createStatement();// Lancement de la requête int nb = st.executeUpdate(sSQL);// Fermeture des connexionsst.close();con.close();
}catch(Exception e) {
e.printStackTrace();}
}
Interface graphique avec XML IvMad, 2011-2016 43
Android : Airplane Mode ON/OFF• Le mode "avion" a pour objectif de couper toute transmission radio du
mobile afin de ne pas perturber les systèmes de l'avion.• La mise en mode "avion" du smartphone évite de l'éteindre totalement
et autorise ainsi l'utilisation des autres fonctionnalités telles quel'écoute de la musique, jeux, etc...
• Le mode "avion" coupe la transmission de signal tel que l'appeltéléphonique, l'envoi de message, Bluetooth, WI-FI etc....
• Le mode "avion" est signalé en Android comme un paramètre debasculement entier : 1 - ON, 0 - OFF.
• Depuis l'API 17 Android le basculement programmé du mode "avion" estréservé au système et une activité Android n'a plus le droit d'activer ou dedésactiver ce mode. Néanmoins, on peut lire le statut du mode et l'afficher.• On utilise la méthode putInt() de la classe Settings.Global pour prendre
l'état courant du mode "avion". On a besoin de la méthode ContentResolver liéeau contexte de l'activité.
Interface graphique avec XML IvMad, 2011-2016 44
Android : Airplane Mode ON/OFFInterface graphique avec XML IvMad, 2011-2016 45
Android : Présenter en Tableau (1)• La structure tableau dans toutes les plates-formes représente un
moyen efficace de présentation et/ou de stockage d'information.• Le point de départ pour mettre en place un tableau dans une
application Android est de s'adresser à l'élément TableLayout.• Le principe est un peu le même que pour le tableau en HTML :
• TableLayout défini un tableau, dans lequel on rajoute des lignes• TableRow contient les composants.
• Les colonnes peuvent être définies comme• extensibles (setColumnStretchable()) pour gérer la largeur des colonnes tout en
laissant une occuper l’espace vide pour arriver à la largeur du conteneur• rétractables (setColumnShrinkable()) pour obtenir l’effet inverse.
• Le TableLayout ne gère pas l’affichage des bordures, lignes, colonnes oucellules. C'est à définir dans un fichier style.xml.
Interface graphique avec XML IvMad, 2011-2016 46
Android : Présenter en Tableau (2)• Créer le tableau dans res/layout/main.xml
<TableLayout style="@style/frag1TableLayout" >
<TableRow style="@style/frag1HeaderTableRow">
<TextView style="@style/frag1HeaderCol" android:text="cm"/>
<TextView style="@style/frag1HeaderCol" android:text="inch"/>
</TableRow>
<TableRow style="@style/frag1TableRow">
<TextView style="@style/frag1Col" android:text="2.54"/>
<TextView style="@style/frag1Col" android:text="1"/>
</TableRow>
<TableRow style="@style/frag1TableRow">
<TextView style="@style/frag1Col" android:text="5.08"/>
<TextView style="@style/frag1Col" android:text="2"/>
</TableRow>
<TableRow style="@style/frag1TableRow">
<TextView style="@style/frag1Col" android:text="7.62"/>
<TextView style="@style/frag1Col" android:text="3"/></TableRow>
</TableLayout>
Interface graphique avec XML IvMad, 2011-2016 47
Android : Présenter en Tableau (3)• Un style peut être appliqué pour chacune des colonnes comme une
feuille de style CSS dans le fichier style.xml.<resources xmlns:android="http://schemas.android.com/apk/res/android"><style name="AppTheme" parent="@android:style/android:Theme.Light" /><style name="defaultTextView" parent="@android:style/TextAppearance.Medium"><item name="android:layout_width">match_parent</item><item name="android:layout_height">wrap_content</item></style>
<style name="frag1TableLayout"><item name="android:layout_width">match_parent</item><item name="android:layout_height">wrap_content</item></style>
<style name="frag1HeaderTableRow" parent="frag1TableLayout"><item name="android:layout_marginBottom">3dp</item></style>
<style name="frag1TableRow" parent="frag1TableLayout"></style><style name="frag1Col" parent="defaultTextView"><item name="android:layout_marginBottom">1dp</item><item name="android:background">@drawable/tableborder</item></style>
<style name="frag1HeaderCol" parent="frag1Col"><item name="android:textStyle">bold</item></style>
</resources>
Interface graphique avec XML IvMad, 2011-2016 48
Android : Présenter en Tableau (4)• Ajouter une bordure au tableau grâce à un objet drawable en forme de
rectangle défini en arrière plan. Pour cela on créer l'objet drawable dansle répertoire /res/drawable/tableborder.xml.<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="#FFFFFF"/><stroke android:width="1dp" android:color="#777777"/><corners android:radius="3dp" /><padding android:left="100dp" android:top="5dp"
android:right="10dp" android:bottom="5dp" /></shape>
Interface graphique avec XML IvMad, 2011-2016 49
Connexion TCP avec AsyncTask (1)• Une application Android se connectant sur un serveur TCP par la
méthode de traitement asynchrone de la requête réseau:public class TCPAsyncTaskActivity extends Activity {
private String stringUrl = "192.168.0.142";private TextView textView;
@Overridepublic void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);textView = new TextView(this);setContentView(textView);TCPAsyncTaskRequest();
}
Interface graphique avec XML IvMad, 2011-2016 50
Connexion TCP avec AsyncTask (2)• La méthode vérifie la connexion et l'accessibilité du service réseau
pour faire appel alors à la méthode gérée par AsyncTask.public void TCPAsyncTaskRequest() {
ConnectivityManager connMgr = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();if (networkInfo != null && networkInfo.isConnected()) {
new AccessServerTask().execute(stringUrl);} else {
textView.setText("No network connection available.");}
}
Interface graphique avec XML IvMad, 2011-2016 51
Connexion TCP avec AsyncTask (3)• La méthode appelle la méthode qui exécute la tache asynchrone en
fond et libère ainsi l'interface utilisateur. La méthode onPostExecuteretourne le résultat du traitement.private class AccessServerTask extends AsyncTask<String,Void,String> {
@Overrideprotected String doInBackground(String... urls) { // params comes from the execute() call: params[0] is the url.
return runTcpClient(urls[0]);}// onPostExecute displays the results of the AsyncTask.@Overrideprotected void onPostExecute(String result) {
textView.setText(result);}
}
Interface graphique avec XML IvMad, 2011-2016 52
Connexion TCP avec AsyncTask (3)• La méthode qui effectue le traitement réseau.private String runTcpClient(String myurl) {try {
Socket s = new Socket(myurl, 1234);BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));// send output msgString outMsg = "Connexion du client TCP sur le port: 1234" +
System.getProperty("line.separator"); out.write(outMsg);out.flush();// accept server responseString inMsg = in.readLine() + System.getProperty("line.separator");// close connections.close();return inMsg;
} catch (UnknownHostException e) {return "Aucune connexion!";
} catch (IOException e) {return "Aucune connexion!";
} }
Interface graphique avec XML IvMad, 2011-2016 53
HTTP Serveur avec AsyncTask (1)• Pour chaque connexion un thread client est créé par une tache de fond
non synchronisé avec le thread principal de l'activité.public class HTTPServerAsynkTaskMainActivity extends ActionBarActivity {
private TextView textView;int port = 4444;@Overrideprotected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);textView = new TextView(this);textView.setText("Serveur installé sur le port: "+port);setContentView(textView);new HTTPDServerTask().execute("");
}
Interface graphique avec XML IvMad, 2011-2016 54
HTTP Serveur avec AsyncTask (2)• private class HTTPDServerTask extends AsyncTask<String, Void, String> {
@Overrideprotected String doInBackground(String... urls) { try { // Installation du serveur sur un port ServerSocket ss = new ServerSocket(port); Log.i("HTTPDServerTaskActivity", "Serveur installé sur "+port);while(true) { // Boucle des connections clients
Socket sk = ss.accept(); // Connexion acceptéemHttpdConnection(sk); // Création du client
}} catch (IOException e) {
Log.i("HTTPDServerTaskActivity", e.getMessage()); }return "";
}@Overrideprotected void onPostExecute(String result) { }
Interface graphique avec XML IvMad, 2011-2016 55
HTTP Serveur avec AsyncTask (3)protected void mHttpdConnection(Socket sk) {
try { OutputStream out = sk.getOutputStream(); // Formater le flux de sortie// Lecture de la requêteString req = (new BufferedReader(
new InputStreamReader(sk.getInputStream()))).readLine();Log.i("mHttpdConnection", "Requête: "+req); // Traitement de la requête GETString str[] = req.split(" "); // Décompose 'req' par " " et charge en éléments en tableauif (str[0].equals("GET")) {
// Vérifier si la requête démarre par "GET"req = str[1].substring(1); // On enlève '/' devant le nom du fichier
if (req.equals("")) req = req + "index.html";
Interface graphique avec XML IvMad, 2011-2016 56
HTTP Serveur avec AsyncTask (4)try {
FileInputStream fis = new FileInputStream(req); // Ouvrir le fichier demandé
byte[] data = new byte[fis.available()];
// available retourne le nombre de bytes à lire
fis.read(data); // Lire les données du fichier dans le tableau de bytes
out.write(data); // Envoyer les données au client
fis.close(); // Fermer le fichier demandé
Log.i("mHttpdConnection", "Le serveur a envoyé la page au client");
} catch (FileNotFoundException e) {
new PrintStream(out).println("404 Not Found"); }
} else {
new PrintStream(out).println("400 Bad Request"); }
sk.close();
} catch (IOException e) {
Log.i("mHttpdConnection", "I/O error " + e.getMessage()); }
}
}
}
Interface graphique avec XML IvMad, 2011-2016 57