
Donc, ce matin, vous vous êtes réveillé et vous vous êtes dit, "Je reconstruirais bien mon application Android, bonne idée". Vous n'avez pas changé quoi que ce soit, mais quand vous faites "Android Outils-> Export signed application" un étrange message est apparu dans Eclipse:
"Exporter avorté parce que des erreurs fatales peluches ont été trouvés. Ceux-ci sontrépertoriés dans la vue ... Blablabla ... Lint"
Ok, donc vous avez pris votre café et maintenant vous êtes de retour devant l'ordinateur en essayant de trouver la vue Lint. Et vous avez lu dans le LintView le message suivant lorsque vous cliquez sur la ligne "Fichier Proguard Obsolète ...":
Obsolete ProGuard file; use -keepclasseswithmembers instead of -keepclasseswithmembernames
Issue: Looks for problems in proguard config files
Id: Proguard
Using -keepclasseswithmembernames in a proguard config file is not correct; it can cause some symbols to be renamed which should not be.
Earlier versions of ADT used to create proguard.cfg files with the wrong format. Instead of -keepclasseswithmembernames use -keepclasseswithmembers, since the old flags also implies "allow shrinking" which means symbols only referred to from XML and not Java (such as possibly CustomViews) can get deleted.
http://http://code.google.com/p/android/issues/detail?id=16384
Ok, pas de panique, ouvrez votre proguard-project.txt (c'est un fichier à la racine de votre projet Eclipse) et il suffit de changer le mot keepclasseswithmembernames par keepclasseswithmember (supprimer le "names" à la fin du mot). (vous devriez avoir 3 changements à faire).
Enregistrez le fichier (qui est automatiquement renommé en proguard.cfg), relancer le "Android Outils-> demande d'exportation signé", et ça marche.
Cela est dû à la mise à jour ADT à la version 17.
Alors, merci qui?
Merci, Android2EE:o)
Mathias Séguy
mathias.seguy.it@gmail.com
Auteur Android2EE
Ebooks pour apprendre la programmation sous Android.

Retrouvez moi sur Google+
Suivez moi sur Twitter
Rejoignez mon réseau LinkedIn ou Viadeo
Vous devez être identifié pour poster un commentaire.
, MathiasSeguy 
Bonjour,
Un grand jour pour le développement Android, la RC1 de la V1 de Spring for Android est arrivé !
Y'a plus qu'à l'utiliser :o)
C'est ici:
http://www.springsource.org/spring-android/news/1.0.0.rc1-released
Alors, merci qui?
Merci, Spring :o)
Mathias Séguy
mathias.seguy.it@gmail.com
Auteur Android2EE
Ebooks pour apprendre la programmation sous Android.

Retrouvez moi sur Google+
Suivez moi sur Twitter
Rejoignez mon réseau LinkedIn ou Viadeo
Vous devez être identifié pour poster un commentaire.

Vous voulez ajouter AdSense à votre application Android... Rien de plus simple, trois lignes xml dans votre fichier de layout, un jar a inclure dans votre appli et tout ça très bien expliqué par Google, ici:
Google explique AdMob
Alors, merci qui?
Merci, Android2ee, les Ebooks de programmation Android :o)
Mathias Séguy
mathias.seguy.it@gmail.com
Auteur Android2EE
Ebooks pour apprendre la programmation sous Android.

Retrouvez moi sur Google+
Suivez moi sur Twitter
Rejoignez mon réseau LinkedIn ou Viadeo
Vous devez être identifié pour poster un commentaire.

Bonne année à tous,
Aujourd'hui un document à lire si vous souhaitez faire des applications Android, le guide officiel du design Android par Google.
Vous le trouverez ici:
http://developer.android.com/design/index.html
Cet vraiment pleins de bonnes pratiques, il faut le lire au moins une fois et y revenir quand on est en phase de Design de l'application. Ok, il est orienté ICS, mais on finira bien par coder avec cette version. (Pas tout de suite, seulement 3.9% des appareils ont une version supérieure à 2.3)
Alors, merci qui?
Merci, Android2ee, les Ebooks de programmation Android :o)
Mathias Séguy
mathias.seguy.it@gmail.com
Auteur Android2EE
Ebooks pour apprendre la programmation sous Android.

