<?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>Javasioux &#187; Android</title>
	<atom:link href="http://www.javasioux.fr/blog/category/android/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.javasioux.fr/blog</link>
	<description>Par Jérôme Van Der Linden</description>
	<lastBuildDate>Mon, 21 Nov 2011 22:45:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Faire du neuf avec du vieux sur Android</title>
		<link>http://www.javasioux.fr/blog/2011/11/22/faire-du-neuf-avec-du-vieux-sur-android/</link>
		<comments>http://www.javasioux.fr/blog/2011/11/22/faire-du-neuf-avec-du-vieux-sur-android/#comments</comments>
		<pubDate>Mon, 21 Nov 2011 22:20:53 +0000</pubDate>
		<dc:creator>Jérôme</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Développement]]></category>

		<guid isPermaLink="false">http://www.javasioux.fr/blog/?p=549</guid>
		<description><![CDATA[DISCLAIMER : Cet article devait initialement être publié sur le blog octo mais ayant pris un peu de retard, il a moins de valeur aujourd'hui donc je le mets ici... ca faisait longtemps que je n'avais pas publié sur mon blog :)

On ne peut pas vraiment parler de vieux quand on parle d'Android même s'il est vrai que les sdk 3 (1.5) et 4 (1.6) tendent à disparaître (respectivement 1% et 1.8% du parc). Mais lorsqu'on a réalisé une application basée sur le sdk 1.6 et qu'on souhaite bénéficier du push ou bien adresser les tablettes, on veut éviter de perdre 90% de ses utilisateurs... Voilà quelques éléments pour y parvenir.]]></description>
			<content:encoded><![CDATA[<h2>Notifications Push</h2>
<p>Comme Maxence le précisait <a href="http://blog.octo.com/notifications-push-android-c2dm/" target="_blank">dans son article traitant du sujet</a>, les notifications push ne fonctionnent qu&#8217;à partir du SDK 8 (2.2). On pourrait se contenter de migrer vers cette version mais on perdrait alors 16% des utilisateurs (contre 40% en février 2011).<br />
Que se passe-t-il exactement ? Sur un device au SDK antérieur, vous aurez l&#8217;erreur <i>PHONE_REGISTRATION_ERROR</i> au moment de vous enregistrer au service de Google.</p>
<p>Le problème ne vient pas du code écrit pour s&#8217;enregistrer (<a href="http://code.google.com/intl/fr-FR/android/c2dm/#registering" target="_blank">un simple Intent</a>), ni même de la configuration du manifest (<a href="http://code.google.com/intl/fr-FR/android/c2dm/#manifest" target="_blank">des permissions et un receiver</a>), et pas non plus du code pour recevoir les messages (un <a href="http://code.google.com/intl/fr-FR/android/c2dm/#received_data" target="_blank">BroadcastReceiver</a>).</p>
<p>Tout ceci est disponible dans le SDK 4, et on peut donc le mettre en place sans risquer d&#8217;avoir une UnsupportedOperationException. Par contre, afin d&#8217;éviter l&#8217;erreur à l&#8217;enregistrement du device, on va ajouter le bout de code suivant :</p>
<pre class="brush:java">
if (SysUtils.getSystemVersion() >= <img src='http://www.javasioux.fr/blog/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> {
	// register to C2DM
}
</pre>
<p><b>On n&#8217;utilise pas la constante <a href="http://developer.android.com/reference/android/os/Build.VERSION_CODES.html#FROYO" target="_blank">Build.VERSION_CODES.FROYO</a> qui n&#8217;est disponible qu&#8217;à partir du SDK 8 et donc on utilise sa valeur (8)</b>. Cette petite astuce permet de mettre le push à disposition des téléphones récents tout en supportant les téléphones plus anciens.</p>
<h2>Support des tablettes</h2>
<h3>Écrans XL</h3>
<p>La logique voudrait que les tablettes soient des écrans xlarge (>= 960dp x 720dp). Dans les faits ce n&#8217;est pas tout à fait vrai, il existe des tablettes dans la catégorie large (>= 640dp x 480dp). Google fournit dorénavant la propriété <a href="http://developer.android.com/guide/practices/screens_support.html#DeclaringTabletLayouts" target="_blank">smallestWidth</a> pour déterminer à partir de quelle largeur minimum un layout doit être sélectionné mais ce n&#8217;est disponible qu&#8217;en version 3.2. Nous avons pris le parti d&#8217;utiliser xlarge.</p>
<p>Pour ce faire, vous aurez besoin d&#8217;un <strong>répertoire <em>layout-xlarge</em> dans les ressources</strong> (et éventuellement <em>layout-xlarge-land</em> pour le mode paysage plus fréquemment utilisé pour les tablettes) : aucun problème pour ajouter ce répertoire même dans un projet en 1.6.</p>
<p>Le second point important est la quantité de données à afficher sur un écran de cette taille. On a tendance à regrouper plusieurs écrans en un seul pour profiter de tout l&#8217;espace et par conséquent de créer une nouvelle activité. Le problème qui se pose alors est comment réutiliser le code des mes deux, voire trois activités smartphone pour en constituer une seule pour tablette ?</p>
<p>Comme un exemple et un dessin valent tous les blablas, prenons l&#8217;exemple d&#8217;<a href="http://www.appaloosa-store.com" target="_blank">Appaloosa</a>, notre service de store privé :<br />
<a href="http://www.javasioux.fr/blog/wp-content/uploads/2011/11/fragment.png"><img src="http://www.javasioux.fr/blog/wp-content/uploads/2011/11/fragment-218x300.png" alt="" title="composition d&#039;écrans" width="218" height="300" class="alignnone size-medium wp-image-555" /></a></p>
<p>Le client Android fournit plusieurs activités pour les smartphones (liste d&#8217;applications, détail d&#8217;une application et commentaires d&#8217;une application) et une seule pour les tablettes. La première chose à faire est donc de choisir la bonne activité en fonction du device. Pour cela on créé une activité de démarrage : </p>
<pre class="brush:java">
public class LaunchActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		Intent startActivity = null;
		if ((getResources().getConfiguration().screenLayout &#038; Configuration.SCREENLAYOUT_SIZE_MASK) >= 4) {
			startActivity = new Intent(this,
					AppListAndDetailActivity.class);
		} else {
			startActivity = new Intent(this, AppListActivity.class);
		}
		startActivity(startActivity);
		finish();
	}
}
</pre>
<p>Comme pour le push, <strong>on utilise la valeur de la constante <a href="http://developer.android.com/reference/android/content/res/Configuration.html#SCREENLAYOUT_SIZE_XLARGE" target="_blank">Configuration.SCREENLAYOUT_SIZE_XLARGE</a> (4)</strong> plutôt que la constante elle-même, disponible à partir du SDK 9. Pour le reste, il s&#8217;agit simplement de lancer la bonne activité.</p>
<h3>Défragmentation des écrans</h3>
<p>Concernant le layout, on pourrait se contenter de concevoir un layout adapté mais ce serait dommage d&#8217;aborder les tablettes sans faire usage des <a href="http://developer.android.com/guide/topics/fundamentals/fragments.html" title="Fragments" target="_blank">Fragments</a>. D&#8217;autant que Google fournit depuis mars 2011 une <strong>librairie de rétrocompatibilité (<em><a href="http://developer.android.com/sdk/compatibility-library.html" title="Compatibility package" target="_blank">Compatibility Package</a></em>)</strong> permettant d&#8217;utiliser les fragments dans toutes les applications avec un sdk >= 1.6.</p>
<h4>Avant la bataille</h4>
<p><img src="http://www.javasioux.fr/blog/wp-content/uploads/2011/11/before_tablets-300x176.png" alt="" title="Smartphones" width="300" height="176" class="alignnone size-full wp-image-554" /></p>
<ul>
<li><code>res/layout/app_list_screen.xml</code> : layout contenant la ListView des applications.</li>
<li><code>AppListActivity.java</code> : contenant le code pour charger la liste des applications (AsyncTask pour l&#8217;appel du web service, ListAdapter pour l&#8217;affichage des lignes&#8230;).</li>
<li><code>res/layout/app_detail_screen.xml</code> : layout contenant les différentes info de l&#8217;application.</li>
<li><code>AppDetailActivity.java</code> : contenant le code pour charger le détail d&#8217;une application (divers AsyncTask pour le détail, les screenshots, le téléchargement du binaire&#8230;)</li>
</ul>
<p><h4>Utilisation des fragments</h4>
<p><a href="http://www.javasioux.fr/blog/wp-content/uploads/2011/11/after_tablets-1024x570.png"><img src="http://www.javasioux.fr/blog/wp-content/uploads/2011/11/after_tablets-1024x570-300x166.png" alt="" title="Tablettes" width="300" height="166" class="alignnone size-medium wp-image-553" /></a><br />
Après découpage en fragments, on a&#8230; <strong>beaucoup plus de fichiers</strong> ! Oui, en effet, mais c&#8217;est nécessaire pour éviter la duplication de code. Reprenons chaque fichier un par un :</p>
<h4>Déménagement des layout.xml dans les fragment.xml</h4>
<p>L&#8217;essentiel du fichier <code>app_list_screen.xml</code> se retrouve dans <code>app_list_fragment.xml</code> : la liste, le loading (chargement de la liste), l&#8217;empty message (message en cas de liste vide). Ne reste dans le fichier initial que le code suivant (entête et fragment) :</p>
<pre class="brush:xml">
&lt;LinearLayout
	android:orientation="vertical"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent"&gt;

	&lt;include layout="@layout/header_layout"&gt;&lt;/include&gt;

	&lt;fragment class="com.octo.appaloosa.activity.AppListFragment"
			android:id="@+id/appListFragment"
			android:layout_width="fill_parent"
			android:layout_height="fill_parent"&gt;&lt;/fragment&gt;

&lt;/LinearLayout&gt;
</pre>
<h4>Des activités au fragments, il n&#8217;y a qu&#8217;un pas</h4>
<p><code>AppListActivity.java</code> (après refactoring) ne contient plus grand chose et <strong>étends FragmentActivity</strong> au lieu d&#8217;une simple Activity. Tous les événements onClick restent dans l&#8217;activité :</p>
<pre class="brush:java">
public class AppnListActivity extends FragmentActivity {

	private AppListFragment listFragment;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.app_list_screen);
		listFragment = (AppListFragment) getSupportFragmentManager().findFragmentById(R.id.appListFragment);
	}

	@Override
	protected void onResume() {
		super.onResume();
		listFragment.loadApplications();
	}
</pre>
<p><code>AppListFragment.java</code> contient dorénavant le code pour interagir avec la vue, utiliser les AsyncTask pour les web services, etc&#8230; :</p>
<pre class="brush:java">
public class AppListFragment extends Fragment {
	private List&lt;Application&gt; mApplicationsList = new ArrayList&lt;Application&gt;();
	private ListView mApplicationsListView;

	private AppListListener listener = new AppListListener() {
		public void onComplete(List&lt;Application&gt; apps) {
			mApplicationsList = apps
			((BaseAdapter)mApplicationsListView).notifyDataSetChanged();
		}
	};

	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.app_list_fragment, container, false);
		mApplicationsListView = (ListView)view.findViewById(R.id.applicationListView);
		mApplicationsListView.setAdapter(new AppListAdapter(mApplicationsList, getActivity()));
		return view;
	}

	public void loadApplications() {
		new AppListAsyncTask(getActivity(), listener).execute();
	}
}
</pre>
<p>Le mécanisme est assez proche d&#8217;une activité, les termes changent un peu (onCreateView au lieu de onCreate par exemple). Par ailleurs, il existe un fragment tout fait pour les listes (ListFragment), que nous n&#8217;avons pas utilisé car le layout contenait un peu plus qu&#8217;une simple liste (loading notamment). </p>
<p></p>
<h4>La version tablette</h4>
<p>Je vous épargne l&#8217;écran de détail qui est basé sur le même principe pour aborder l&#8217;écran tablette qui cumule la liste et le détail. <code>app_list_detail_screen.xml</code> est donc relativement simple puisqu&#8217;il <strong>utilise les mêmes fragments que les smartphones</strong> :</p>
<pre class="brush:xml">
&lt;LinearLayout
  	android:orientation="horizontal"
  	android:layout_width="fill_parent"
  	android:layout_height="0dp"
  	android:layout_weight="1"&gt;

  	&lt;fragment class="com.octo.appaloosa.activity.AppListFragment"
		android:id="@+id/appListFragment"
		android:layout_weight="1" android:layout_width="0dp"
		android:layout_height="fill_parent"&gt;&lt;/fragment&gt;

	&lt;fragment class="com.octo.appaloosa.activity.AppDetailFragment"
		android:id="@+id/appDetailFragment"
		android:layout_weight="2.5" android:layout_width="0dp"
		android:layout_height="fill_parent"&gt;&lt;/fragment&gt;
