<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ace Art</title>
	<atom:link href="http://www.ace-art.fr/wordpress/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ace-art.fr/wordpress</link>
	<description>Developpement Android / C# / Java</description>
	<lastBuildDate>Mon, 23 Jan 2012 10:42:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>[Tutoriel Android] Partie 18 – Contrôles personnalisés</title>
		<link>http://www.ace-art.fr/wordpress/2012/01/22/tutoriel-android-partie-18-customcontrols/</link>
		<comments>http://www.ace-art.fr/wordpress/2012/01/22/tutoriel-android-partie-18-customcontrols/#comments</comments>
		<pubDate>Sun, 22 Jan 2012 17:55:16 +0000</pubDate>
		<dc:creator>Pierre-Emmanuel Mercier</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Programmation]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[contrôle]]></category>
		<category><![CDATA[custom component]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[tutoriel]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://www.ace-art.fr/wordpress/?p=561</guid>
		<description><![CDATA[Aujourd&#8217;hui nous allons aborder le thème des contrôles personnalisés. Tout d&#8217;abord qu&#8217;est-ce qu&#8217;un contrôle personnalisé ? (Custom control ou encore Custom component). Hé bien un c&#8217;est un composant que nous allons utiliser dans notre application pour afficher une donnée, nous allons développer un contrôle personnalisé car soit ce composant n&#8217;existe pas dans le SDK Android, soit parce que cet élément est redondant dans toute l&#8217;interface. Le cas où le composant n&#8217;existe pas Diagramme (camembert,bâton,etc&#8230;) Compteur [...]]]></description>
			<content:encoded><![CDATA[<p>Aujourd&#8217;hui nous allons aborder le thème des contrôles personnalisés.</p>
<p>Tout d&#8217;abord qu&#8217;est-ce qu&#8217;un contrôle personnalisé ? (Custom control ou encore Custom component).</p>
<p>Hé bien un c&#8217;est un composant que nous allons utiliser dans notre application pour afficher une donnée, nous allons développer un contrôle personnalisé car soit ce composant n&#8217;existe pas dans le SDK Android, soit parce que cet élément est redondant dans toute l&#8217;interface.</p>
<p>Le cas où le composant n&#8217;existe pas</p>
<ul>
<li>Diagramme (camembert,bâton,etc&#8230;)</li>
<li>Compteur de vitesse</li>
<li>Thermomètre</li>
<li>Etc&#8230;</li>
</ul>
<p>Cas où le composant existe mais on le modifie pour le réutiliser tout le temps</p>
<ul>
<li>Chargement d&#8217;une image</li>
<li>Bannière publicitaire</li>
<li>Menu</li>
<li>etc&#8230;</li>
</ul>
<p><span id="more-561"></span></p>
<h2>Héritage !</h2>
<p>L&#8217;héritage est très important dans la création d&#8217;un contrôle.</p>
<p>Les contrôles se différencies avec deux grands types</p>
<ol>
<li>Affichage à base de canvas (View)</li>
<li>Affichage à base d&#8217;OpenGL (SurfaceView)</li>
</ol>
<div>A vous de choisir en fonction de ce que vous voulez faire, par exemple pour la galerie d&#8217;image Android, une SurfaceView sera plus performante.</div>
<div>Ensuite il est possible d&#8217;utiliser plusieurs méthodes pour créer un contrôle à base de View.</div>
<div></div>
<div>
<ol>
<li>On part d&#8217;une base vierge (View)</li>
<li>On part d&#8217;un élément existant (TextView,etc&#8230;)</li>
<li>On part d&#8217;une liste d&#8217;éléments (ViewGroup,LinearLayout,etc&#8230;)</li>
</ol>
<div>Vous avez plusieurs possibilités selon votre besoin.</div>
<div>Partir d&#8217;une base vierge demande pas mal de travail au niveau conception pour rendre son contrôle performant et adaptable sur tous les écrans (échelle etc..).</div>
</div>
<h2>Chargement d&#8217;une image asynchrone</h2>
<p>Imaginons que nous avons une ListView avec des images à charger, pour rendre notre application performante nous allons utiliser un thread pour charger nos images sinon on risque de bloquer l&#8217;utilisateur si la vitesse de téléchargement est trop lente.</p>
<p>Donc il nous faut 1 ImageView et 1 Thread à chaque fois, mais c&#8217;est embêtant j&#8217;ai 2 activités qui utilises le même fonctionnement, voir même plusieurs applications !</p>
<p>Pas d’inquiétudes matelot nous allons faire un contrôle pour cela</p>
<p>Tout d&#8217;abord on va partir d&#8217;un contrôle existant (ImageView) puis embarquer un Thread dans ce contrôle pour gérer le chargement en asynchrone (AsyncTrask).</p>
<pre class="brush: java; title: ; notranslate">
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.widget.ImageView;

/***
 * ImageLoader
 *
 * @author ace
 *
 */
public class ImageLoaderView extends ImageView {

	/**
	 * Constructeur hérité
	 *
	 * @param context
	 * @param attrs
	 */
	public ImageLoaderView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public void loadImage(String url) {
		new DownloadImage(this).execute(url);
	}

	private class DownloadImage extends AsyncTask {

		final ImageView imageView;

		public DownloadImage(ImageView imageView) {
			this.imageView = imageView;
		}

		@Override
		protected Bitmap doInBackground(String... params) {
			if (params.length == 0)
				return null;

			try {
				URL url = new URL(params[0]);
				InputStream stream = url.openStream();

				Bitmap bf = BitmapFactory.decodeStream(stream);

				return bf;

			} catch (MalformedURLException e) {
				return null;
			} catch (IOException e) {
				return null;
			}
		}

		@Override
		protected void onPostExecute(Bitmap result) {
			if(result != null)
				imageView.setImageBitmap(result);

			super.onPostExecute(result);
		}

	}

}
</pre>
<p>Je vous donne la classe directement, pas besoin d&#8217;explication vous savez déjà charger une image (Partie 8) et vous connaissez aussi les threads (Partie 9).</p>
<p>Nous allons maintenant utiliser notre nouveau composant dans notre layout principal</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
android:layout_width=&quot;fill_parent&quot;
android:layout_height=&quot;fill_parent&quot;
android:orientation=&quot;vertical&quot; &gt;

&lt;com.aceart.formation.component.ImageLoaderView
android:id=&quot;@+id/imageLoader1&quot;
android:layout_width=&quot;wrap_content&quot;
android:layout_height=&quot;wrap_content&quot;
/&gt;

&lt;com.aceart.formation.component.ImageLoaderView
android:id=&quot;@+id/imageLoader2&quot;
android:layout_width=&quot;wrap_content&quot;
android:layout_height=&quot;wrap_content&quot;
/&gt;

&lt;com.aceart.formation.component.ImageLoaderView
android:id=&quot;@+id/imageLoader3&quot;
android:layout_width=&quot;wrap_content&quot;
android:layout_height=&quot;wrap_content&quot;
/&gt;

&lt;/LinearLayout&gt;
</pre>
<p>Trois images loader avec chacun un ID.<br />
Dirigeons nous maintenant vers notre activité</p>
<pre class="brush: java; title: ; notranslate">
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        final ImageLoaderView imgL1 = (ImageLoaderView) findViewById(R.id.imageLoader1);
        imgL1.loadImage(&quot;http://www.laptopspirit.fr/wp-content/uploads/new/mandriva-logo.thumbnail.jpg&quot;);

        final ImageLoaderView imgL2 = (ImageLoaderView) findViewById(R.id.imageLoader2);
        imgL2.loadImage(&quot;http://i73.photobucket.com/albums/i240/jazzk1/android-logo-mask.png&quot;);

        final ImageLoaderView imgL3 = (ImageLoaderView) findViewById(R.id.imageLoader3);
        imgL3.loadImage(&quot;http://upload.wikimedia.org/wikipedia/fr/7/78/Quakelive_logo_300.png&quot;);

    }
</pre>
<p>On récupère nos ImageLoader et on effectue l&#8217;action de chargement.<br />
Lancer l&#8217;application et miracle le chargement est en asynchrone et pas besoin de réécrire le code et qui plus est vous pouvez réutiliser ce code dans les ListView etc&#8230;</p>
<p style="text-align: center;"><a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2012/01/device-2012-01-22-113157.png" rel="lightbox[561]"><img class="aligncenter  wp-image-562" title="ImageLoaderView" src="http://www.ace-art.fr/wordpress/wp-content/uploads/2012/01/device-2012-01-22-113157.png" alt="" width="144" height="259" /></a></p>
<h2 style="text-align: left;">Création d&#8217;un graphique</h2>
<p>Nous allons maintenant voir comment créer un custom components grâce au canvas.</p>
<p>Les étapes :</p>
<ol>
<li>Définir le modèle de données (Classe Item)</li>
<li>Créer le contrôle (Héritage de la classe View)</li>
<li>Implémenter la méthode onDraw</li>
<li>Dessiner le diagramme grâce au canvas</li>
<li>Afficher</li>
</ol>
<p>Rien de plus simple en fait.</p>
<p>Voici la classe item que nous utiliserons pour fournir en données notre vue</p>
<pre class="brush: java; title: ; notranslate">
public class PieChartItem {
	private double value;
	private int color;

	public PieChartItem(double value, int color) {
		this.value = value;
		this.color = color;
	}
	public double getValue() {
		return value;
	}
	public void setValue(double value) {
		this.value = value;
	}
	public int getColor() {
		return color;
	}
	public void setColor(int color) {
		this.color = color;
	}
}
</pre>
<p>Notre objet contient une valeur et une couleur.</p>
<p>Notre vue maintenant</p>
<pre class="brush: java; title: ; notranslate">
public class PieChartView extends View {

	private List&lt;PieChartItem&gt; items;

	public PieChartView(Context context, AttributeSet attrs) {
		super(context, attrs);
		items = new ArrayList&amp;lt;PieChartItem&amp;gt;();
	}

	@Override
	protected void onDraw(Canvas canvas) {
		drawChart(canvas);
		super.onDraw(canvas);
	}

	private void drawChart(Canvas canvas) {
		if (items != null) {
		}
	}
}
</pre>
<p>On a bien hérité de la vue, on a le bon constructeur et la méthode onDraw est implémentée <img src='http://www.ace-art.fr/wordpress/wp-content/plugins/smilies-themer/Nomicons v2.0/w00t.png' alt=':w00t:' class='wp-smiley' /> <br />
Il reste plus qu&#8217;a appeler notre petit diagramme dans le layout</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
 android:layout_width=&quot;fill_parent&quot;
 android:layout_height=&quot;fill_parent&quot;
 android:orientation=&quot;vertical&quot;&gt;

&lt;com.aceart.formation.component.PieChartView
 android:id=&quot;@+id/pieChart&quot;
 android:layout_width=&quot;fill_parent&quot;
 android:layout_height=&quot;wrap_content&quot;
 android:background=&quot;@android:color/white&quot; /&gt;

&lt;/LinearLayout&gt;
</pre>
<p>Je vous donnes le code d&#8217;exemple tout de même pour pouvoir vous amusez <img src='http://www.ace-art.fr/wordpress/wp-content/plugins/smilies-themer/Nomicons v2.0/laughing.png' alt=':lol:' class='wp-smiley' /> </p>
<p><strong>Classe complète: </strong></p>
<pre class="brush: java; title: ; notranslate">
public class PieChartView extends View {

	private List&lt;PieChartItem&gt; items;

	public PieChartView(Context context, AttributeSet attrs) {
		super(context, attrs);
		items = new ArrayList&amp;lt;PieChartItem&amp;gt;();
	}

	@Override
	protected void onDraw(Canvas canvas) {
		drawChart(canvas);
		super.onDraw(canvas);
	}

	private void drawChart(Canvas canvas) {
		if (items != null) {

			// angle de départ
			float angleDepart = 0.f;
			double somme = getSomme();

			// Zone carrée
			RectF zoneDessin = new RectF(0, 0, getWidth(), getWidth());

			// Pinceau
			Paint paint = new Paint();
			paint.setAntiAlias(true);
			paint.setStyle(Paint.Style.FILL);

			// On passe chaque item en revue
			for (PieChartItem item : items) {

				// on change la couleur
				paint.setColor(item.getColor());

				// On calcul l'angle d'ouverutre
				float sweepAngle = (float) ((item.getValue() / somme) * 360);

				// On dessine l'arc
				canvas.drawArc(zoneDessin, angleDepart, sweepAngle, true, paint);

				// On change l'angle de départ
				angleDepart += sweepAngle;
			}
		}
	}

	private double getSomme() {
		double somme = 0;

		for (PieChartItem item : items) {
			somme += item.getValue();
		}

		return somme;
	}

	public void addValue(PieChartItem item) {
		this.items.add(item);
	}

	public void setValues(List&amp;lt;PieChartItem&amp;gt; items) {
		this.items = items;
	}

}
</pre>
<p><strong>Les appels dans l&#8217;activité principale :</strong></p>
<pre class="brush: java; title: ; notranslate">
public class FormationCustomComponentActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        final PieChartView pieChartView = (PieChartView) findViewById(R.id.pieChart);

        pieChartView.addValue(new PieChartItem(25, Color.GREEN));
        pieChartView.addValue(new PieChartItem(75, Color.RED));

    }
}
</pre>
<p>Et le rendu pour finir</p>
<p><a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2012/01/device-2012-01-22-185028.png" rel="lightbox[561]"><img class="aligncenter size-medium wp-image-567" title="PieChart" src="http://www.ace-art.fr/wordpress/wp-content/uploads/2012/01/device-2012-01-22-185028-180x300.png" alt="" width="180" height="300" /></a></p>
<p>Maintenant à vous de vous amuser à créer vos propres composants.</p>
<a class="wpptopdf" target="_blank" rel="noindex,nofollow" href="http://www.ace-art.fr/wordpress/2012/01/22/tutoriel-android-partie-18-customcontrols/?format=pdf" title="Download PDF"><img alt="Download PDF" src="http://www.ace-art.fr/wordpress/wp-content/plugins/wp-post-to-pdf/asset/images/pdf.png"></a><fb:like href='http://www.ace-art.fr/wordpress/2012/01/22/tutoriel-android-partie-18-customcontrols/' send='false' layout='standard' show_faces='true' width='450' height='65' action='like' colorscheme='light' font='lucida+grande'></fb:like>]]></content:encoded>
			<wfw:commentRss>http://www.ace-art.fr/wordpress/2012/01/22/tutoriel-android-partie-18-customcontrols/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[Tutoriel Android] Partie 17 &#8211; StrictMode</title>
		<link>http://www.ace-art.fr/wordpress/2012/01/16/tutoriel-android-partie-17-strictmode/</link>
		<comments>http://www.ace-art.fr/wordpress/2012/01/16/tutoriel-android-partie-17-strictmode/#comments</comments>
		<pubDate>Mon, 16 Jan 2012 13:34:16 +0000</pubDate>
		<dc:creator>Pierre-Emmanuel Mercier</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[StrictMode]]></category>
		<category><![CDATA[tutoriel]]></category>

		<guid isPermaLink="false">http://www.ace-art.fr/wordpress/?p=551</guid>
		<description><![CDATA[Le StrictMode Bonjour à tous, Aujourd&#8217;hui nous allons aborder un petit outil sympathique embarqué au sein de la plateforme Android, cet outil se nomme le StrictMode. http://developer.android.com/reference/android/os/StrictMode.html Vous allez me dire, &#8220;c&#8217;est quoi cette bête ?&#8221; le StrictMode est une mode Strict (ouha !) il permet de rendre son application plus performantes en vous donnant des informations précises. Les informations peuvent être de plusieurs types OS Ecriture sur le disque Lecture sur le disque Opération [...]]]></description>
			<content:encoded><![CDATA[<h1>Le StrictMode</h1>
<p>Bonjour à tous,</p>
<p>Aujourd&#8217;hui nous allons aborder un petit outil sympathique embarqué au sein de la plateforme Android, cet outil se nomme le StrictMode.</p>
<p><a href="http://developer.android.com/reference/android/os/StrictMode.html">http://developer.android.com/reference/android/os/StrictMode.html</a></p>
<p>Vous allez me dire, &#8220;c&#8217;est quoi cette bête ?&#8221; le StrictMode est une mode Strict (ouha !) il permet de rendre son application plus performantes en vous donnant des informations précises.</p>
<p>Les informations peuvent être de plusieurs types</p>
<ul>
<li>OS</li>
<ul>
<li>Ecriture sur le disque</li>
<li>Lecture sur le disque</li>
<li>Opération sur le réseau</li>
<li>Accès lents</li>
</ul>
<li>VM (Machine virtuelle)</li>
<ul>
<li>Fuite mémoire sur les activités</li>
<li>Fuite mémoire sur les objets</li>
<li>Fuite mémoire sur les données SQL</li>
</ul>
</ul>
<p>Ces points sont très importants, car pour faire une bonne application il faut la rendre performante, vous allez me dire qu&#8217;aujourd&#8217;hui on a 1go de ram, des processeurs dual core etc&#8230;</p>
<p>Je ne suis pas d&#8217;accord sur ce point, sur l&#8217;OS vous n&#8217;êtes pas la seule application, l&#8217;utilisateurs n&#8217;utilise pas forcément de gestionnaire de tâches pour décharger les applications qui ne lui servent plus, tout cela à un impact.</p>
<p>Il faut garder en tête qu&#8217;un utilisateur lambda installe des applications et les utilisent fréquemment, de plus ces applications sont peut-être mal codées ce qui pose le problème sur la mémoire encombrées.</p>
<p>Pensez aussi au téléphone de l&#8217;ancienne génération avec des petits processeurs et peu de mémoire vive.</p>
<p>Avoir une application optimisée et propre va vous permettre de mieux coder et de rendre son utilisation de meilleure qualité.</p>
<p><span id="more-551"></span></p>
<h2>Pré-requis</h2>
<ul>
<li> Android 2.3 et supérieur</li>
</ul>
<h2>Implémentation</h2>
<p>L&#8217;implémentation au sein du framework Android n&#8217;est disponible qu&#8217;à partir d&#8217;Android 2.3 donc ne cherchez pas si ça ne fonctionne pas pour les versions inférieures.</p>
<p>Tout d&#8217;abord, le StrictMode s&#8217;applique uniquement dans les méthodes onCreate(), donc les classes de type Activity, Application et tout autre objet ayant une méthode onCreate.</p>
<p>L&#8217;ensemble des informations que nous allons avoir besoin se trouve dans la classe StrictMode fournie par Google.</p>
<p>Au niveau OS nous utiliserons la méthode suivante</p>
<blockquote>
<pre>public static void setThreadPolicy (<a href="../../../reference/android/os/StrictMode.ThreadPolicy.html">StrictMode.ThreadPolicy</a> policy)</pre>
</blockquote>
<p>Au niveau de la VM nous utiliserons la méthode suivante</p>
<blockquote>
<pre>public static void setVmPolicy (<a href="../../../reference/android/os/StrictMode.VmPolicy.html">StrictMode.VmPolicy</a> policy)</pre>
</blockquote>
<p>Voici un exemple pour la détection au niveau OS</p>
<pre class="brush: java; title: ; notranslate">
    	StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
    	.detectAll() 	// On détecte tout
    	.penaltyDialog()   // On retourne les informations dans les logs
    	.build());
</pre>
<p>Au commence par détecter toutes les formes de violations, on affiche les violations dans une popup.</p>
<p>Types de violation (Doc Google)</p>
<blockquote><p>detectAll() &#8211; Detect everything that&#8217;s potentially suspect.<br />
detectCustomSlowCalls() &#8211; Enable detection of disk reads.<br />
detectDiskReads() &#8211; Enable detection of disk reads.<br />
detectDiskWrites() &#8211; Enable detection of disk writes.</p></blockquote>
<p>Retour sur les violations (Doc Google)</p>
<blockquote><p>penaltyDeath() &#8211; Crash the whole process on violation.<br />
penaltyDeathOnNetwork() &#8211; Crash the whole process on any network usage.<br />
penaltyDialog()- Show an annoying dialog to the developer on detected violations, rate-limited to be only a little annoying.<br />
penaltyDropBox() &#8211; Enable detected violations log a stacktrace and timing data to the DropBox on policy violation.<br />
penaltyFlashScreen() &#8211; Flash the screen during a violation.<br />
penaltyLog() &#8211; Log detected violations to the system log.</p></blockquote>
<p>Voici un exemple pour la détection au niveau del a VM</p>
<pre class="brush: java; title: ; notranslate">
    	StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
    	.detectAll()  // On détecte tout
    	.penaltyLog() // On retourne les informations dans les logs
    	.build());
</pre>
<p>Au commence par détecter toutes les formes de violations, on affiche les violations dans une popup.</p>
<p>Types de violation (Doc Google)</p>
<blockquote><p>detectAll() &#8211; Detect everything that&#8217;s potentially suspect.<br />
detectActivityLeaks() &#8211; Detect leaks of Activity subclasses.<br />
detectLeakedClosableObjects() &#8211; Detect when an Closeable or other object with a explict termination method is finalized without having been closed.<br />
detectLeakedSqlLiteObjects() &#8211; Detect when an SQLiteCursor or other SQLite object is finalized without having been closed.</p></blockquote>
<p>Retour sur les violations (Doc Google)</p>
<blockquote><p>penaltyDeath() &#8211; Crash the whole process on violation.<br />
penaltyDropBox() &#8211; Enable detected violations log a stacktrace and timing data to the DropBox on policy violation.<br />
penaltyLog() &#8211; Log detected violations to the system log.</p></blockquote>
<p>Voici ce que vous pouvez avoir si vous souhaitez accéder a internet sans internet.</p>
<p><a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2012/01/device-2012-01-16-142834.png" rel="lightbox[551]"><img class="aligncenter size-full wp-image-554" title="Violation" src="http://www.ace-art.fr/wordpress/wp-content/uploads/2012/01/device-2012-01-16-142834.png" alt="" width="240" height="320" /></a></p>
<p>Je vous conseil vivement d&#8217;utiliser ce petit outils dans vos applications pour améliorer celles-ci.</p>
<a class="wpptopdf" target="_blank" rel="noindex,nofollow" href="http://www.ace-art.fr/wordpress/2012/01/16/tutoriel-android-partie-17-strictmode/?format=pdf" title="Download PDF"><img alt="Download PDF" src="http://www.ace-art.fr/wordpress/wp-content/plugins/wp-post-to-pdf/asset/images/pdf.png"></a><fb:like href='http://www.ace-art.fr/wordpress/2012/01/16/tutoriel-android-partie-17-strictmode/' send='false' layout='standard' show_faces='true' width='450' height='65' action='like' colorscheme='light' font='lucida+grande'></fb:like>]]></content:encoded>
			<wfw:commentRss>http://www.ace-art.fr/wordpress/2012/01/16/tutoriel-android-partie-17-strictmode/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Un blog sur les technos MS .Net et Silverlight</title>
		<link>http://www.ace-art.fr/wordpress/2011/11/25/un-blog-sur-les-technos-ms-net-et-silverlight/</link>
		<comments>http://www.ace-art.fr/wordpress/2011/11/25/un-blog-sur-les-technos-ms-net-et-silverlight/#comments</comments>
		<pubDate>Fri, 25 Nov 2011 19:49:17 +0000</pubDate>
		<dc:creator>Pierre-Emmanuel Mercier</dc:creator>
				<category><![CDATA[Non classé]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[dotnet]]></category>
		<category><![CDATA[liens]]></category>
		<category><![CDATA[silverlight]]></category>

		<guid isPermaLink="false">http://www.ace-art.fr/wordpress/?p=542</guid>
		<description><![CDATA[On m&#8217;a fait part d&#8217;un blog aujourd&#8217;hui, après consultation il s&#8217;avère plus qu&#8217;intéressant. On y retrouve des exemples,des news, des tutoriaux sur le monde du dotnet et Silverlight. Je vous invites à le consulter de toute urgence si vous êtes désireux d&#8217;explorer cette voie. Stéphane Louge est l&#8217;éditeur de ce blog et je le remercie pour le travail qu&#8217;il accomplit. http://slouge.wordpress.com/ &#160;]]></description>
			<content:encoded><![CDATA[<p>On m&#8217;a fait part d&#8217;un blog aujourd&#8217;hui, après consultation il s&#8217;avère plus qu&#8217;intéressant.</p>
<p>On y retrouve des exemples,des news, des tutoriaux sur le monde du dotnet et Silverlight.</p>
<p>Je vous invites à le consulter de toute urgence si vous êtes désireux d&#8217;explorer cette voie.</p>
<p>Stéphane Louge est l&#8217;éditeur de ce blog et je le remercie pour le travail qu&#8217;il accomplit.</p>
<p><a href="http://slouge.wordpress.com/">http://slouge.wordpress.com/</a></p>
<p>&nbsp;</p>
<a class="wpptopdf" target="_blank" rel="noindex,nofollow" href="http://www.ace-art.fr/wordpress/2011/11/25/un-blog-sur-les-technos-ms-net-et-silverlight/?format=pdf" title="Download PDF"><img alt="Download PDF" src="http://www.ace-art.fr/wordpress/wp-content/plugins/wp-post-to-pdf/asset/images/pdf.png"></a><fb:like href='http://www.ace-art.fr/wordpress/2011/11/25/un-blog-sur-les-technos-ms-net-et-silverlight/' send='false' layout='standard' show_faces='true' width='450' height='65' action='like' colorscheme='light' font='lucida+grande'></fb:like>]]></content:encoded>
			<wfw:commentRss>http://www.ace-art.fr/wordpress/2011/11/25/un-blog-sur-les-technos-ms-net-et-silverlight/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Créer un émulateur de console</title>
		<link>http://www.ace-art.fr/wordpress/2011/10/25/creer-un-emulateur-de-console/</link>
		<comments>http://www.ace-art.fr/wordpress/2011/10/25/creer-un-emulateur-de-console/#comments</comments>
		<pubDate>Tue, 25 Oct 2011 13:07:52 +0000</pubDate>
		<dc:creator>Pierre-Emmanuel Mercier</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[emulation]]></category>
		<category><![CDATA[sdz]]></category>

		<guid isPermaLink="false">http://www.ace-art.fr/wordpress/?p=500</guid>
		<description><![CDATA[Tout le monde connait les émulateur de console, mais avez déjà eu l&#8217;idée dans développer un ? Pour un développeur lambda il est très difficile de comprendre le fonctionnement pour recréer une console, certaines demandant de simuler que quelques Mhz voir Hz de processeur pour faire fonctionner correctement un l&#8217;émulateur. Maintenant c&#8217;est chose faites ! BestCoder du site du zéro a écrit un très bon article la dessus, pas à pas il vous aidera a [...]]]></description>
			<content:encoded><![CDATA[<p>Tout le monde connait les émulateur de console, mais avez déjà eu l&#8217;idée dans développer un ?</p>
<p>Pour un développeur lambda il est très difficile de comprendre le fonctionnement pour recréer une console, certaines demandant de simuler que quelques Mhz voir Hz de processeur pour faire fonctionner correctement un l&#8217;émulateur.</p>
<p>Maintenant c&#8217;est chose faites ! BestCoder du site du zéro a écrit un très bon article la dessus, pas à pas il vous aidera a créer votre premier émulateur pour RCA.</p>
<p>Je vous conseilles d&#8217;aller faire un tour ici, vous n&#8217;en serez que plus ravis.</p>
<p><a href="http://www.siteduzero.com/tutoriel-3-555021-l-emulation-console.html">http://www.siteduzero.com/tutoriel-3-555021-l-emulation-console.html</a></p>
<p>Ps : Ne vous jetez pas sur l&#8217;émulation des consoles NextGen ou GB / GameGear etc&#8230; l&#8217;approche est beaucoup plus difficile qu&#8217;il n&#8217;y paraît <img src='http://www.ace-art.fr/wordpress/wp-content/plugins/smilies-themer/Nomicons v2.0/wink.png' alt=':wink:' class='wp-smiley' /> </p>
<a class="wpptopdf" target="_blank" rel="noindex,nofollow" href="http://www.ace-art.fr/wordpress/2011/10/25/creer-un-emulateur-de-console/?format=pdf" title="Download PDF"><img alt="Download PDF" src="http://www.ace-art.fr/wordpress/wp-content/plugins/wp-post-to-pdf/asset/images/pdf.png"></a><fb:like href='http://www.ace-art.fr/wordpress/2011/10/25/creer-un-emulateur-de-console/' send='false' layout='standard' show_faces='true' width='450' height='65' action='like' colorscheme='light' font='lucida+grande'></fb:like>]]></content:encoded>
			<wfw:commentRss>http://www.ace-art.fr/wordpress/2011/10/25/creer-un-emulateur-de-console/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Tutoriel Android] Partie 16 &#8211; Base de données</title>
		<link>http://www.ace-art.fr/wordpress/2011/10/08/tutoriel-android-partie-16-base-de-donnees/</link>
		<comments>http://www.ace-art.fr/wordpress/2011/10/08/tutoriel-android-partie-16-base-de-donnees/#comments</comments>
		<pubDate>Sat, 08 Oct 2011 15:45:16 +0000</pubDate>
		<dc:creator>Pierre-Emmanuel Mercier</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Programmation]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[base de données]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[tutoriel]]></category>

		<guid isPermaLink="false">http://www.ace-art.fr/wordpress/?p=472</guid>
		<description><![CDATA[Bonjour à tous, Nous allons aborder aujourd’hui la conception d’une application reposant sur les bases de données. Les bases de données sont un moyen de stocker une donnée dans un format que vous aurez choisi, le stockage est de façon permanent. Vous pouvez aussi stocker les données au format Xml, texte, json etc… Ce tutoriel portera uniquement sur le stockage avec le langage SQL voir la Définition SQL. Android propose utilise le moteur SQL nommé [...]]]></description>
			<content:encoded><![CDATA[<p>Bonjour à tous,</p>
<p>Nous allons aborder aujourd’hui la conception d’une application reposant sur les bases de données.</p>
<p>Les bases de données sont un moyen de stocker une donnée dans un format que vous aurez choisi, le stockage est de façon permanent.</p>
<p>Vous pouvez aussi stocker les données au format Xml, texte, json etc…</p>
<p>Ce tutoriel portera uniquement sur le stockage avec le langage SQL voir la <a href="http://fr.wikipedia.org/wiki/Structured_Query_Language" target="_blank">Définition SQL</a>.</p>
<p>Android propose utilise le moteur SQL nommé SQLite voir sa <a href="http://fr.wikipedia.org/wiki/SQLite" target="_blank">Définition</a>.</p>
<p>Le moteur SQLite accepte les types suivants de données</p>
<table style="width: 400px;" border="0" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td valign="top" width="200"><strong>Type</strong></td>
<td valign="top" width="200"><strong>Définition</strong></td>
</tr>
<tr>
<td valign="top" width="200">NULL</td>
<td valign="top" width="200">Valeur vide</td>
</tr>
<tr>
<td valign="top" width="200">INTEGER</td>
<td valign="top" width="200">Entier signé</td>
</tr>
<tr>
<td valign="top" width="200">REAL</td>
<td valign="top" width="200">Nombre réel</td>
</tr>
<tr>
<td valign="top" width="200">TEXT</td>
<td valign="top" width="200">Champ texte</td>
</tr>
<tr>
<td valign="top" width="200">BLOB</td>
<td valign="top" width="200">Champ binaire</td>
</tr>
</tbody>
</table>
<p>Le type boolean n’est qu’un entier ayant pour valeur 0 et 1</p>
<p>Pour les dates il y a plusieurs manières de procéder</p>
<ul>
<li>Dans un champ TEXT : Format YYYY-MM-DD HH:MM:SS.SSS</li>
<li>Dans un champ REAL : Nombre de jour depuis Greenwich le 24 Novembre 4714 avant J.C</li>
<li>Dans un champ INTEGER : Nombre de seconde depuis le 01/01/1970 soit la date au format UNIX</li>
</ul>
<p>Ne vous inquiétez pas SQLite possède des fonctions pour manipuler les dates.</p>
<p><span id="more-472"></span></p>
<h2>Définition du projet</h2>
<p>Nous allons créer une application pour faire nos courses, ça nous permettra d’avoir un contexte de compréhension.</p>
<p>Tout d’abord, il faut penser au format des données.</p>
<p>Dans notre cas une course sera :</p>
<ul>
<li>Un produit</li>
<li>Une quantité</li>
<li>Un flag acheté (pour suivre notre avancement dans le magasin)</li>
</ul>
<p>Nous devrons pouvoir Ajouter / Supprimer / Modifier un produit, ainsi que lister les produits.</p>
<p>Nous avons désormais notre contexte pour travailler, il faut maintenant coder tout cela.</p>
<p>Commençons par créer notre objet Course</p>
<pre class="brush: java; title: ; notranslate">
public class Course {

	private int id;
	private String produit;
	private int quantite;
	private boolean achete;

	public Course(String produit, int quantite) {
		this.produit = produit;
		this.quantite = quantite;
		this.achete = false;
	}

	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getProduit() {
		return produit;
	}
	public void setProduit(String produit) {
		this.produit = produit;
	}
	public int getQuantite() {
		return quantite;
	}
	public void setQuantite(int quantite) {
		this.quantite = quantite;
	}
	public boolean isAchete() {
		return achete;
	}
	public void setAchete(boolean achete) {
		this.achete = achete;
	}

}
</pre>
<p>Abordons maintenant l&#8217;utilisation des bases de données.</p>
<h2>SQLiteOpenHelper</h2>
<p>Le but de cette classe est de permettre la création et l&#8217;utilisation des bases de données au sein de l’écosystème Android.</p>
<p>Commençons tout d&#8217;abord par créer une classe nommée <strong>CourseOpenHelper</strong> héritant de la classe <strong>SQLiteOpenHelper</strong>.</p>
<p>Puis nous allons rajouter des attributs statiques à notre classe</p>
<pre class="brush: java; title: ; notranslate">
	// Version de la base de données
	private static final int DATABASE_VERSION = 1;

	// Nom de la base
	private static final String COURSE_BASE_NAME = &quot;course.db&quot;;

	// Nom de la table
	public static final String COURSE_TABLE_NAME = &quot;Course&quot;;

	// Description des colonnes
	public static final String COLUMN_ID = &quot;ID&quot;;
	public static final int NUM_COLUMN_ID = 0;
	public static final String COLUMN_PRODUIT = &quot;PRODUIT&quot;;
	public static final int NUM_COLUMN_PRODUIT = 1;
	public static final String COLUMN_QUANTITE = &quot;QUANTITE&quot;;
	public static final int NUM_COLUMN_QUANTITE = 2;
	public static final String COLUMN_ACHETE = &quot;ACHETE&quot;;
	public static final int NUM_COLUMN_ACHETE = 3;

	// Requête SQL pour la création da la base
	private static final String REQUETE_CREATION_BDD = &quot;CREATE TABLE &quot;
			+ COURSE_TABLE_NAME + &quot; (&quot; + COLUMN_ID
			+ &quot; INTEGER PRIMARY KEY AUTOINCREMENT, &quot; + COLUMN_PRODUIT
			+ &quot; TEXT NOT NULL, &quot; + COLUMN_QUANTITE + &quot; INTEGER NOT NULL, &quot;
			+ COLUMN_ACHETE + &quot; INTEGER NOT NULL);&quot;;
</pre>
<p>Nous avons donc :</p>
<ul>
<li><span class="Apple-style-span" style="line-height: 18px;">Version de la base de données (pour les mises à jour)</span></li>
<li><span class="Apple-style-span" style="line-height: 18px;">Nom de la base (nom du fichier)</span></li>
<li><span class="Apple-style-span" style="line-height: 18px;">Nom de la table (Course pour nous)</span></li>
<li><span class="Apple-style-span" style="line-height: 18px;">Description des colonnes, ainsi que leur position (0..n)</span></li>
<li><span class="Apple-style-span" style="line-height: 18px;">La requête de création de la base</span></li>
</ul>
<div><span class="Apple-style-span" style="line-height: 18px;">Et pour finir nos méthodes</span></div>
<pre class="brush: java; title: ; notranslate">
	public CourseOpenHelper(Context context, CursorFactory factory) {
		super(context, COURSE_BASE_NAME, factory, DATABASE_VERSION);
	}

	/**
	 * Création de la base
	 */
	@Override
	public void onCreate(SQLiteDatabase db) {
		db.execSQL(REQUETE_CREATION_BDD);
	}

	/**
	 * Mise à jour de la base
	 */
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// Lorsque l'on change le numéro de version de la base on supprime la
		// table puis on la recrée
		if (newVersion &gt; DATABASE_VERSION) {
			db.execSQL(&quot;DROP TABLE &quot; + COURSE_TABLE_NAME + &quot;;&quot;);
			onCreate(db);
		}
	}
</pre>
<p>Notre méthode onCreate sera appelée si la base n&#8217;existe pas, la méthode onUpgrade sera appelée si une mise à jour est à faire.</p>
<p>J&#8217;espère que vous suivez toujours   <img src='http://www.ace-art.fr/wordpress/wp-content/plugins/smilies-themer/Nomicons v2.0/smile.png' alt=':smile:' class='wp-smiley' /> </p>
<h2>Repository</h2>
<p>Vous en avez peut être déjà entendu parler, en français c&#8217;est un dépôt. Il sert à faire la jonction avec notre base de données.</p>
<p>Comme ça en cas d&#8217;évolution on n&#8217;impacte pas la vue (layout) si ce n&#8217;est qu&#8217;un correctif ou une modification de la façon d&#8217;allez chercher nos données, c&#8217;est tout de même plus propre et je vous le conseil fortement.</p>
<p>Créons pour commencer une interface nommée IRepository qui sera générique (gné ?) <a href="http://www.siteduzero.com/tutoriel-3-10421-la-genericite-en-java.html" target="_blank">voir ce tutoriel </a></p>
<pre class="brush: java; title: ; notranslate">
public interface IRepository {

	public List GetAll();
	public T GetById(int id);

	public void Save(T entite);
	public void Update(T entite);
	public void Delete(int id);

	public List ConvertCursorToListObject(Cursor c);
	public T ConvertCursorToObject(Cursor c);
	public T ConvertCursorToOneObject(Cursor c);
}
</pre>
<p>Alors nos méthodes :</p>
<ul>
<li><span class="Apple-style-span" style="line-height: 18px;">GetAll : Retourne la liste des données</span></li>
<li><span class="Apple-style-span" style="line-height: 18px;">GetById : Retourne un objet unique</span></li>
<li><span class="Apple-style-span" style="line-height: 18px;">Save : Enregistre un objet</span></li>
<li><span class="Apple-style-span" style="line-height: 18px;">Update : Met à jour un objet</span></li>
<li><span class="Apple-style-span" style="line-height: 18px;">Delete : Supprime un objet</span></li>
<li><span class="Apple-style-span" style="line-height: 18px;">ConvertCursorToListObject : Converti un curseur en une liste d&#8217;objet</span></li>
<li><span class="Apple-style-span" style="line-height: 18px;">ConvertCursorToObject : Converti un curseur en un objet</span></li>
<li><span class="Apple-style-span" style="line-height: 18px;">ConvertCursorToOneObject : Converti un curseur en un seul objet</span></li>
</ul>
<div><span class="Apple-style-span" style="line-height: 18px;">En suite il va nous falloir la base de notre Repository</span></div>
<div>Toujours une classe générique mais abstraite</div>
<pre class="brush: java; title: ; notranslate">
public abstract class Repository implements IRepository {
	// Base de données
	protected SQLiteDatabase maBDD;

	protected SQLiteOpenHelper sqLiteOpenHelper;

	/**
	 * Constructeur par défaut
	 */
	public Repository() {

	}

	/**
	 * Ouverture de la connection
	 */
	public void Open() {
		maBDD = sqLiteOpenHelper.getWritableDatabase();
	}

	/**
	 * Fermeture de la connection
	 */
	public void Close() {
		maBDD.close();
	}
}
</pre>
<p>Cette classe comprend deux méthodes et deux attributs.</p>
<p>Attributs :</p>
<ul>
<li><span class="Apple-style-span" style="line-height: 18px;">maBDD : Relation avec la base de données SQLite</span></li>
<li><span class="Apple-style-span" style="line-height: 18px;">sqLiteOpenHelper : Notre helper pour traiter avec la base</span></li>
</ul>
<div><span class="Apple-style-span" style="line-height: 18px;">Méthodes :</span></div>
<div>
<ul>
<li><span class="Apple-style-span" style="line-height: normal;">Constructeur</span></li>
<li><span class="Apple-style-span" style="line-height: normal;">Open : Permet d&#8217;ouvrir la liaison avec la base</span></li>
<li><span class="Apple-style-span" style="line-height: normal;">Close : Ferme la liaison</span></li>
</ul>
</div>
<div>Pour terminer implémentons notre CourseRepository</div>
<pre class="brush: java; title: ; notranslate">
public class CourseRepository extends Repository {

	public CourseRepository(Context context) {
		sqLiteOpenHelper = new CourseOpenHelper(context, null);
	}

	/**
	 * Suppression d'un produit
	 *
	 * @param id
	 */
	public void DeleteProduit(int id) {
		maBDD.delete(CourseOpenHelper.COURSE_TABLE_NAME,
				CourseOpenHelper.COLUMN_ID + &quot;=?&quot;,
				new String[] { String.valueOf(id) });
	}

	/**
	 * Récupération de la liste de tous les produits
	 */
	@Override
	public List GetAll() {
		// Récupération de la liste des courses
		Cursor cursor = maBDD.query(CourseOpenHelper.COURSE_TABLE_NAME,
				new String[] { CourseOpenHelper.COLUMN_ID,
						CourseOpenHelper.COLUMN_PRODUIT,
						CourseOpenHelper.COLUMN_QUANTITE,
						CourseOpenHelper.COLUMN_ACHETE }, null, null, null,
				null, null);

		return ConvertCursorToListObject(cursor);
	}

	/**
	 * Retourne un seul produit
	 */
	@Override
	public Course GetById(int id) {
		Cursor cursor = maBDD.query(CourseOpenHelper.COURSE_TABLE_NAME,
				new String[] { CourseOpenHelper.COLUMN_ID,
						CourseOpenHelper.COLUMN_PRODUIT,
						CourseOpenHelper.COLUMN_QUANTITE,
						CourseOpenHelper.COLUMN_ACHETE },
				CourseOpenHelper.COLUMN_ID + &quot;=?&quot;,
				new String[] { String.valueOf(id) }, null, null, null);

		return ConvertCursorToObject(cursor);
	}

	/**
	 * Enregistre en produit dans la base
	 */
	@Override
	public void Save(Course entite) {
		ContentValues contentValues = new ContentValues();
		contentValues.put(CourseOpenHelper.COLUMN_PRODUIT, entite.getProduit());
		contentValues.put(CourseOpenHelper.COLUMN_QUANTITE,
				entite.getQuantite());
		contentValues.put(CourseOpenHelper.COLUMN_ACHETE, entite.isAchete());

		maBDD.insert(CourseOpenHelper.COURSE_TABLE_NAME, null, contentValues);
	}

	/**
	 * Met à jour un produit
	 */
	@Override
	public void Update(Course entite) {
		ContentValues contentValues = new ContentValues();
		contentValues.put(CourseOpenHelper.COLUMN_PRODUIT, entite.getProduit());
		contentValues.put(CourseOpenHelper.COLUMN_QUANTITE,
				entite.getQuantite());
		contentValues.put(CourseOpenHelper.COLUMN_ACHETE, entite.isAchete());

		maBDD.update(CourseOpenHelper.COURSE_TABLE_NAME, contentValues,
				CourseOpenHelper.COLUMN_ID + &quot;=?&quot;,
				new String[] { String.valueOf(entite.getId()) });
	}

	/**
	 * Supprime un produit
	 */
	@Override
	public void Delete(int id) {
		maBDD.delete(CourseOpenHelper.COURSE_TABLE_NAME,
				CourseOpenHelper.COLUMN_ID + &quot;=?&quot;,
				new String[] { String.valueOf(id) });
	}

	/**
	 * Converti un curseur en une liste de produits
	 */
	@Override
	public List ConvertCursorToListObject(Cursor c) {
		List liste = new ArrayList();

		// Si la liste est vide
		if (c.getCount() == 0)
			return liste;

		// position sur le premeir item
		c.moveToFirst();

		// Pour chaque item
		do {

			Course course = ConvertCursorToObject(c);

			liste.add(course);
		} while (c.moveToNext());

		// Fermeture du curseur
		c.close();

		return liste;
	}

	/**
	 * Méthode utilisée par ConvertCursorToObject et ConvertCursorToListObject
	 */
	@Override
	public Course ConvertCursorToObject(Cursor c) {

		Course course = new Course(
				c.getString(CourseOpenHelper.NUM_COLUMN_PRODUIT),
				c.getInt(CourseOpenHelper.NUM_COLUMN_QUANTITE));
		course.setId(c.getInt(CourseOpenHelper.NUM_COLUMN_ID));
		course.setAchete((c.getInt(CourseOpenHelper.NUM_COLUMN_ACHETE) != 0));

		return course;
	}

	/**
	 * Converti un curseur en un produit
	 */
	@Override
	public Course ConvertCursorToOneObject(Cursor c) {
		c.moveToFirst();

		Course course = ConvertCursorToObject(c);

		c.close();
		return course;
	}
}
</pre>
<p>Oulala c&#8217;est du lourd !</p>
<p>Pour mieux comprendre, toutes actions effectuées de type Get en base (retour d&#8217;un ou plusieurs objets) retourne un curseur.</p>
<p>Ce curseur comprend l’intégralité de ce que vous avez demandé, il faut juste passer sur chaque ligne retournée pour l&#8217;affectée à un objet, dans notre cas un objet Course.</p>
<p>Pour faire un Save, Delete, Update, GetAll ou encore GetById on utilise simplement une commande fournie par Android.</p>
<ul>
<li><span class="Apple-style-span" style="line-height: 18px;">GetAll / GetById : Query (<a href="/reference/java/lang/String.html">String</a> table, <a href="/reference/java/lang/String.html">String[]</a> columns, <a href="/reference/java/lang/String.html">String</a> selection, <a href="/reference/java/lang/String.html">String[]</a> selectionArgs, <a href="/reference/java/lang/String.html">String</a> groupBy, <a href="/reference/java/lang/String.html">String</a> having, <a href="/reference/java/lang/String.html">String</a> orderBy)</span></li>
<li><span class="Apple-style-span" style="line-height: 18px;">Save : Insert (<a href="/reference/java/lang/String.html">String</a> table, <a href="/reference/java/lang/String.html">String</a> nullColumnHack, <a href="/reference/android/content/ContentValues.html">ContentValues</a> values)</span></li>
<li><span class="Apple-style-span" style="line-height: 18px;">Update : Update (<a href="/reference/java/lang/String.html">String</a> table, <a href="/reference/android/content/ContentValues.html">ContentValues</a> values, <a href="/reference/java/lang/String.html">String</a> whereClause, <a href="/reference/java/lang/String.html">String[]</a> whereArgs)</span></li>
<li><span class="Apple-style-span" style="line-height: 18px;">Delete : Delete (<a href="/reference/java/lang/String.html">String</a> table, <a href="/reference/java/lang/String.html">String</a> whereClause, <a href="/reference/java/lang/String.html">String[]</a> whereArgs)</span></li>
</ul>
<p>Dans le cas d&#8217;un Save,Delete,Update nous utiliserons un objet ContentValues qui transportera nos données.</p>
<p>Enfin de compte il n&#8217;y a rien de plus simple !</p>
<p>N&#8217;oubliez pas de refermer vos curseurs après utilisations (c&#8217;est comme les BIC , sinon ça sèche).</p>
<p>De plus n&#8217;oubliez pas d&#8217;ouvrir votre connexion avec la base avant un traitement et de la refermée ensuite.</p>
<p>Exemple :</p>
<pre class="brush: java; title: ; notranslate">
public void DeleteItem(int id) {
	courseRepository.Open();
	courseRepository.Delete(id);
	courseRepository.Close();
}</pre>
<p>Je n&#8217;expliquerais pas le programme au complet, car la suite ce n&#8217;est qu&#8217;une Listview, un menu et des boutons (déjà vu dans les autres chapitres).</p>
<p>Mais voici ce que vous devriez avoir à la fin  <img src='http://www.ace-art.fr/wordpress/wp-content/plugins/smilies-themer/Nomicons v2.0/happy.png' alt=':happy:' class='wp-smiley' /> </p>
<table border="0">
<tbody>
<tr>
<td><a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/10/db-1.png" rel="lightbox[472]"><img class="aligncenter size-medium wp-image-487" title="db-1" src="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/10/db-1-180x300.png" alt="" width="180" height="300" /></a></td>
<td><a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/10/db-2.png" rel="lightbox[472]"><img class="aligncenter size-medium wp-image-488" title="db-2" src="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/10/db-2-180x300.png" alt="" width="180" height="300" /></a></td>
</tr>
<tr>
<td> <a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/10/db-3.png" rel="lightbox[472]"><img class="aligncenter size-medium wp-image-489" title="db-3" src="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/10/db-3-180x300.png" alt="" width="180" height="300" /></a></td>
<td> <a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/10/db-4.png" rel="lightbox[472]"><img class="aligncenter size-medium wp-image-490" title="db-4" src="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/10/db-4-180x300.png" alt="" width="180" height="300" /></a></td>
</tr>
</tbody>
</table>
<p>Source : <a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/10/FormationDatabase.zip">Sources de la formation</a></p>
<a class="wpptopdf" target="_blank" rel="noindex,nofollow" href="http://www.ace-art.fr/wordpress/2011/10/08/tutoriel-android-partie-16-base-de-donnees/?format=pdf" title="Download PDF"><img alt="Download PDF" src="http://www.ace-art.fr/wordpress/wp-content/plugins/wp-post-to-pdf/asset/images/pdf.png"></a><fb:like href='http://www.ace-art.fr/wordpress/2011/10/08/tutoriel-android-partie-16-base-de-donnees/' send='false' layout='standard' show_faces='true' width='450' height='65' action='like' colorscheme='light' font='lucida+grande'></fb:like>]]></content:encoded>
			<wfw:commentRss>http://www.ace-art.fr/wordpress/2011/10/08/tutoriel-android-partie-16-base-de-donnees/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>[Tutoriel Android] Partie 15 &#8211; Expandable List</title>
		<link>http://www.ace-art.fr/wordpress/2011/10/07/tutoriel-android-partie-15-expandable-list/</link>
		<comments>http://www.ace-art.fr/wordpress/2011/10/07/tutoriel-android-partie-15-expandable-list/#comments</comments>
		<pubDate>Fri, 07 Oct 2011 11:44:05 +0000</pubDate>
		<dc:creator>Pierre-Emmanuel Mercier</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Programmation]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[liste]]></category>
		<category><![CDATA[tutoriel]]></category>

		<guid isPermaLink="false">http://www.ace-art.fr/wordpress/?p=447</guid>
		<description><![CDATA[Aujourd’hui nous allons voir comment créer une ExpandableListView. Ce tutoriel s’inscrit dans la lignée du billet suivante : ListView Pré requis : Projet Android 1.6+ Avoir lu le tutoriel sur les listview Nous allons débuter ce cours par une approche simple du fonctionnement des ExpandableListView Voici notre modèle logique, un Groupe peut contenir 1:n enfants. De ce fait nous allons commencer par créer nos objets de la même manière Nous avons notre classe Groupe qui [...]]]></description>
			<content:encoded><![CDATA[<p>Aujourd’hui nous allons voir comment créer une ExpandableListView.</p>
<p>Ce tutoriel s’inscrit dans la lignée du billet suivante : <a href="http://www.ace-art.fr/wordpress/2010/07/21/tutoriel-android-partie-6-les-listview/" target="_blank">ListView</a></p>
<h2>Pré requis :</h2>
<ul>
<li>Projet Android 1.6+</li>
<li>Avoir lu le tutoriel sur les listview</li>
</ul>
<p>Nous allons débuter ce cours par une approche simple du fonctionnement des ExpandableListView</p>
<p><a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/10/image.png" rel="lightbox[447]"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px; border-width: 0px;" title="image" src="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/10/image_thumb.png" alt="image" width="364" height="216" border="0" /></a></p>
<p>Voici notre modèle logique, un Groupe peut contenir 1:n enfants.</p>
<p><span id="more-447"></span></p>
<p>De ce fait nous allons commencer par créer nos objets de la même manière</p>
<pre class="brush: java; title: ; notranslate">package com.formation.Testexpandable;

import java.util.ArrayList;

public class Groupe {
	private String nom;
	private ArrayList&lt;Objet&gt; objets;

	public Groupe(String nom) {
		super();
		this.nom = nom;
		this.objets = new ArrayList&lt;Objet&gt;();
	}

	public String getNom() {
		return nom;
	}

	public void setNom(String nom) {
		this.nom = nom;
	}

	public ArrayList&lt;Objet&gt; getObjets() {
		return objets;
	}

	public void setObjets(ArrayList&lt;Objet&gt; objets) {
		this.objets = objets;
	}

}</pre>
<p>Nous avons notre classe Groupe qui contiendra une liste d&#8217;enfant (objet), ainsi qu&#8217;un nom.</p>
<pre class="brush: java; title: ; notranslate">package com.formation.Testexpandable;

public class Objet {

	private Groupe groupe;
	private String nom;

	public Objet(Groupe groupe, String nom) {
		super();
		this.groupe = groupe;
		this.nom = nom;
	}

	public Groupe getGroupe() {
		return groupe;
	}

	public void setGroupe(Groupe groupe) {
		this.groupe = groupe;
	}

	public String getNom() {
		return nom;
	}

	public void setNom(String nom) {
		this.nom = nom;
	}

}</pre>
<p>Notre classe enfant (objet) contenue dans le groupe, elle contient un nom et est affilée à un groupe.</p>
<p>Nous allons remplir nos objets en vue de les afficher.</p>
<pre class="brush: java; title: ; notranslate">package com.formation.Testexpandable;

import java.util.ArrayList;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ExpandableListView;

public class TestexpandableActivity extends Activity {

	private ExpandableListView expandableList = null;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		expandableList = (ExpandableListView) findViewById(R.id.expandableView);

		ArrayList&lt;Groupe&gt; groupes = new ArrayList&lt;Groupe&gt;();

		for (int i = 1; i &lt; 10; i++) {

			Groupe groupe = new Groupe(&quot;Groupe &quot; + i);

			ArrayList&lt;Objet&gt; donnees = new ArrayList&lt;Objet&gt;();

			for (int x = 1; x &lt; 10; x++) {
				donnees.add(new Objet(groupe, &quot;Objet &quot; + x));
			}

			groupe.setObjets(donnees);

			groupes.add(groupe);
		}
	}
}
</pre>
<p>Continuons en créant nos layout</p>
<p>Main.xml</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
	android:orientation=&quot;vertical&quot;
	android:layout_width=&quot;fill_parent&quot;
	android:layout_height=&quot;fill_parent&quot;&gt;

	&lt;ExpandableListView android:id=&quot;@+id/expandableView&quot; android:layout_width=&quot;match_parent&quot; android:layout_height=&quot;match_parent&quot; &gt;
	&lt;/ExpandableListView&gt;
&lt;/LinearLayout&gt;
</pre>
<p>Notre entête pour les groupes</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;

&lt;TextView xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
	android:id=&quot;@+id/TVGroup&quot;
	android:text=&quot;Groupe&quot;
	android:layout_width=&quot;match_parent&quot;
	android:layout_height=&quot;?android:attr/listPreferredItemHeight&quot;
	android:gravity=&quot;center_vertical&quot;
	android:paddingLeft=&quot;?android:attr/expandableListPreferredItemPaddingLeft&quot;
	android:textAppearance=&quot;?android:attr/textAppearanceLarge&quot;/&gt;
</pre>
<p>Puis nos enfants</p>
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout
  xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
  android:orientation=&quot;horizontal&quot;
  android:layout_width=&quot;match_parent&quot;
  android:layout_height=&quot;wrap_content&quot;&gt;

    &lt;Button android:id=&quot;@+id/BTChild&quot; android:text=&quot;1&quot; android:layout_width=&quot;wrap_content&quot; android:layout_height=&quot;wrap_content&quot;/&gt;

    &lt;TextView android:id=&quot;@+id/TVChild&quot; android:text=&quot;test&quot; android:layout_width=&quot;match_parent&quot; android:layout_height=&quot;wrap_content&quot;/&gt;

&lt;/LinearLayout&gt;
</pre>
<p>Pour terminer nous allons créer un adapteur pour gérer notre liste.<br />
Pour cela nous allons hériter de la classe BaseExpandableListAdapter.</p>
<pre class="brush: java; title: ; notranslate">
package com.formation.Testexpandable;

import java.util.ArrayList;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class ELVAdapter extends BaseExpandableListAdapter {

	private Context context;
	private ArrayList&lt;Groupe&gt; groupes;
	private LayoutInflater inflater;

	public ELVAdapter(Context context, ArrayList&lt;Groupe&gt; groupes) {
		this.context = context;
		this.groupes = groupes;
		inflater = LayoutInflater.from(context);
	}

	@Override
	public boolean areAllItemsEnabled() {
		return true;
	}

	public Object getChild(int gPosition, int cPosition) {
		return groupes.get(gPosition).getObjets().get(cPosition);
	}

	public long getChildId(int gPosition, int cPosition) {
		return cPosition;
	}

	public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
		final Objet objet = (Objet) getChild(groupPosition, childPosition);

		ChildViewHolder childViewHolder;

        if (convertView == null) {
        	childViewHolder = new ChildViewHolder();

            convertView = inflater.inflate(R.layout.group_child, null);

            childViewHolder.textViewChild = (TextView) convertView.findViewById(R.id.TVChild);
            childViewHolder.buttonChild = (Button) convertView.findViewById(R.id.BTChild);

            convertView.setTag(childViewHolder);
        } else {
        	childViewHolder = (ChildViewHolder) convertView.getTag();
        }

        childViewHolder.textViewChild.setText(objet.getNom());

        childViewHolder.buttonChild.setText(objet.getNom());

        childViewHolder.buttonChild.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				Toast.makeText(context, &quot;Groupe : &quot; + objet.getGroupe().getNom() + &quot; - Bouton : &quot; + objet.getNom(), Toast.LENGTH_SHORT).show();
			}
		});

        return convertView;
	}

	public int getChildrenCount(int gPosition) {
		return groupes.get(gPosition).getObjets().size();
	}

	public Object getGroup(int gPosition) {
		return groupes.get(gPosition);
	}

	public int getGroupCount() {
		return groupes.size();
	}

	public long getGroupId(int gPosition) {
		return gPosition;
	}

	public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
		GroupViewHolder gholder;

		Groupe group = (Groupe) getGroup(groupPosition);

        if (convertView == null) {
        	gholder = new GroupViewHolder();

        	convertView = inflater.inflate(R.layout.group_row, null);

        	gholder.textViewGroup = (TextView) convertView.findViewById(R.id.TVGroup);

        	convertView.setTag(gholder);
        } else {
        	gholder = (GroupViewHolder) convertView.getTag();
        }

        gholder.textViewGroup.setText(group.getNom());

        return convertView;
	}

	public boolean hasStableIds() {
		return true;
	}

	public boolean isChildSelectable(int arg0, int arg1) {
		return true;
	}

	class GroupViewHolder {
		public TextView textViewGroup;
	}

	class ChildViewHolder {
		public TextView textViewChild;
		public Button buttonChild;
	}

}
</pre>
<p>Les parties les plus importantes sont getChildView et getGroupView, ces deux méthodes permettent de d&#8217;attacher nos layout a un groupe ou a un objet enfant.</p>
<p>Ne pas oublier le viewHolder, qui permettent d&#8217;avoir de meilleur performances.</p>
<p>Et pour finir notre activité</p>
<pre class="brush: java; title: ; notranslate">
package com.formation.Testexpandable;