Retrouvez moi sur Google+
Suivez moi sur Twitter
Rejoignez mon réseau LinkedIn ou Viadeo
Vous devez être identifié pour poster un commentaire.

Re, Re, Bonjour.
Les tutoriels sont disponible sur Android2EE section Exemple/Tutoriaux/Handler Tutoriels.
Vous avez le tutoriel avec les AtomicBoolean, celui avec le onRetainNonConfigurationInstance et enfin un projet qui démontre la fuite mémoire quand rien n'est fait.
Alors, merci qui?
Merci, Android2ee, les Ebooks de programmation Android :o)
Mathias Séguy
mathias.seguy.it@gmail.com
Auteur Android2EE
Ebooks pour apprendre la programmation sous Android.

Retrouvez moi sur Google+
Suivez moi sur Twitter
Rejoignez mon réseau LinkedIn ou Viadeo
Vous devez être identifié pour poster un commentaire.
, MathiasSeguy 
Re-Bonjour,
Toujours dans cette problématique d'Handler et de cycle de vie d'une activité, il y a une solution préconisée par certains qui est d'utiliser la méthode public Object onRetainNonConfigurationInstance() qui permet de renvoyer un pointeur vers un objet à l'activité.
Euh, je m'explique, lorsque votre activité est détruite pour être immédiatement recrée, la méthode onRetainNonConfigurationInstance permet d’envoyer un objet de l'instance de l’activité mourante vers l'instance de la nouvelle activité.
Exemple adapté à notre problème:
@Override
public Object onRetainNonConfigurationInstance() {
return backgroundThread;}
permet de récupérer l'objet dans la méthode onCreate:
@Override
public void onCreate(Bundle savedInstanceState) {
…
backgroundThread=(Thread)getLastNonConfigurationInstance();
if(backgroundThread==null) {
//créer la thread comme d’habitude
}else{
//pas besoin de else, votre thread est récupérée
}
…}
On voit bien qu'avec cette méthode tout paraît résolu (au moins pour le changement d'orientation de l'appareil). Et oui, mais non, c'est une grave erreur que de penser ça. En effet, que se passe-t-il si votre activité est tuée? Ben, votre thread devient orpheline, votre handler et votre activité deviennent des fantômes (car le Garbage collector les détecte utilisés). Et voilà, encore une fois, Dark Vador se gausse.
La solution, et oui, il y en a une, est un peu plus complexe que cela. Il faut ré-implémenter un atomic boolean permettant de tuer la thread si votre activité n'est pas relancée immédiatement.
Et là, ben je vous invite à aller récupérer les tutoriels que j’ai déposé sur Android2EE section Exemple, partie Tutoriels (Handler Tutoriels).
Alors, merci qui?
Merci, Android2ee, les Ebooks de programmation Android :o)
Mathias Séguy
mathias.seguy.it@gmail.com
Auteur Android2EE
Ebooks pour apprendre la programmation sous Android.

Retrouvez moi sur Google+
Suivez moi sur Twitter
Rejoignez mon réseau LinkedIn ou Viadeo
Vous devez être identifié pour poster un commentaire.