&lt;/LinearLayout&gt;
</pre>
</p>
<h3>Faire le bon choix</h3>
<p>Un point intéressant à regarder est l&#8217;action d&#8217;un click sur un élément de la liste. En effet, si on se trouve <strong>dans le cas du smartphone, on lance l&#8217;activité</strong> de détail (<code>AppDetailActivity</code>). Si on se trouve <strong>dans le cas de la tablette, on charge le détail dans le fragment</strong> associé : </p>
<pre class="brush:java">
public void onItemClick(AdapterView&lt;?&gt; parent, View view, int position, long id) {
	AppDetailFragment detailFragment = (AppDetailFragment) getFragmentManager().findFragmentById(R.id.appDetailFragment);
	if (detailFragment == null) {
		Intent intent = new Intent(getActivity(), AppDetailActivity.class);
		intent.putExtra("application", mApplicationsList.get(position));
		startActivity(intent);
	} else {
		if (detailFragment.getCurrentApplication() == null || detailFragment.getCurrentApp().getId().equals(mApplicationsList.get(position).getId()) == false) {
			detailFragment.loadApplicationDetail(mApplicationsList.get(position));
		}
	}
}
</pre>
</p>
<p>Au final, on a beaucoup plus de classes et de fichiers, mais les fragments (java + xml) sont réutilisables, ce qui nous permet d&#8217;envisager toute sorte d&#8217;interface et surtout envisager les tablettes, voire les TV&#8230;</p>
<h2>Conclusion</h2>
<p>En l&#8217;état actuel des choses, <strong>il possible de couvrir un spectre de <a href="http://developer.android.com/resources/dashboard/platform-versions.html" target="_blank">SDKs</a> relativement large (1.6 -> 4.0) et un spectre d&#8217;<a href="http://developer.android.com/resources/dashboard/screens.html" target="_blank">écrans</a> complet (small -> xlarge) avec une seule application</strong>. Toutefois, Google fournit la possibilité de proposer plusieurs apk pour une même application, par exemple si la version tablette contient des images HD assez lourdes que l&#8217;on souhaite épargner aux smartphones&#8230;</p>
<p>On dit souvent qu&#8217;Android est fragmenté (je ne le nierai pas complètement) mais cet article démontre que malgré la multitude de devices (qui fait aussi la richesse de la plateforme), on peut adresser 99% des utilisateurs sans trop de difficultés.</p>
<p>La sortie récente de Android 4.0 (Ice Cream Sandwich) promet de réunir les développements tablettes et smartphones mais en attendant d&#8217;avoir un parc conséquent d&#8217;appareils basés sur cette dernière mouture, il faudra continuer a jouer d&#8217;astuces pour cibler le plus grand nombre d&#8217;utilisateurs.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javasioux.fr/blog/2011/11/22/faire-du-neuf-avec-du-vieux-sur-android/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Metroide mis à jour et version complète en ligne</title>
		<link>http://www.javasioux.fr/blog/2010/05/27/metroide-mis-a-jour-et-version-complete-en-ligne/</link>
		<comments>http://www.javasioux.fr/blog/2010/05/27/metroide-mis-a-jour-et-version-complete-en-ligne/#comments</comments>
		<pubDate>Wed, 26 May 2010 22:50:13 +0000</pubDate>
		<dc:creator>Jérôme</dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://www.javasioux.fr/blog/?p=547</guid>
		<description><![CDATA[Après plusieurs mois de standby sur les développements de Metroide, j&#8217;ai décidé de me bouger et de finir (ou tout du moins livrer une version). Et bien c&#8217;est chose faite, la version demo, renommée en lite a été revue et corrigée et la version complète est également arrivée (pour 1 euro). Je suis donc heureux [...]]]></description>
			<content:encoded><![CDATA[<p>Après plusieurs mois de standby sur les développements de Metroide, j&#8217;ai décidé de me bouger et de finir (ou tout du moins livrer une version).<br />
Et bien c&#8217;est chose faite, la version demo, renommée en lite a été revue et corrigée et la version complète est également arrivée (pour 1 euro).</p>
<p>Je suis donc heureux d&#8217;annoncer le lancement de Metroide ! Si vous l&#8217;avez téléchargé et que vous trouvez des bugs, écrivez moi à metroide dot android at gmail dot com.</p>
<p>Si vous ne l&#8217;avez pas encore installé, c&#8217;est ici pour la version complète : <br /><a href="market://search?q=pname:fr.vdl.metroide"><img border="0" src="http://chart.apis.google.com/chart?cht=qr&#038;chs=100x100&#038;chl=http://cyrket.com/qr/107787"></a></p>
<p>Et ici pour la version lite :<br />
<br /><a href="market://search?q=pname:fr.javasioux.metroide"><img border="0"src="http://chart.apis.google.com/chart?cht=qr&#038;chs=100x100&#038;chl=http://cyrket.com/qr/22182"></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.javasioux.fr/blog/2010/05/27/metroide-mis-a-jour-et-version-complete-en-ligne/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Metroide est disponible !</title>
		<link>http://www.javasioux.fr/blog/2009/06/01/metroide-est-disponible/</link>
		<comments>http://www.javasioux.fr/blog/2009/06/01/metroide-est-disponible/#comments</comments>
		<pubDate>Sun, 31 May 2009 22:06:38 +0000</pubDate>
		<dc:creator>Jérôme</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[metro]]></category>
		<category><![CDATA[metroide]]></category>

		<guid isPermaLink="false">http://www.javasioux.fr/blog/?p=474</guid>
		<description><![CDATA[Il ne s&#8217;agit pour le moment que d&#8217;une version demo/beta/lite ou peu importe le nom que vous lui donnerez, mais metroide est enfin en ligne ! La version complète (avec le RER, tramway et trains de banlieue, ainsi que des fonctionnalités en plus) arrivera un peu plus tard&#8230; La liste des fonctionnalités est disponible ici. [...]]]></description>
			<content:encoded><![CDATA[<p>Il ne s&#8217;agit pour le moment que d&#8217;une version demo/beta/lite ou peu importe le nom que vous lui donnerez, mais <a href="http://www.cyrket.com/package/fr.javasioux.metroide">metroide est enfin en ligne</a> ! La version complète (avec le RER, tramway et trains de banlieue, ainsi que des fonctionnalités en plus) arrivera un peu plus tard&#8230; La liste des fonctionnalités est disponible <a href="http://www.javasioux.fr/metroide/metroide">ici</a>.</p>
<p><center><img title="Metroide demo sur le market" src="http://www.javasioux.fr/metroide/wp-content/uploads/2009/05/screen-capture-12.png" alt="Metroide demo sur le market" width="275" height="306" /></center></p>
<table>
<tr>
<td valign="top">C&#8217;est ici que ca se passe pour le téléchargement :</td>
<td><img class="alignnone" title="CodeBarre Metroide demo" src="http://chart.apis.google.com/chart?cht=qr&amp;chs=100x100&amp;chl=market://search?q=pname:fr.javasioux.metroide" alt="" width="100" height="100" /></td>
</tr>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.javasioux.fr/blog/2009/06/01/metroide-est-disponible/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Astuce du jour Android : récupérer dynamiquement une ressource</title>
		<link>http://www.javasioux.fr/blog/2009/05/29/astuce-du-jour-android-recuperer-dynamiquement-une-ressource/</link>
		<comments>http://www.javasioux.fr/blog/2009/05/29/astuce-du-jour-android-recuperer-dynamiquement-une-ressource/#comments</comments>
		<pubDate>Fri, 29 May 2009 21:43:20 +0000</pubDate>
		<dc:creator>Jérôme</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Développement]]></category>

		<guid isPermaLink="false">http://www.javasioux.fr/blog/?p=467</guid>
		<description><![CDATA[Petite astuce si comme moi vous cherchez à récupérer dynamiquement une ressource (drawable, color...) en connaissant son nom...]]></description>
			<content:encoded><![CDATA[<p>Mon besoin est simple, la solution aussi&#8230;</p>
<p>
Sur métroide (mon application de calcul d&#8217;itinéraire de metro pour Android), j&#8217;ai un grand nombre d&#8217;images pour toutes les lignes du métro (+rer et tram) que je dois afficher dynamiquement sur l&#8217;itinéraire.</p>
<p>
<u>Comme un exemple vaut mille paroles, exemple</u> :<br />
J&#8217;ai l&#8217;itinéraire suivant : nation (&laquo;&nbsp;m1&#8243;: ligne 1 du métro), porte d&#8217;italie (&laquo;&nbsp;m7&#8243;).<br />
Je vais donc avoir besoin des images R.drawable.m1 et R.drawable.m7. Mais je n&#8217;ai qu&#8217;une chaine de caractère pour spécifier le nom de l&#8217;image. J&#8217;aurais aimé faire un truc du genre R.drawable["m1"] ou R.drawable.get(&laquo;&nbsp;m7&#8243;)&#8230; mais malheureusement, ce n&#8217;est pas possible. Je dois avouer que pour le concours SFRJTD, je n&#8217;ai pas poussé plus loin mes recherches et j&#8217;ai fait un switch en découpant ma chaine (m1 -> m et 1, donc m me dit metro, 1 ligne 1, je prend donc R.drawable.m1)&#8230; berk !</p>
<p>
Cette solution ne me convenant pas et n&#8217;ayant pas trouvé de réponse à ma question, je me suis dit : &laquo;&nbsp;tant qu&#8217;a faire crade, pourquoi ne pas faire de l&#8217;introspection ?&nbsp;&raquo; Et c&#8217;est comme ca que j&#8217;ai réduit un switch de 40 lignes en 5 lignes comme ceci :</p>
<pre lang="java">
try {
	Field f = R.drawable.class.getField(line); // line = "m1" ou "rb" ou "t3"...
	return f.getInt(null); // class static et champs static dans R, on peut laisser à null
} catch (Exception e) {
	return R.drawable.empty;
}
</pre>
<p>Je ne suis pas encore complètement convaincu et je me dis que j&#8217;ai du me prendre la tête à faire compliqué alors que c&#8217;est prévu dans le SDK. Si tel est le cas, je suis preneur de vos solutions&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javasioux.fr/blog/2009/05/29/astuce-du-jour-android-recuperer-dynamiquement-une-ressource/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Android, le futur de l&#8217;humanité ?</title>
		<link>http://www.javasioux.fr/blog/2009/04/24/android-le-futur-de-lhumanite/</link>
		<comments>http://www.javasioux.fr/blog/2009/04/24/android-le-futur-de-lhumanite/#comments</comments>
		<pubDate>Fri, 24 Apr 2009 21:10:07 +0000</pubDate>
		<dc:creator>Jérôme</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[gps]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[metro]]></category>
		<category><![CDATA[metroide]]></category>

		<guid isPermaLink="false">http://www.javasioux.fr/blog/?p=404</guid>
		<description><![CDATA[Je ne vais pas vous parler ici des <a href="http://fr.wikipedia.org/wiki/Androide" target="_blank">robots humanoïdes</a> mais bien de l'OS de Google, <a href="http://fr.wikipedia.org/wiki/Android" target="_blank">Android</a> ! J'ai découvert ce petit monde il y a quelques temps et je souhaitais partager avec vous cette mini-révolution.]]></description>
			<content:encoded><![CDATA[<table>
<tr>
<td><img src="http://blog.oxiane.com/wp-content/uploads/2009/03/android_vector.jpg" alt="Android"  width="150"/></td>
<td>
<h1>Android, kezako ?</h1>
<p>Pour ceux d&#8217;entre vous qui ne lirait jamais les news (comment êtes vous tombé sur mon blog ?!), Android est le système d&#8217;exploitation pour plateformes mobiles développé par Google. Dans les faits, Google a racheté une société qui avait conçu la première version d&#8217;Andoid mais peu importe. Android est donc un OS pour appareils mobiles (téléphones, dont le HTC Dream chez Orange et le HTC Magic chez SFR; netbooks; archos&#8230;). </p>
<p>A l&#8217;OS, s&#8217;ajoute un SDK (actuellent en v1.1, bientôt 1.5) permettant à tout un chacun de développer ses applications pour l&#8217;OS&#8230; à ceci prêt qu&#8217;il faut connaître le langage Java mais si vous fréquentez mon blog, je suppose que c&#8217;est le cas.</td>
</tr>
</table>
<h1>Un environnement de développement aux petits oignons</h1>
<ul>
<li>Tout d&#8217;abord, gros avantage, c&#8217;est du <strong>Java</strong> ! Mine de rien, les développeurs Java, c&#8217;est pas ce qu&#8217;il manque aujourd&#8217;hui sur le marché et on peut donc espérer une grosse activité de développement. Est ce le bon choix d&#8217;avoir pris un langage qui n&#8217;est pas réputé pour sa rapidité d&#8217;exécution ? Peut-être pas&#8230; toujours est-il que si Google veut rattraper le nombre d&#8217;applications déjà développées sur l&#8217;Iphone, ça me semble être une bonne stratégie.</li>
</ul>
<ul>
<li>Ensuite, il existe un <strong>plugin Eclipse</strong> (ajoutez cette adresse à vos updates Eclipse : http://dl-ssl.google.com/android/eclipse/). Là encore, la communauté Eclipse est à ce jour la plus importante comparé à Netbeans et IntelliJ. Encore un bon point pour toucher le plus grand nombre de développeurs. Avec le SDK, est fourni un émulateur pour tester vos applications sans pour autant avoir à acheter un téléphone. Le lancement de l&#8217;émulateur est pris en charge dans Eclipse, c&#8217;est donc un réel plaisir que de développer pour la plateforme. Je regrette juste la lenteur de démarrage de l&#8217;émulateur&#8230;</li>
</ul>
<ul>
<li>Le SDK en lui-même est d&#8217;une simplicité assez déconcertante, tout du moins pour qui connaît déjà Java. La <a href="http://developer.android.com/guide/basics/what-is-android.html" target="_blank">doc</a> est relativement claire, le SDK est fourni avec quelques exemples mais surtout, on peut en quelque lignes manipuler google maps, récupérer les coordonnées GPS, utiliser la liste de ses contacts (cf partie suivante)&#8230; En tout cas, on trouve pas mal d&#8217;infos partout sur le web : forum <a href="http://www.anddev.org/" target="_blank">anddev</a>, <a href="http://groups.google.com/group/android-developers" target="_blank">google groups</a>, &#8230;</li>
</ul>
<h1>Code snippets</h1>
<h2>Récupérer la position GPS actuelle</h2>
<p>Dans le manifest, il faut ajouter les permissions suivantes :</p>
<pre lang="xml" line="3">
	<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
	<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
	<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
</pre>
<p>Dans votre activité, vous aurez un code ressemblant à ça :</p>
<pre lang="java" line="20">
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);

LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
String provider = locationManager.getBestProvider(criteria, true);
Location currentLocation = locationManager.getLastKnownLocation(provider);
locationManager.requestLocationUpdates(provider, 100, 100, locationListener); // si on se déplace de 100 m (vérification toutes les 100 millisecondes)

// ...

private final LocationListener locationListener = new LocationListener() {
	public void onLocationChanged(final Location location) {
		currentLocation = location;
	}

	public void onProviderDisabled(final String provider) {
		currentLocation = null;
	}

	public void onProviderEnabled(final String provider) {
	}

	public void onStatusChanged(final String provider, final int status,
			final Bundle extras) {
	}
};
</pre>
<p>Attention, si le GPS n&#8217;est pas activé, vous aurez des erreurs, notamment le provider sera null et getLastKnownLocation plantera lamentablement.</p>
<p>Pour tester, vous pouvez émuler une position. On est censé pouvoir le faire depuis eclipse mais perso, ça n&#8217;a pas fonctionné. J&#8217;ai donc utilisé la méthode geek :</p>
<pre lang="shell">
telnet localhost 5554
geo fix 2.305114 48.869321
</pre>
<h2>Afficher une map et dessiner dessus</h2>
<p>Pour afficher la map (Google maps), c&#8217;est relativement simple, il y a une Activity et une View toutes prêtes. Dans votre fichier myMap.xml, vous aurez :</p>
<pre lang="xml">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" android:layout_width="fill_parent"
	android:layout_height="fill_parent">

	<com.google.android.maps.MapView
		android:id="@+id/map_view" android:layout_width="fill_parent"
		android:layout_height="fill_parent" android:enabled="true"
		android:clickable="true" android:apiKey="KEY HERE" />

</RelativeLayout>
</pre>
<p>Remplacez le KEY HERE par une clé fournie par <a href="http://code.google.com/intl/fr/android/maps-api-signup.html" target="_blank">google</a> à partir du keystore de votre sdk (plus de détails <a href="http://developer.android.com/guide/topics/location/geo/mapkey.html"  target="_blank">ici</a>).</p>
<p>
Dans le manifest, sous la balise application, vous aurez :</p>
<pre lang="xml">
  <uses-library android:name="com.google.android.maps" />
</pre>
<p>Enfin dans le code java :</p>
<pre lang="java" line="10">
public class MapLines extends MapActivity {
   @Override
	public void onCreate(final Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.myMap);
		MapView mapView = (MapView) findViewById(R.id.map_view);
		Overlay overlay = new MyOverlay();
		mapView.getOverlays().add(overlay);
	}

	private class MyOverlay extends Overlay {
		@Override
		public void draw(final Canvas canvas, final MapView mapView) {
			GeoPoint myPoint = new GeoPoint((int) (48.858563 * 1E6),
					(int) (2.347204 * 1E6));
			Point point = new Point();
			mapView.getProjection().toPixels(myPoint, point); // transforme les coordonnées GPS en position x/y sur l'écran
			RectF oval = new RectF(point.x - 2, point.y - 2, point.x + 2, point.y + 2);
			canvas.drawOval(oval, paint); // dessine un rond à la position souhaitée
		}
	}
}
</pre>
<p>Bien entendu, vous pouvez dessiner autre chose que des ronds, des carrés&#8230; vous pouvez mettre des images par exemple.</p>
<h2>Récupérer les contacts</h2>
<p>Là encore, c&#8217;est très simple. Dans le fichier manifest, vous déclarez la permission :</p>
<pre lang="xml">
<uses-permission android:name="android.permission.READ_CONTACTS"/>
</pre>
<p>Ensuite, dans votre code, pour récupérer par exemple les noms des contacts :</p>
<pre lang="java">
String[] columns = new String[] { People.NAME };
Cursor cursor = getContentResolver().query(People.CONTENT_URI, columns, null, null, People.NAME);

String[] contacts = new String[cursor.getCount()];
if (cursor.moveToFirst()) {
	int i = 0;
	do {
		contacts[i++] = cursor.getString(cursor.getColumnIndex(People.NAME));
	} while (cursor.moveToNext());
}
</pre>
<p>Vous pouvez ensuite les mettre dans un spiner ou une liste : </p>
<pre lang="java">
ArrayAdapter contactAdapter = new ArrayAdapter<String>(MainSearch.this, android.R.layout.simple_dropdown_item_1line, contacts);
AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.edit);
textView.setAdapter(contactAdapter);
</pre>
<p>Et voilà !!</p>
<h1>Mon humble participation</h1>
<h2>Concours SFR Jeunes Talents</h2>
<p>SFR a annoncé il y a un mois le lancement d&#8217;un concours de développement d&#8217;applications pour Android afin de faire connaître la plateforme et surtout pour annoncer l&#8217;arrivée de l&#8217;HTC G2 (qui se fait attendre&#8230;). C&#8217;est à cette occasion que je me suis lancé dans le développement d&#8217;une application qui à défaut d&#8217;être originale, sera d&#8217;une grande utilité pour tous ceux qui habitent Paris (dans un premier temps et n&#8217;importe quelle ville où il y a un métro à terme). Vous l&#8217;aurez compris, il s&#8217;agit d&#8217;une application gérant les itinéraires en métro !</p>
<h2>Metroide</h2>
<p>Metroide, c&#8217;est son nom, permet simplement de calculer votre itinéraire en métro depuis n&#8217;importe où (station, contact, adresse, favori et position gps courante). L&#8217;avantage est qu&#8217;il n&#8217;a <b>pas besoin de connexion internet</b> pour calculer un itinéraire de station à station (<b>aucune connexion au site de la ratp</b>). </p>
<p>En effet, toutes les stations et tous les liens sont dans l&#8217;application (au format XML pour l&#8217;instant), et j&#8217;ai implémenté l&#8217;algorithme <a href="http://fr.wikipedia.org/wiki/Algorithme_de_Dijkstra" target="_blank">Dijkstra</a> pour calculer le plus court chemin, donc le meilleur itinéraire entre deux points.</p>
<p>Par contre, si vous utilisez les autres options, elles font toutes appel au <a href="http://developer.android.com/reference/android/location/Geocoder.html" target="_blank">GeoCoder</a> pour transformer l&#8217;adresse en coordonnées GPS et donc là, une connexion internet est requise.</p>
<p>Trève de blabla, voici la présentation que j&#8217;ai soumise au concours SFR :</p>
<p><center>
<div style="width:425px" id="__ss_1338234"><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=metroide-090424122248-phpapp02&#038;rel=0&#038;stripped_title=metroide" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=metroide-090424122248-phpapp02&#038;rel=0&#038;stripped_title=metroide" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></div>
<p></center></p>
<p>Ainsi que la vidéo de l&#8217;appli :</p>
<p><center>
<div><object width="320" height="307"><param name="movie" value="http://www.dailymotion.com/swf/x932pg_metroide_tech&#038;related=0"></param><param name="allowFullScreen" value="true"></param><param name="allowScriptAccess" value="always"></param><embed src="http://www.dailymotion.com/swf/x932pg_metroide_tech&#038;related=0" type="application/x-shockwave-flash" width="320" height="307" allowFullScreen="true" allowScriptAccess="always"></embed></object></div>
<p></center></p>
<p>J&#8217;ai encore un peu de boulot pour rendre le tout plus joli (notamment les favoris), et beaucoup de boulot pour saisir les stations de RER / tramway et trains de banlieue. La version actuelle sera mise à disposition gratuitement sur l&#8217;android market et je verrai pour passer à une version payante (1 ou 2 €) quand elle sera plus aboutie.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javasioux.fr/blog/2009/04/24/android-le-futur-de-lhumanite/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