import java.util.ArrayList;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ExpandableListView;

public class TestexpandableActivity extends Activity {

	private ExpandableListView expandableList = null;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		expandableList = (ExpandableListView) findViewById(R.id.expandableView);

		ArrayList&lt;Groupe&gt; groupes = new ArrayList&lt;Groupe&gt;();

		for (int i = 1; i &lt; 10; i++) {

			Groupe groupe = new Groupe(&quot;Groupe &quot; + i);

			ArrayList&lt;Objet&gt; donnees = new ArrayList&lt;Objet&gt;();

			for (int x = 1; x &lt; 10; x++) {
				donnees.add(new Objet(groupe, &quot;Objet &quot; + x));
			}

			groupe.setObjets(donnees);

			groupes.add(groupe);
		}

		ELVAdapter adapter = new ELVAdapter(this, groupes);

		expandableList.setAdapter(adapter);
	}
}
</pre>
<p>Voilà vous savez désormais utiliser une ExpandableListView.<br />
Si vous avez suivis le tutoriel sur les ListView, il n&#8217;y a pas grand changement.</p>
<p>Vous devriez avoir ceci maintenant</p>
<p><a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/10/device-2011-10-09-110553.png" rel="lightbox[447]"><img class="aligncenter size-medium wp-image-484" title="Groupes" src="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/10/device-2011-10-09-110553-180x300.png" alt="" width="180" height="300" /></a><a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/10/device-2011-10-09-110612.png" rel="lightbox[447]"><img class="aligncenter size-medium wp-image-485" title="Enfants" src="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/10/device-2011-10-09-110612-180x300.png" alt="" width="180" height="300" /></a></p>
<p>Source de la formation :<a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/10/Testexpandable.zip">Sources de la formation</a></p>
<a class="wpptopdf" target="_blank" rel="noindex,nofollow" href="http://www.ace-art.fr/wordpress/2011/10/07/tutoriel-android-partie-15-expandable-list/?format=pdf" title="Download PDF"><img alt="Download PDF" src="http://www.ace-art.fr/wordpress/wp-content/plugins/wp-post-to-pdf/asset/images/pdf.png"></a><fb:like href='http://www.ace-art.fr/wordpress/2011/10/07/tutoriel-android-partie-15-expandable-list/' send='false' layout='standard' show_faces='true' width='450' height='65' action='like' colorscheme='light' font='lucida+grande'></fb:like>]]></content:encoded>
			<wfw:commentRss>http://www.ace-art.fr/wordpress/2011/10/07/tutoriel-android-partie-15-expandable-list/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Petites statistiques après un an passé ensemble</title>
		<link>http://www.ace-art.fr/wordpress/2011/07/26/petite-statistiques-apres-un-an-passe-ensemble/</link>
		<comments>http://www.ace-art.fr/wordpress/2011/07/26/petite-statistiques-apres-un-an-passe-ensemble/#comments</comments>
		<pubDate>Tue, 26 Jul 2011 11:12:13 +0000</pubDate>
		<dc:creator>Pierre-Emmanuel Mercier</dc:creator>
				<category><![CDATA[Non classé]]></category>
		<category><![CDATA[ace-art]]></category>
		<category><![CDATA[statistique]]></category>

		<guid isPermaLink="false">http://www.ace-art.fr/wordpress/?p=397</guid>
		<description><![CDATA[Bonjour à tous, Je tenais à vous remercier (oui vous cher visiteur), pour cette année passée ensemble, on ne s&#8217;arrête pas la pour autant, mais je tenais à tous vous remercier de venir si nombreux pour consulter le fruit de mon travail (qui vous est dédié bien entendue). Quelques statistiques sur l&#8217;année : 60 487 visites 122 193 pages vues Top 5 des naviguateurs Firefox &#8211; 31 561 Chrome &#8211; 20 174 IE &#8211; 4 [...]]]></description>
			<content:encoded><![CDATA[<p>Bonjour à tous,</p>
<p>Je tenais à vous remercier (oui vous cher visiteur), pour cette année passée ensemble, on ne s&#8217;arrête pas la pour autant, mais je tenais à tous vous remercier de venir si nombreux pour consulter le fruit de mon travail (qui vous est dédié bien entendue).</p>
<p>Quelques statistiques sur l&#8217;année :</p>
<ul>
<li>60 487 visites</li>
<li>122 193 pages vues</li>
</ul>
<div>Top 5 des naviguateurs</div>
<div>
<ul>
<li>Firefox &#8211; 31 561</li>
<li>Chrome &#8211; 20 174</li>
<li>IE &#8211; 4 580</li>
<li>Opera &#8211; 2 078</li>
<li>Safari &#8211; 1 849</li>
</ul>
<div>Top 3 OS</div>
<div>
<ul>
<li>Windows &#8211; 49 472</li>
<li>Linux &#8211; 7 103</li>
<li>Mac OS &#8211; 3 829</li>
</ul>
<div>Quelle diversité !</div>
</div>
<div>Dans tous les cas Merci à tous et je vous dis à bientôt pour de nouveaux tutoriaux  <img src='http://www.ace-art.fr/wordpress/wp-content/plugins/smilies-themer/Nomicons v2.0/laughing.png' alt=':lol:' class='wp-smiley' /> </div>
</div>
<a class="wpptopdf" target="_blank" rel="noindex,nofollow" href="http://www.ace-art.fr/wordpress/2011/07/26/petite-statistiques-apres-un-an-passe-ensemble/?format=pdf" title="Download PDF"><img alt="Download PDF" src="http://www.ace-art.fr/wordpress/wp-content/plugins/wp-post-to-pdf/asset/images/pdf.png"></a><fb:like href='http://www.ace-art.fr/wordpress/2011/07/26/petite-statistiques-apres-un-an-passe-ensemble/' send='false' layout='standard' show_faces='true' width='450' height='65' action='like' colorscheme='light' font='lucida+grande'></fb:like>]]></content:encoded>
			<wfw:commentRss>http://www.ace-art.fr/wordpress/2011/07/26/petite-statistiques-apres-un-an-passe-ensemble/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Tutoriel Android] Partie 14 – Wifi</title>
		<link>http://www.ace-art.fr/wordpress/2011/07/14/tutoriel-android-partie-14-%e2%80%93-wifi/</link>
		<comments>http://www.ace-art.fr/wordpress/2011/07/14/tutoriel-android-partie-14-%e2%80%93-wifi/#comments</comments>
		<pubDate>Thu, 14 Jul 2011 10:44:55 +0000</pubDate>
		<dc:creator>Pierre-Emmanuel Mercier</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Programmation]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[tutoriel]]></category>
		<category><![CDATA[wifi]]></category>

		<guid isPermaLink="false">http://www.ace-art.fr/wordpress/?p=409</guid>
		<description><![CDATA[Nous allons voir dans ce tutoriel comment utiliser l&#8217;API Wifi d&#8217;Android.  Pré requis : Projet Android 2.2 Un téléphone / tablette Un / plusieurs réseaux wifi Avoir lu le tutoriel sur les listview  Permissions : Notre projet nécessite quelques permissions android.permission.ACCESS_WIFI_STATE android.permission.CHANGE_WIFI_STATE La première sert à checker l&#8217;état du wifi, la seconde à changer celui-ci Ressources : Je vous donnes directement les ressources nécessaires pour l&#8217;adapter sans les expliquer, c&#8217;est pour ça qu&#8217;il faut se référencer au tutoriel [...]]]></description>
			<content:encoded><![CDATA[<p>Nous allons voir dans ce tutoriel comment utiliser l&#8217;API Wifi d&#8217;Android.</p>
<h2> Pré requis :</h2>
<ul>
<li>Projet Android 2.2</li>
<li>Un téléphone / tablette</li>
<li>Un / plusieurs réseaux wifi</li>
<li>Avoir lu le tutoriel sur les listview</li>
</ul>
<h2> Permissions :</h2>
<p>Notre projet nécessite quelques permissions</p>
<ul>
<li>android.permission.ACCESS_WIFI_STATE</li>
<li>android.permission.CHANGE_WIFI_STATE</li>
</ul>
<p>La première sert à checker l&#8217;état du wifi, la seconde à changer celui-ci</p>
<h2>Ressources :</h2>
<p>Je vous donnes directement les ressources nécessaires pour l&#8217;adapter sans les expliquer, c&#8217;est pour ça qu&#8217;il faut se référencer au tutoriel sur les listview si jamais vous ne comprenez pas.</p>
<p>Le format des items pour notre listview</p>
<pre class="brush:xml">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="horizontal" android:layout_width="match_parent"
	android:layout_height="wrap_content"&gt;

	&lt;TextView android:layout_height="fill_parent" android:layout_width="10dp" android:background="@android:color/white" android:id="@+id/ForceSignal"/&gt;

	&lt;LinearLayout android:orientation="vertical"
		android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="10dp"&gt;

		&lt;TextView android:id="@+id/tvWifiName" android:layout_width="fill_parent"
			android:layout_height="wrap_content" android:text="AP Name" /&gt;

		&lt;TextView android:id="@+id/tvWifiMac" android:layout_width="fill_parent"
			android:layout_height="wrap_content" android:textSize="10dp"
			android:text="00:00:00:00:00:00" /&gt;

	&lt;/LinearLayout&gt;

&lt;/LinearLayout&gt;</pre>
<p><span id="more-409"></span></p>
<p>Notre main.xml</p>
<pre class="brush:xml">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    &gt;
    &lt;Button android:id="@+id/buttonRefresh" android:text="Rechercher" android:layout_width="fill_parent" android:layout_height="wrap_content"&gt;&lt;/Button&gt;
    &lt;ListView android:id="@+id/listViewWifi" android:layout_height="fill_parent" android:layout_width="match_parent"&gt;&lt;/ListView&gt;
&lt;/LinearLayout&gt;</pre>
<p>La classe représentant notre item pour la listview</p>
<pre class="brush:java">public class WifiItem {
	private String APName;
	private String AdresseMac;
	private int ForceSignal;

	public String getAPName() {
		return APName;
	}
	public void setAPName(String aPName) {
		APName = aPName;
	}
	public String getAdresseMac() {
		return AdresseMac;
	}
	public void setAdresseMac(String adresseMac) {
		AdresseMac = adresseMac;
	}
	public int getForceSignal() {
		return ForceSignal;
	}
	public void setForceSignal(int forceSignal) {
		ForceSignal = forceSignal;
	}	

}</pre>
<p>Notre adapter</p>
<pre class="brush:java">public class WifiAdapter extends BaseAdapter {

	private List&lt;WifiItem&gt; listeWifiItem;
	private LayoutInflater layoutInflater;

	public WifiAdapter(Context context, List&lt;WifiItem&gt; objects) {

			listeWifiItem = objects;
			layoutInflater = LayoutInflater.from(context);
	}

	public int getCount() {
		return listeWifiItem.size();
	}

	public Object getItem(int position) {
		return listeWifiItem.get(position);
	}

	public long getItemId(int position) {
		return position;
	}

	private class ViewWifiHolder {
		TextView tvApName;
		TextView tvAdresseMac;
		TextView ForceSignal;
	}

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

		if(convertView == null) {
			viewHolder = new ViewWifiHolder();

			convertView = layoutInflater.inflate(R.layout.item_wifi, null);

			viewHolder.tvApName = (TextView) convertView.findViewById(R.id.tvWifiName);
			viewHolder.tvAdresseMac = (TextView) convertView.findViewById(R.id.tvWifiMac);
			viewHolder.ForceSignal = (TextView) convertView.findViewById(R.id.ForceSignal);

			convertView.setTag(viewHolder);
		} else {
			viewHolder = (ViewWifiHolder)convertView.getTag();
		}

		// On affecte les valeurs
		viewHolder.tvApName.setText(listeWifiItem.get(position).getAPName());
		viewHolder.tvAdresseMac.setText(listeWifiItem.get(position).getAdresseMac());

		// On change la couleur en fonction de la force du signal
		if(listeWifiItem.get(position).getForceSignal() &lt;= -80) {
			viewHolder.ForceSignal.setBackgroundColor(Color.GREEN);
		} else if(listeWifiItem.get(position).getForceSignal() &lt;= -50) {
			viewHolder.ForceSignal.setBackgroundColor(Color.YELLOW);
		} else {
			viewHolder.ForceSignal.setBackgroundColor(Color.RED);
		}

		return convertView;
	}

}</pre>
<h2>Implémentation :</h2>
<p>Passons désormais à l&#8217;implémentation de notre code, tout d&#8217;abord nous allons commencer par instancier tout les objets dont nous avons besoin.</p>
<p>&nbsp;</p>
<pre class="brush:java">private Button boutonRechercher;
private ListView listeViewWifi;
private List&lt;WifiItem&gt; listeWifiItem;
private WifiAdapter wifiAdapter;
private WifiManager wifiManager;
private WifiBroadcastReceiver broadcastReceiver;</pre>
<ul>
<li>Le bouton de l&#8217;IHM</li>
<li>La listview de l&#8217;IHM</li>
<li>La liste des WifiItem</li>
<li>Notre adapter</li>
<li>Le wifi manager du sdk Android</li>
<li>Le broadcast receiver que nous allons créer par la suite</li>
</ul>
<p>Notre méthode onCreate</p>
<pre class="brush:java">@Override
public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.main);

	listeViewWifi = (ListView) findViewById(R.id.listViewWifi);
	boutonRechercher = (Button) findViewById(R.id.buttonRefresh);

	boutonRechercher.setOnClickListener(new OnClickListener() {

		public void onClick(View v) {
			if(wifiManager != null)
				wifiManager.startScan();
		}
	});

	// On récupère le service Wifi d'Android
	wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);

	// Gestion de la liste des AP Wifi (Voir tuto sur les adapters et les
	// listview)
	listeWifiItem = new ArrayList&lt;WifiItem&gt;();
	wifiAdapter = new WifiAdapter(this, listeWifiItem);
	listeViewWifi.setAdapter(wifiAdapter);

	// Création du broadcast Receiver
	broadcastReceiver = new WifiBroadcastReceiver();

	// On attache le receiver au scan result
	registerReceiver(broadcastReceiver, new IntentFilter(
			WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));

}</pre>
<p>On commence par récupèrer le bouton et la listview, ensuite on va lier notre wifiManager au service Android grâce au getSystemService.</p>
<p>Continuons en initialisant la liste d&#8217;objet et l&#8217;adapter.</p>
<p>Pour finir on va instancier notre broadcast receiver et l&#8217;enregistrer pour qu&#8217;il soit appelé à chaque fois qu&#8217;un scan des réseaux wifi est fait.</p>
<pre class="brush:java">// On arrête le receiver quand on met en pause l'application
@Override
protected void onPause() {
	unregisterReceiver(broadcastReceiver);
	super.onPause();
}