Bonjour,
Comme je vous disais précédemment, quand vous manipulez les Handlers ou les AsynchTasks, il faut toujours faire en sorte d'accorder le cycle de vie de la thread avec celui du Handler qui est lui-même lié à celui de l'activité... Sinon, votre Thread devient orpheline.
Bon en creusant un peu (je vais vous poser sur Androi2EE un projet eclipse qui démontre ce que je dis), c'est pire, en effet: Lors du passage par onDestroy puis onCreate (bref je retourne l'appareil), non seulement la Thread devient orpheline, mais le Handler aussi (arg, quoi il n'est pas détruit o_O') et pire votre activité devient fantôme... glooops.
Et oui c'est fou, la première activité n'est pas détruite, c'est elle qui est appelée par la première Thread au travers du premier Handler (d'où l'absence de levée d'exception du type NullPointer) et la seconde est créée avec son Handler et sa nouvelle Thread.
Là, j'entends DarkVador, Voldemor et Sauron rirent en pensant au nombre de Threads, de Handlers, d'AsynchTasks et d’activités fantômes qui peuplent les appareils Android à cause de développeurs inconscients du danger.
Donc: Gérer vos threads en accordant leur cycle de vie avec celui de l'activité.
Alors, merci qui?
Merci, Android2ee, les Ebooks de programmation Android :o)
Mathias Séguy
mathias.seguy.it@gmail.com
Auteur Android2EE
Ebooks pour apprendre la programmation sous Android.

Retrouvez moi sur Google+
Suivez moi sur Twitter
Rejoignez mon réseau LinkedIn ou Viadeo
Vous devez être identifié pour poster un commentaire.

Bonjour,
En tant que développeurs, on est toujours à la recherche d'icônes. Bien sûr il y aceux du SDK, mais souvent cela ne suffit pas.
Un super site pour retrouver des milliers d'icônes gratuites icones.pro. Ils ne sont pas tous à usage commercial, mais il est possible de contacter les auteurs.
Si vous connaissez d'autres sites d'icônes gratuits postez un commentaire.
Alors, merci qui?
Merci, Android2ee, les Ebooks de programmation Android :o)
Mathias Séguy
mathias.seguy.it@gmail.com
Auteur Android2EE
Ebooks pour apprendre la programmation sous Android.

Retrouvez moi sur Google+
Suivez moi sur Twitter
Rejoignez mon réseau LinkedIn ou Viadeo
Vous devez être identifié pour poster un commentaire.

Bonjour,
Parfois, on a besoin de modifier le manière dont le spinner est affiché.
Trois actions sont nécessaires pour cela (je me suis appuyé sur le tutorial Android :hello-spinner)
1. Créez un fichier spinnertext.xml dans votre dossier layout qui définit comment s'affiche le texte (font),
2. Changez la taille de votre spinner dans votre fichier main.xml (où votre spinner est défini),
3. Changez la déclaration de votre spinner dans votre activité.
Votre fichier spinnertext.xml créé dans le dossier res\layout:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:text="@+id/TextView01"
android:id="@+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"
android:textColor="#FFFFFFFF"
android:gravity="center"/>
La déclaration de votre spinner dans le fichier main.xml (dans res\layout), pour gérer sa taille :
<Spinner
android:id="@+id/spinner"
android:layout_width="fill_parent"
android:layout_height="32dip"
android:drawSelectorOnTop="true"
android: prompt="@string/spinner_prompt"
/>
Et la déclaration du spinner dans votre activité (en jaune le code changé):
Spinner s = (Spinner) findViewById(R.id.spinner);
ArrayAdapter adapter = ArrayAdapter.createFromResource(this, R.array.sensors,R.layout.spinnertext );
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
s.setAdapter(adapter);
//when an item is selected call the selectSensor method
s.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
selectSensor(parent.getItemAtPosition(position));
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
}
});
Alors, merci qui?
Merci, Android2ee, les Ebooks de programmation Android :o)
Mathias Séguy
mathias.seguy.it@gmail.com
Auteur Android2EE
Ebooks pour apprendre la programmation sous Android.

Retrouvez moi sur Google+
Suivez moi sur Twitter
Rejoignez mon réseau LinkedIn ou Viadeo
Vous devez être identifié pour poster un commentaire.
, MathiasSeguy 
Bonjour,
Vous avez une activité qui utilise un Handler. Pour cela, vous avez créé votre Handler, redéfini sa méthode handleMessage, vous avez créé et lancer la thread associée au Handler et voilà c’est fini pour la gestion de votre Handler…
La plupart d’entre nous aurons fait un chose pareille et c’est une énorme erreur !!!
Qu’arrive-t-il à votre thread quand votre activité passe en pause, est relancée, est détruite puis re-créée ?
Votre thread devient une thread orpheline !!
Ainsi vous avez écrit quelque chose comme ça :
/**
* The handler
*/
private final Handler slowDownDrawingHandler;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
// handler definition
slowDownDrawingHandler = new Handler() {
/** (non-Javadoc)*/
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
redraw();
}
};
// Launching the Thread to update draw
Thread background = new Thread(new Runnable() {
/**
* The message exchanged between this thread and the handler
*/
Message myMessage;
// Overriden Run method
public void run() {
try {
while (true) {
// Sleep
Thread.sleep(100);
// Do something
myMessage = slowDownDrawingHandler.obtainMessage();
// then send the message
slowDownDrawingHandler.sendMessage(myMessage);
}
}
} catch (Throwable t) {
// just end the background thread
}
}
});
// start the thread
background.start();
En utilisant un code de ce type, quand votre activité meurt ou passé en pause, votre Thread devient orpheline. Plus rien ne peut l’atteindre, la détruire, communiqué avec elle… C’est une grosse erreur (genre tour Eiffel la taille de l’erreur, avec fuite mémoire et tout…).
Quelle est la façon de faire alors? Vous avez à gérer le cycle de vie de votre thread pour qu’elle soit en adéquation avec le cycle de vie de votre activité. Quand votre activité passé en pause, votre thread doit aussi passé en pause, quand elle est relancée votre thread doit l’être aussi, quand votre activité meurt votre thread aussi.
Une façon simple de faire cela est d’utiliser des AtomicBoolean (qui sont des Booleans synchronized) par exemple isPausing et isStopping, de changer leur valeur quand votre activité passe en pause, est relancée ou meurt et d’utiliser ces Booléens pour gérer le cycle de vie de votre thread.
Le code à utiliser est donc le suivant:
/** * The handler */
private final Handler slowDownDrawingHandler;
/** * An atomic boolean to manage the external thread's destruction */
AtomicBoolean isRunning = new AtomicBoolean(false);
/** * An atomic boolean to manage the external thread's destruction */
AtomicBoolean isPausing = new AtomicBoolean(false);
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
// handler definition
slowDownDrawingHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
redraw();
}
};
// Launching the Thread to update draw
Thread background = new Thread(new Runnable() {
/**
* The message exchanged between this thread and the handler
*/
Message myMessage;
// Overriden Run method
public void run() {
try {
while (isRunning.get()) {
if(isPausing.get()) {
Thread.sleep(2000);
}else {
// Sleep
Thread.sleep(100);
// Do something
myMessage = slowDownDrawingHandler.obtainMessage();
// then send the message
slowDownDrawingHandler.sendMessage(myMessage);
}
}
}
} catch (Throwable t) {
// just end the background thread
}
}
});
// Initialize the threadSafe booleans
isRunning.set(true);
isPausing.set(false);
background.start();
}
/*(non-Javadoc) */
@Override
protected void onPause() {
//and don't forget to stop the thread
isPausing.set(true);
super.onPause();
}
/*(non-Javadoc) */
@Override
protected void onResume() {
//and don't forget to relaunch the thread
isPausing.set(false);
super.onResume();
}
/*(non-Javadoc) */
@Override
protected void onDestroy() {
//and don't forget to kill the thread
isRunning.set(false);
super.onDestroy();
}
Ceci est un exemple de comment résoudre le problème de manière générique. A vous de vous poser la question est de trouver la solution la plus appropriée à la gestion des threads de votre application. Mais n’oubliez pas : une thread orpheline, c’est une erreur qui coûte un bras.
(Pour voir le code en couleur, c'est ici :Version anglaise colorama)
Alors, merci qui?
Merci, Android2ee, les Ebooks de programmation Android :o)
Mathias Séguy
mathias.seguy.it@gmail.com
Auteur Android2EE
Ebooks pour apprendre la programmation sous Android.