// On remet en rourte le receiver quand on reviens sur l'application
@Override
protected void onResume() {
	registerReceiver(broadcastReceiver, new IntentFilter(
			WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
	super.onResume();
}</pre>
<p>N&#8217;oublions pas ces deux parties qui permette d&#8217;arrêter de recevoir les scans si vous avez mis l&#8217;application en arrière plan et de nouveau recevoir les scans si vous revenez sur celle-ci.</p>
<p>Pour terminer on fait des getters sur certaines de nos variables pour qu&#8217;elles soient accésibles dans le BroadcastReceiver.</p>
<pre class="brush:java">public WifiManager getCurrentWifiManager() {
	return wifiManager;
}

public WifiAdapter getWifiAdapter() {
	return wifiAdapter;
}

public List&lt;WifiItem&gt; getListeWifiItem() {
	return listeWifiItem;
}</pre>
<p>Passons maintenant à la création du BroadcastReceiver associé au wifi</p>
<pre class="brush:java">public class WifiBroadcastReceiver extends BroadcastReceiver {

	private WifiManager wifiManager;
	private WifiAdapter wifiAdapter;
	private List&lt;WifiItem&gt; listeWifiItem;

	@Override
	public void onReceive(Context context, Intent intent) {
		wifiManager = ((FormationWifiActivity) context).getCurrentWifiManager();
		wifiAdapter = ((FormationWifiActivity) context).getWifiAdapter();
		listeWifiItem = ((FormationWifiActivity) context).getListeWifiItem();

		// On vérifie que notre objet est bien instancié
		if (wifiManager != null) {

			// On vérifie que le wifi est allumé
			if (wifiManager.isWifiEnabled()) {
				// On récupère les scans
				List&lt;ScanResult&gt; listeScan = wifiManager.getScanResults();

				// On vide notre liste
				listeWifiItem.clear();

				// Pour chaque scan
				for (ScanResult scanResult : listeScan) {
					WifiItem item = new WifiItem();

					item.setAdresseMac(scanResult.BSSID);
					item.setAPName(scanResult.SSID);
					item.setForceSignal(scanResult.level);

					Log.d("FormationWifi", scanResult.SSID + " LEVEL "
							+ scanResult.level);

					listeWifiItem.add(item);
				}

				// On rafraichit la liste
				wifiAdapter.notifyDataSetChanged();
			} else {
				Toast.makeText(context, "Vous devez activer votre wifi",
						Toast.LENGTH_SHORT);
			}
		}

	}

}</pre>
<ul>
<li>On crée un classe qui hérite de BroadcastReceiver</li>
<li>On redéfinie la méthode onReceive</li>
<li>On récupère nos getter de l&#8217;activité</li>
<li>On vérifie tout de même que le wifimanager est en route</li>
<li>On vérifie aussi que le wifi est activé</li>
<li>On récupère la liste des réseaux scannés</li>
<li>On vide notre liste et on la remplie avec les nouvelles informations</li>
<li>On spécifie à notre adapter que la liste à était modifiée</li>
</ul>
<p>&nbsp;</p>
<p>Et voilà le tour est joué, normalement vous pouvez voir tout les réseaux wifi à portée de votre mobile.</p>
<p>Le broadcast receiver est appelé à chaque fois qu&#8217;un scan est fait par l&#8217;OS.</p>
<p>&nbsp;</p>
<p><a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/07/device-2011-07-14-123125.png" rel="lightbox[409]"><img class="aligncenter size-medium wp-image-413" title="Scan" src="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/07/device-2011-07-14-123125-180x300.png" alt="Scan" width="180" height="300" /></a></p>
<p>&nbsp;</p>
<p>En espérant que ce tutoriel vous sera utile.</p>
<p>&nbsp;</p>
<p>Source : <a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/07/FormationWifi.zip">FormationWifi</a></p>
<a class="wpptopdf" target="_blank" rel="noindex,nofollow" href="http://www.ace-art.fr/wordpress/2011/07/14/tutoriel-android-partie-14-%e2%80%93-wifi/?format=pdf" title="Download PDF"><img alt="Download PDF" src="http://www.ace-art.fr/wordpress/wp-content/plugins/wp-post-to-pdf/asset/images/pdf.png"></a><fb:like href='http://www.ace-art.fr/wordpress/2011/07/14/tutoriel-android-partie-14-%e2%80%93-wifi/' send='false' layout='standard' show_faces='true' width='450' height='65' action='like' colorscheme='light' font='lucida+grande'></fb:like>]]></content:encoded>
			<wfw:commentRss>http://www.ace-art.fr/wordpress/2011/07/14/tutoriel-android-partie-14-%e2%80%93-wifi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Tutoriel Android] Partie 13 – L&#8217;appareil photo</title>
		<link>http://www.ace-art.fr/wordpress/2011/07/14/tutoriel-android-partie-13-%e2%80%93-lappareil-photo/</link>
		<comments>http://www.ace-art.fr/wordpress/2011/07/14/tutoriel-android-partie-13-%e2%80%93-lappareil-photo/#comments</comments>
		<pubDate>Thu, 14 Jul 2011 06:31:47 +0000</pubDate>
		<dc:creator>Pierre-Emmanuel Mercier</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Programmation]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[camera]]></category>
		<category><![CDATA[tutoriel]]></category>

		<guid isPermaLink="false">http://www.ace-art.fr/wordpress/?p=394</guid>
		<description><![CDATA[Dans ce tutoriel nous allons voir comment faire fonctionner notre appareil photo, sur Android. Nous allons voir pas à pas comment utiliser ce dispositif et comment bien gérer notre application à ce niveau (merci les bonnes pratiques). &#160; Pré requis : Un nouveau projet tout beau tout propre sous android 2.2 Un téléphone ou une tablette Permissions : Nous devons ajouter des droits pour pouvoir utiliser la caméra &#60;uses-permission android:name="android.permission.CAMERA"&#62;&#60;/uses-permission&#62; &#60;uses-feature android:name="android.hardware.camera"/&#62; &#60;uses-feature android:name="android.hardware.camera.autofocus"/&#62; Orientation de l&#8217;activite : [...]]]></description>
			<content:encoded><![CDATA[<p>Dans ce tutoriel nous allons voir comment faire fonctionner notre appareil photo, sur Android.</p>
<p>Nous allons voir pas à pas comment utiliser ce dispositif et comment bien gérer notre application à ce niveau (merci les bonnes pratiques).</p>
<p>&nbsp;</p>
<h2>Pré requis :</h2>
<ul>
<li>Un nouveau projet tout beau tout propre sous android 2.2</li>
<li>Un téléphone ou une tablette</li>
</ul>
<p><span class="Apple-style-span" style="font-size: 26px; line-height: 28px;">Permissions :</span></p>
<p>Nous devons ajouter des droits pour pouvoir utiliser la caméra</p>
<pre class="brush:xml">&lt;uses-permission android:name="android.permission.CAMERA"&gt;&lt;/uses-permission&gt;
&lt;uses-feature android:name="android.hardware.camera"/&gt;
&lt;uses-feature android:name="android.hardware.camera.autofocus"/&gt;</pre>
<h2>Orientation de l&#8217;activite :</h2>
<p>Il est tout de même plus facile de filmer ou prendre une photo en mode paysage</p>
<pre class="brush:xml">android:screenOrientation="landscape"</pre>
<p><span id="more-394"></span></p>
<h2>Contenu global de notre fichier manifest.xml</h2>
<pre class="brush:xml">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.aceart.FormationCamera"
      android:versionCode="1"
      android:versionName="1.0" android:installLocation="auto"&gt;
    &lt;uses-sdk android:minSdkVersion="10" /&gt;
    &lt;uses-permission android:name="android.permission.CAMERA"&gt;&lt;/uses-permission&gt;
    &lt;uses-feature android:name="android.hardware.camera"/&gt;
    &lt;uses-feature android:name="android.hardware.camera.autofocus"/&gt;

    &lt;application android:icon="@drawable/icon" android:label="@string/app_name"&gt;
        &lt;activity android:name=".FormationCameraActivity"
                  android:label="@string/app_name" android:screenOrientation="landscape"&gt;
            &lt;intent-filter&gt;
                &lt;action android:name="android.intent.action.MAIN" /&gt;
                &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
            &lt;/intent-filter&gt;
        &lt;/activity&gt;

    &lt;/application&gt;
&lt;/manifest&gt;</pre>
<p>&nbsp;</p>
<h2>Commençons à coder</h2>
<p>Nous allons avoir besoin tout d&#8217;abord d&#8217;une surface pour prévisualiser l&#8217;image que nous renvoie l&#8217;appareil photo. Il faut ajouter une SurfaceView à notre layout, comme ceci :</p>
<pre class="brush:xml">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    &gt;
    &lt;SurfaceView android:id="@+id/surfaceViewCamera" android:layout_width="fill_parent" android:layout_height="fill_parent"&gt;&lt;/SurfaceView&gt;
&lt;/LinearLayout&gt;</pre>
<p>Une fois ceci fait, rentrons dans le vif du sujet avec la partie java, comme d&#8217;habitude celle-ci est plus que cruciale dans vos développements, mais quand on joue avec un dispositif tel que l&#8217;appareil photo il faut prendre de soin de libérer celui-ci lorsque l&#8217;on ne l&#8217;utilise plus.</p>
<p>&nbsp;</p>
<p>Tout d&#8217;abord nous allons implémenter une interface nommée SurfaceHolder.Callback à notre activité qui permettra d&#8217;avoir les retours sur notre SurfaceView et nous permettre d&#8217;afficher en temps réel notre prévisualisation.</p>
<p>&nbsp;</p>
<pre class="brush:java">public class FormationCameraActivity extends Activity implements SurfaceHolder.Callback</pre>
<p>Une fois l&#8217;interface implémentée il à l&#8217;aide d&#8217;Eclipse nous devons avoir 3 fonctions supplémentaires</p>
<pre class="brush:java">public void surfaceChanged(SurfaceHolder holder, int format, int width,int height)
public void surfaceCreated(SurfaceHolder holder)
public void surfaceDestroyed(SurfaceHolder holder)</pre>
<p>Crééons maintenant 3 variables locales dans notre activité</p>
<pre class="brush:java">private Camera camera;
private SurfaceView surfaceCamera;
private Boolean isPreview;</pre>
<p>La première contiendra notre Camera, la seconde notre surface pour la prévisualisation et pour finir connaître l&#8217;état de la prévisualisation.</p>
<p>&nbsp;</p>
<p>Dirigeons nous vers méthode onCreate ou nous allons ajouter de nouvelles fonctionnalités</p>
<pre class="brush:java">@Override
public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);

	// On met l'application en plein écran et sans barre de titre
	getWindow().setFormat(PixelFormat.TRANSLUCENT);
	requestWindowFeature(Window.FEATURE_NO_TITLE);
	getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
			WindowManager.LayoutParams.FLAG_FULLSCREEN);

	isPreview = false;

	// On applique notre layout
	setContentView(R.layout.main);

	// On récupère notre surface pour le preview
	surfaceCamera = (SurfaceView) findViewById(R.id.surfaceViewCamera);

	// Méthode d'initialisation de la caméra
	InitializeCamera();
}</pre>
<p>On commence tout d&#8217;abord par définir les propriétés de notre activite, sans barre de titre et en plein écran.</p>
<p>On initialise notre prévisualisation a faux et on récupére notre SurfaceView.</p>
<p>Pour terminer on appelle notre méthode pour initialiser notre caméra.</p>
<pre class="brush:java">public void InitializeCamera() {
	// On attache nos retour du holder à notre activite
	surfaceCamera.getHolder().addCallback(this);

	// On spécifie le type du holder en mode SURFACE_TYPE_PUSH_BUFFERS
	surfaceCamera.getHolder().setType(
			SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}</pre>
<p>On récupère le holder de notre surface et on attache son callback à l&#8217;activite, c&#8217;est d&#8217;ailleurs pour ça que l&#8217;on a implémenté notre interface.</p>
<p>On définie ensuite le type du holder, si vous l&#8217;oubliez vous aurez droit à un magnifique crash de votre application.</p>
<p>Définissons maintenant nos méthodes implémentées par l&#8217;interface.</p>
<pre class="brush:java">public void surfaceDestroyed(SurfaceHolder holder) {
	// On arrête la camera et on rend la main
	if (camera != null) {
		camera.stopPreview();
		isPreview = false;
		camera.release();
	}
}</pre>
<p>Quand la surface est détruite, on arrête la prévisualisation, on met notre jeton isPreview à false puis on libère le périphérique (c&#8217;est important).</p>
<pre class="brush:java">public void surfaceCreated(SurfaceHolder holder) {
	// On prend le controle de la camera
	if (camera == null)
		camera = Camera.open();
}</pre>
<p>Quand la surface est créé on ouvre le périphérique pour pouvoir capturer.</p>
<pre class="brush:java">// Quand la surface change
public void surfaceChanged(SurfaceHolder holder, int format, int width,
		int height) {

	// Si le mode preview est lancé alors on le stop
	if (isPreview) {
		camera.stopPreview();
	}
	// On récupère les parametres de la camera
	Camera.Parameters parameters = camera.getParameters();

	// On change la taille
	parameters.setPreviewSize(width, height);

	// On applique nos nouveaux parametres
	camera.setParameters(parameters);

	try {
		// On attache notre previsualisation de la camera au holder de la
		// surface
		camera.setPreviewDisplay(surfaceCamera.getHolder());
	} catch (IOException e) {
	}

	// On lance la previeuw
	camera.startPreview();

	isPreview = true;
}</pre>
<ul>
<li>On commence par vérifier si on est en train de capturer la prévisualisation, si oui on stop le processus,</li>
<li>On récupère les paramétres actuels de notre object Camera, ensuite on lui attribut la nouvelle taille de la surface pour projeter notre prévisualisation</li>
<li>On set les nouveaux paramètres</li>
<li>On indique a notre camera qu&#8217;il faut rediriger la prévisualisation sur notre surface</li>
<li>Pour finir on lance la prévisualisation</li>
<li>On met notre jeton à true</li>
</ul>
<p>&nbsp;</p>
<p><strong>Pour terminer on oublie pas ces deux parties</strong></p>
<pre class="brush:java">// Retour sur l'application
@Override
public void onResume() {
	super.onResume();
	camera = Camera.open();
}

// Mise en pause de l'application
@Override
public void onPause() {
	super.onPause();

	if (camera != null) {
		camera.release();
		camera = null;
	}
}</pre>
<p>Elles vont vous permettre de gérer la mise en arrière plan et le retour au premier plan de l&#8217;application, en libérant la caméra de votre emprise (bande de tirans).</p>
<p>Pour terminer notre petit tutoriel nous allons voir comment enregistrer une image (c&#8217;est le but en fin de compte).</p>
<h2>Prendre une photo</h2>
<p>Nous allons rajouter un peut de code dans notre méthode onCreate, pour que l&#8217;on puisse prendre une photo lorsque l&#8217;on appuye sur l&#8217;écran.</p>
<pre class="brush:java">// Quand on clique sur notre surface
surfaceCamera.setOnClickListener(new OnClickListener() {

	public void onClick(View v) {
		// On prend une photo
		if (camera != null) {
			SavePicture();
		}

	}
});</pre>
<p>On attache l&#8217;évenement onClick de notre SurfaceView a un listener.</p>
<p>Si l&#8217;évenement est levé on appel notre méthode SavePicture.</p>
<pre class="brush:java">private void SavePicture() {
	try {
		SimpleDateFormat timeStampFormat = new SimpleDateFormat(
				"yyyy-MM-dd-HH.mm.ss");
		String fileName = "photo_" + timeStampFormat.format(new Date())
				+ ".jpg";

		// Metadata pour la photo
		ContentValues values = new ContentValues();
		values.put(Media.TITLE, fileName);
		values.put(Media.DISPLAY_NAME, fileName);
		values.put(Media.DESCRIPTION, "Image prise par FormationCamera");
		values.put(Media.DATE_TAKEN, new Date().getTime());
		values.put(Media.MIME_TYPE, "image/jpeg");

		// Support de stockage
		Uri taken = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI,
				values);

		// Ouverture du flux pour la sauvegarde
		stream = (FileOutputStream) getContentResolver().openOutputStream(
				taken);

		camera.takePicture(null, pictureCallback, pictureCallback);
	} catch (Exception e) {
		// TODO: handle exception
	}

}</pre>
<ul>
<li>On commence par définir un format de nommage pour nos photos</li>
<li>Puis on définie toutes propriétés pour le mettre dans la base de données des photos</li>
<li>On récupère le chemin d&#8217;insertion</li>
<li>On ouvre le flux d&#8217;écriture</li>
<li>On lance le camera.takePicture pour prendre une photo</li>
</ul>
<p>Pour finir il faut implémenter le pictureCallback</p>
<pre class="brush:java">// Callback pour la prise de photo
Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {

	public void onPictureTaken(byte[] data, Camera camera) {
		if (data != null) {
			// Enregistrement de votre image
			try {
				if (stream != null) {
					stream.write(data);
					stream.flush();
					stream.close();
				}
			} catch (Exception e) {
				// TODO: handle exception
			}

			// On redémarre la prévisualisation
			camera.startPreview();
		}
	}
};</pre>
<ul>
<li>On enregistre nos données dans le stream</li>
<li>On écrit en dur sur la sdcard</li>
<li>On ferme le flux</li>
<li>On rélance la prévisualisation</li>
</ul>
<p>&nbsp;</p>
<p>Et pour terminer !</p>
<pre class="brush:xml">&lt;uses-permission android:name="android.permision.WRITE_EXTERNAL_STORAGE"&gt;&lt;/uses-permission&gt;</pre>
<p>&nbsp;</p>
<p>Si jamais vous en avez besoin.</p>
<p>&nbsp;</p>
<p>Voilà désormais nous allons chercher notre photo dans la galerie et on regarde son détail</p>
<p>&nbsp;</p>
<p><a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/07/device-2011-07-14-080417.png" rel="lightbox[394]"><img class="aligncenter size-medium wp-image-401" title="Détails" src="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/07/device-2011-07-14-080417-180x300.png" alt="Détails" width="180" height="300" /></a></p>
<p>&nbsp;</p>
<p>Et voilà tout est là !</p>
<p>&nbsp;</p>
<p>J&#8217;espère que ce tuto vous auras plus.</p>
<p>&nbsp;</p>
<p>Source : <a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/07/FormationCamera.zip">FormationCamera</a></p>
<a class="wpptopdf" target="_blank" rel="noindex,nofollow" href="http://www.ace-art.fr/wordpress/2011/07/14/tutoriel-android-partie-13-%e2%80%93-lappareil-photo/?format=pdf" title="Download PDF"><img alt="Download PDF" src="http://www.ace-art.fr/wordpress/wp-content/plugins/wp-post-to-pdf/asset/images/pdf.png"></a><fb:like href='http://www.ace-art.fr/wordpress/2011/07/14/tutoriel-android-partie-13-%e2%80%93-lappareil-photo/' send='false' layout='standard' show_faces='true' width='450' height='65' action='like' colorscheme='light' font='lucida+grande'></fb:like>]]></content:encoded>
			<wfw:commentRss>http://www.ace-art.fr/wordpress/2011/07/14/tutoriel-android-partie-13-%e2%80%93-lappareil-photo/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>[Tutoriel Honeycomb] Partie 1 &#8211; Les actions bars</title>
		<link>http://www.ace-art.fr/wordpress/2011/06/09/tutoriel-honeycomb-partie-1-les-actions-bars/</link>
		<comments>http://www.ace-art.fr/wordpress/2011/06/09/tutoriel-honeycomb-partie-1-les-actions-bars/#comments</comments>
		<pubDate>Thu, 09 Jun 2011 09:46:00 +0000</pubDate>
		<dc:creator>Pierre-Emmanuel Mercier</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Programmation]]></category>
		<category><![CDATA[actions bars]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[honeycomb]]></category>
		<category><![CDATA[tutoriel]]></category>

		<guid isPermaLink="false">http://www.ace-art.fr/wordpress/?p=372</guid>
		<description><![CDATA[Aujourd’hui nous allons débuter notre nouveau périple sur honeycomb, vous savez la nouvelle version d’Android pour les tablettes. Pour commencer nous allons apprendre à utiliser les actions bar comme celle-ci : ﻿ Il est en effet plus pratique sous Honeycomb d’utiliser une action bar qu’un menu qui apparait et disparait lorsque l’on clique sur le bouton menu. Vous aurez remarqués que par défaut le bouton menu n’existe plus sur l’interface, ce n’est pas un mal il [...]]]></description>
			<content:encoded><![CDATA[<p>Aujourd’hui nous allons débuter notre nouveau périple sur honeycomb, vous savez la nouvelle version d’Android pour les tablettes.</p>
<p>Pour commencer nous allons apprendre à utiliser les actions bar comme celle-ci :</p>
<p>﻿<a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/06/image001.gif" rel="lightbox[372]"><img class="aligncenter size-full wp-image-376" title="Action bar" src="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/06/image001.gif" alt="" width="500" height="34" /></a></p>
<p>Il est en effet plus pratique sous Honeycomb d’utiliser une action bar qu’un menu qui apparait et disparait lorsque l’on clique sur le bouton menu.</p>
<p>Vous aurez remarqués que par défaut le bouton menu n’existe plus sur l’interface, ce n’est pas un mal il faut seulement passer ce menu dans l’action bar.</p>
<p><span id="more-372"></span></p>
<h2>Pré-requis :</h2>
<ul>
<li>Android 3.1</li>
<li>Eclipse</li>
<li>Une tablette si possible (l’émulateur est assez lent pour développer)</li>
</ul>
<h2>Présentation :</h2>
<p>Commençons par créer un nouveau projet sous Android 3.1, une fois ceci fait vous remarquerez que l’arborescence des répertoires n’a pas changé.</p>
<p>Ouvrez maintenant le fichier main.xml qui nous servira de base, vous devriez voir apparaitre la nouvelle interface de création fournie par google avec notre main.xml dedans.</p>
<p><a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/06/image002.jpg" rel="lightbox[372]"><img class="aligncenter size-medium wp-image-377" title="Présentation" src="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/06/image002-300x157.jpg" alt="" width="300" height="157" /></a></p>
<p>Cette nouvelle interface est plus intuitive que ses versions précédentes, nous avons donc un aperçu directe de sa représentation sur Honeycomb.</p>
<h2>Création du menu :</h2>
<p>Nous allons créer un nouveau menu pour notre application comme ceci :</p>
<p><a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/06/image003.jpg" rel="lightbox[372]"><img class="aligncenter size-full wp-image-378" title="Création menu xml" src="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/06/image003.jpg" alt="" width="271" height="68" /></a></p>
<p><a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/06/image004.jpg" rel="lightbox[372]"><img class="aligncenter size-medium wp-image-379" title="Configuration menu xml" src="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/06/image004-279x300.jpg" alt="" width="279" height="300" /></a></p>
<p>Une fois le menu créé il faut maintenant le renseigner avec des valeurs</p>
<div style="text-align: center;"><span style="color: #0071bb;"><span style="text-decoration: underline;"><br />
</span></span></div>
<pre class="brush:xml">&lt;?xml version="1.0" encoding="utf-8"?&gt;

&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;

	&lt;item android:title="Afficher une popup" android:id="@+id/itemDialog"&gt;&lt;/item&gt;
	&lt;item android:title="Quitter" android:id="@+id/itemExit"&gt;&lt;/item&gt;

&lt;/menu&gt;</pre>
<p>Voici notre code, deux actions :</p>
<ul>
<li>La première affichera une popup disant « Hello world »</li>
<li>La deuxième quittera l’application</li>
</ul>
<p>Maintenant il faut que le menu soit utilisable dans notre application, pour cela dirigeons nous vers notre Activity.</p>
<p>Par défaut le menu ne s’affiche pas, il faut le rajouter à notre activité, pour cela il faut utiliser la méthode <strong>onCreateOptionsMenu</strong> comme ceci :</p>
<pre class="brush:java">@Override

public boolean onCreateOptionsMenu(Menu menu) {
	getMenuInflater().inflate(R.menu.menuhoney, menu);
	return super.onCreateOptionsMenu(menu);
}</pre>
<p>Lancez l’application et voyez par vous-même !</p>
<p><a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/06/image005.jpg" rel="lightbox[372]"><img class="aligncenter size-medium wp-image-380" title="Premier menu" src="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/06/image005-300x187.jpg" alt="" width="300" height="187" /></a></p>
<p>Nous avons créé notre tout premier menu dans l’Action Bar.</p>
<p>Vous allez me dire oui mais j’aimerais que « Afficher une popup » apparaisse directement dans la fenêtre sans passer par le bouton.</p>
<p>Rien de plus simple il suffit d’aller dans notre menu et de rajouter l’option suivante :</p>
<p>android:showAsAction=&#8221;ifRoom&#8221;</p>
<p>Pour notre bouton ce qui doit vous donner cela</p>
<pre class="brush:xml">&lt;?xml version="1.0" encoding="utf-8"?&gt;

&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;

	&lt;item android:title="Afficher une popup" android:id="@+id/itemDialog" android:showAsAction="ifRoom"&gt;&lt;/item&gt;
	&lt;item android:title="Quitter" android:id="@+id/itemExit"&gt;&lt;/item&gt;

&lt;/menu&gt;</pre>
<p>Relançons notre application maintenant</p>
<p><a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/06/image006.jpg" rel="lightbox[372]"><img class="aligncenter size-medium wp-image-381" title="Deuxième menu" src="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/06/image006-300x187.jpg" alt="" width="300" height="187" /></a></p>
<p>Notre bouton action est de sortie dans l’Action Bar.</p>
<p>Vous pouvez attribuer une icône à cette action, mais par défaut il n’y aura que l’icône dans la barre, il faudra alors rajouter <strong><em>android:showAsAction=&#8221;ifRoom|withText&#8221; </em></strong>si vous voulez voir apparaître le texte.</p>
<p>Par contre, c’est bien jolie, mais il faudrait maintenant que lorsqu’on clic sur les actions qu’il y est quelque chose qui se passe.</p>
<p>Android a tout prévu !</p>
<p><strong>onOptionsItemSelected</strong> va faire votre bonheur je vous l’assure</p>
<pre class="brush:java">@Override
public boolean onOptionsItemSelected(MenuItem item) {
	switch (item.getItemId()) {
		case R.id.itemDialog:
			OuvrirUnePopup();
			return true;
		case R.id.itemExit:
			this.finish();
			return true;
		default:
			return super.onOptionsItemSelected(item);
	}
}

private void OuvrirUnePopup() {
	AlertDialog.Builder builder = new AlertDialog.Builder(this);
	builder.setMessage("Bonjour tout le monde")
		.setCancelable(false)
		.setPositiveButton("Fermer", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				dialog.cancel();
		}
	});

	AlertDialog alert = builder.create();

	alert.show();

}</pre>
<p>C’est quand même facile.</p>
<h2>Recherche :</h2>
<p>On a bien progressé mais on aimerait bien avoir une barre de recherche dans notre application comme celle-ci :</p>
<p><a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/06/image007.gif" rel="lightbox[372]"><img class="aligncenter size-full wp-image-382" title="SearchView" src="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/06/image007.gif" alt="" width="429" height="55" /></a></p>
<p>C’est tout de même plus pratique si nous avons des données à rechercher comme dans beaucoup d’applications.</p>
<p>Mais encore une fois Android a tout prévu, son vraiment sympa chez Google !</p>
<p>Rajoutons un menu dans notre menuhoney.xml</p>
<pre class="brush:xml">&lt;item android:id="@+id/itemSearch" android:showAsAction="ifRoom" android:actionViewClass="android.widget.SearchView" android:title="Recherche"&gt;&lt;/item&gt;</pre>
<p>Cette fois-ci on va prendre la classe android.widget.SearchView qui permet de faire ça directement, pas besoin de passer 2h à tout recoder.</p>
<p>Lançons l’application encore une fois</p>
<p><a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/06/image008.jpg" rel="lightbox[372]"><img class="aligncenter size-medium wp-image-383" title="Action bar search" src="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/06/image008-300x187.jpg" alt="" width="300" height="187" /></a></p>
<p>Super notre barre de recherche s’affiche, par contre elle ne fait que s’afficher, il va falloir la faire fonctionner.</p>
<p>Etapes :</p>
<ul>
<li>Récupérer le SearchView</li>
<li>Lier un listener sur setOnQueryTextListener</li>
<li>Faire une action sur onQueryTextSubmit</li>
</ul>
<pre class="brush:java">@Override
public boolean onCreateOptionsMenu(Menu menu) {
	getMenuInflater().inflate(R.menu.menuhoney, menu); 
	SearchView searchView = (SearchView) menu.findItem(R.id.itemSearch).getActionView(); 

	searchView.setOnQueryTextListener(new OnQueryTextListener() { 

		@Override
		public boolean onQueryTextSubmit(String query) {
			OuvrirUnePopup(query);
			return false;
		}

		@Override
		public boolean onQueryTextChange(String newText) {
			return false;
		}

	});

	return super.onCreateOptionsMenu(menu);

}</pre>
<p>Et voilà ce que cela donne au final !</p>
<p><a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/06/image009.jpg" rel="lightbox[372]"><img class="aligncenter size-medium wp-image-384" title="Utilisation search view" src="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/06/image009-300x187.jpg" alt="" width="300" height="187" /></a></p>
<p>Vous voilà désormais fin prêt à faire des actions bar dans vos applications honeycomb !</p>
<p>&nbsp;</p>
<p>Sources : <a href="http://www.ace-art.fr/wordpress/wp-content/uploads/2011/06/FormationHoneyBar.zip">FormationHoneyBar</a></p>
<a class="wpptopdf" target="_blank" rel="noindex,nofollow" href="http://www.ace-art.fr/wordpress/2011/06/09/tutoriel-honeycomb-partie-1-les-actions-bars/?format=pdf" title="Download PDF"><img alt="Download PDF" src="http://www.ace-art.fr/wordpress/wp-content/plugins/wp-post-to-pdf/asset/images/pdf.png"></a><fb:like href='http://www.ace-art.fr/wordpress/2011/06/09/tutoriel-honeycomb-partie-1-les-actions-bars/' send='false' layout='standard' show_faces='true' width='450' height='65' action='like' colorscheme='light' font='lucida+grande'></fb:like>]]></content:encoded>
			<wfw:commentRss>http://www.ace-art.fr/wordpress/2011/06/09/tutoriel-honeycomb-partie-1-les-actions-bars/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