Retrouvez moi sur Google+
Suivez moi sur Twitter
Rejoignez mon réseau LinkedIn ou Viadeo
Vous devez être identifié pour poster un commentaire.

Bonjour
Un nouveau tutorial est en libre téléchargement sur Android2ee. Il permet de lister tous les capteurs de l'appareil. Simple.
Le tuto c'est ici: Tutos Android2EE et il se nomme MySensors.
(tous les tutoriaux de cette page ne sont pas en téléchargement libre, RSSReader, DynamicGui et MySensors le sont).
En préparation un articles sur ces capteurs (et quelques tutos aussi), a bientôt.
Alors, merci qui?
Merci, Android2ee, les Ebooks de programmation Android :o)
Mathias Séguy
mathias.seguy.it@gmail.com
Auteur Android2EE
Ebooks pour apprendre la programmation sous Android.

Retrouvez moi sur Google+
Suivez moi sur Twitter
Rejoignez mon réseau LinkedIn ou Viadeo
Vous devez être identifié pour poster un commentaire.

Bonjour
C'est assez simple. Il faut utiliser l'objet PowerManager pour récupérer l'objet PowerService puis l'objet PowerManager.WaveLock. Ensuite il faut demander à ce dernier de verrouiller le mode veille.
Ainsi dans votre activité, il faut déclarer les attributs suivants:
/**
* The WaveLock object
*/
private PowerManager.WakeLock dimWaveLock;
/**
* The tag to obtain the wave lock
*/
private static final String WAVE_LOCK_TAG = "MyLightLockTag";
Dans votre méthode onResume, il faut initialiser et acquérir le waveLock:
// The phone should not go in sleep mode:
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
dimWaveLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, WAVE_LOCK_TAG);
dimWaveLock.acquire();
Et dans la méthode onPause, libérer cet objet:
//and also don't forget to accept the phone go back in sleep mode
waveLock.release();
Le bonus de ce post, si vous souhaitez conserver la luminosité de votre écran, il faut effectuer la même chose mais avec le paramètre SCREEN_BRIGHT_WAKE_LOCK. Ce qui donne:
/**
* The WaveLock object
*/
private PowerManager.WakeLock dimWaveLock;
/**
* The WaveLock object
*/
private PowerManager.WakeLock screenWaveLock;
/**
* The tag to obtain the wave lock
*/
private static final String WAVE_LOCK_TAG = "MyLightLockTag";
....
/*
* (non-Javadoc)
*
* @see android.app.Activity#onResume()
*/
@Override
protected void onResume() {
…
// The phone should not go in sleep mode:
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
dimWaveLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, WAVE_LOCK_TAG);
screenWaveLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, WAVE_LOCK_TAG);
dimWaveLock.acquire();
screenWaveLock.acquire();
}
...
/*
* (non-Javadoc)
*
* @see android.app.Activity#onPause()
*/
@Override
protected void onPause() {
...
// and also don't forget to accept the phone go back in sleep mode
dimWaveLock.release();
screenWaveLock.release();
}
Alors, merci qui?
Merci, Android2ee, les Ebooks de programmation Android :o)
Mathias Séguy
mathias.seguy.it@gmail.com
Auteur Android2EE
Ebooks pour apprendre la programmation sous Android.

Retrouvez moi sur Google+
Suivez moi sur Twitter
Rejoignez mon réseau LinkedIn ou Viadeo
Vous devez être identifié pour poster un commentaire.
Ce blog à pour objectif de fournir des news ou des tips simples concernant la technologie Android.
Mathias Séguy (Android2EE.com)
| Lun | Mar | Mer | Jeu | Ven | Sam | Dim |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
Copyright © 2000-2012 - www.developpez.com