Live Wallpaper

 

Le live wallpaper est une animation qui tourne en fond sur l'écran d'accueil Android. Or il est possible de coder son propre live wallpaper pour l'écran d'acceuil !

 

Les grandes lignes

L'utilisateur peut à partir de l'accueil choisir d'installer un live wallpaper. Android ne présente alors que les lives wallpaper disponibles sur le système. Cela signifie:

- Création d'une activité particulière de type wallpaper pour pouvoir fonctionner en collaboration avec l'écran d'accueil, et positionnement d'un filtre d'intention afin qu'android trouve ce wallpaper. On ajoutera qu'il est nécessaire d'avoir des droits pour pouvoir installer l'application sur le système.

- L'utilisateur peut alors paramétrer et pré-visualiser le live wallpaper. Il faudra donc prévoir tout cela aussi.

- Enfin, affichage du wall paper dans l'écran d'accueil. Donc nécessité d'avoir une surface et la possibilité de travailler dans l'UI Thread (objet runnable) pour pouvoir boucler de manière régulière sur le traitement de calcul et de dessin de votre animation.

 

Première étape - création du projet

Création d'un projet Android sans génération d'activité. Vous allez tout faire à la main.

 

Deuxième étape - création d'une ressource wallpaper

Création d'un fichier de ressource XML sous res/xml. Vous pouvez nommer ce fichier comme vous le voulez, sachant que le nom de ce fichier (sans .xml) sera nécessairement une ressource à utiliser ensuite (dans le fichier ManifestAndroid.xml) !

Le contenu du fichier XML étant le suivant:

Image non trouvée !Vous pouvez faire un copier/coller de ce fichier, car l'écriture du contenu de ce fichier est imposée. Impossible par exemple de mettre en dur le nom de l'auteur, il faut passer par une ressource string.

Par conséquent, il faudra définir dans le fichier strings.xml

app_name: Nom de l'application. C'est ce nom qui sera affiché à l'utilisateur lorsqu'il verra s'afficher la liste des wallpapers disponibles.

author: le nom de l'auteur de live wallpaper.

description: une description du wallpaper

wallpapericon un drawable pour afficher l'image représentant le wallpaper lors de la sélection d'un live wallpaper par l'utilisateur. Ici, je ne me fatigue pas, j'indique juste une couleur rouge...Si vous avez une icone (par exemple celle générée par défaut nommée ic_launcher.png) dans vos différents répertoires drawable sous res, vous pouvez remplacer dans la ressource XML sous res/xml la ligne par android:thumbnail="@drawable/ic_launcher"

 

Troisième étape - le wallpaper service

Il s'agit ici de définir un service wallpaper avec tout le nécessaire pour gérer un wallpaper en live !

public class MonLiveWallpaperService extends WallpaperService { ... }

Avec une méthode:

@Override
public Engine onCreateEngine() {

return new MonWallPaperServiceEngine();

}

Cette méthode va retourner une instance de type WallPaperService.Engine

Image non trouvée !WallPaperService.Engine est une sous classe de WallpaperService qui est une classe abstraite. Il n'est donc pas possible de créer WallPaperService.Engine en dehors de votre classe MonLiveWallpaperService sous peine d'avoir un message d'erreur:

No enclosing instance of type WallpaperService is accessible to invoke the super constructor. Must define a constructor and explicitly qualify its super constructor invocation with an instance of WallpaperService.

Et vous allez chercher longtemps avant de comprendre !

 

La classe WallPaperService.Engine ayant les méthodes suivantes:

public void onCreate(SurfaceHolder surfaceHolder)

Méthode lancée lors de la création de l'instance Engine. Il sera possible de récupérer le gestionnaire de surface surfaceHolder

public void onSurfaceDestroyed (SurfaceHolder holder)

Méthode pour indiquer que le gestionnaire de surface n'est plus disponible !

public void onDestroy()

Cette méthode permettra de mettre fin à l'animation. Et oui, qui dit live wallpaper dit wallpaper animé ! Il faut donc arrêter cette animation.

public void onVisibilityChanged(boolean visible)

Méthode très importante, car elle indique que le live wallpaper est visible ou non à l'utilisateur. Il sera possible de mettre en pause l'animation si celle-ci n'est plus visible, pour limiter une consommation de la batterie inutile !

public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset)

Cette méthode permet de savoir que l'utilisateur se déplace dans les pages de l'écran d'accueil.

public void onTouchEvent(MotionEvent event)

Cette méthode est déclenchée lorsque l'utilisateur touche l'écran. Similaire au touchscreen.

Image non trouvée !onTouchEvent est déclenchée systèmatiquement lors d'une pression à l'écran qu'un widget soit présent ou non sous votre doigt. Il peut être intéressant de ne recevoir cette information que si l'utilisateur presse une zone où seul le wallpaper est présent, pas de widgets dans la zone pressée, ...

Dans ce cas, il vaut mieux implémenter la méthode onCommand et traiter l'information WallpaperManager.COMMAND_TAP de la manière suivante:

public void onSurfaceCreated(SurfaceHolder holder)

Création d'une surface. Ce n'est qu'à ce moment que vous pourrez envisager de dessiner !

 

Des méthodes qui seront intéressantes:

SurfaceHolder android.service.wallpaper.WallpaperService.Engine.getSurfaceHolder()

qui permet de récupérer le gestionnaire de surfaces. Il sera alors possible de récupérer un canevas pour dessiner.

public boolean isPreview () permet de savoir si le live wallpaper est affiché en preview ou sur l'écran d'accueil

public int getDesiredMinimumWidth () et public int getDesiredMinimumHeight () indique les dimensions souhaitées par le système pour le wallpaper.

public void onSurfaceRedrawNeeded (SurfaceHolder holder) pour une surface qu'il faut redessiner.

 

A cela, il faudra un objet runnable:

qui fera appel à une méthode perso. drawFrame(). L'objet runnable sera lancé la première fois grace à la méthode onSurfaceCreated();

C'est dans cette méthode drawFrame que sera lancée l'exécution retardé de l'objet runnable. Retardé du nombre de frames que l'on veut obtenir par seconde (constante FPS dans mon exemple soit 1000/FPS).

La gestion du booléen visible permet de lancer ou non l'objet runnable. Ce booléen sera initialisé dans la méthode onSurfaceCreated() à vrai et modifié dans la méthode onVisibilityChanged() suivant la visibilité de l'écran d'accueil à l'utilisateur.

 

Quatrième étape - Le fichier ManifestAndroid.xml

Les nouveautés sont:

la permission android.permission.BIN_WALLPAPER pour permettre l'installation de votre live wallpaper.

Le service wallpaper référençant votre classe WallpaperService précédemment créée. Sera aussi précisé un filtre d'intention pour permettre à Android de connaître le wallpaper et l'indiquation de la ressource .xml créée au tout début.

 

Et enfin, une méthode paintSurface qui aura en charge de récupérer un canevas afin de dessiner votre animation.

 

Exemple

On reprend...

monlivewallpaper.xml sous res/xml

Le fichier strings.xml

 

La classe MonLiveWallpaperService

Et AndroidManifest.xml

 

Le setup du wallpaper

Il est possible, mais non obligatoire d'avoir un setup pour le wallpaper développé (par exemple laisser le choix à l'utilisateur du nombre de frames/sec., de choisir une image de fond, une couleur, ...)

Pour configurer le wallpaper, il suffit de se créer une activité standard.

Cette activité devra être déclarée de manière classique dans le fichier ManifestAndroid.xml.

Par contre, il faudra définir dans le fichier XML du wallpaper qu'il existe une activité permettant la saisie de la configuration en ajoutant la ligne suivante:

android:settingsActivity="fr.free.supertos.MonSetupActivity"

Exemple très très basique (puisqu'il se contente d'afficher setup à l'écran !) avec la classe MonSetupActivity

 

Le fichier monlivewallpaper.xml adapté:

Et le fichier ManifestAndroid.xml

Dans le cas présent, j'autorise le lancement du setup depuis le lanceur d'application. Si vous voulez que l'activité ne soit lancée que depuis l'écran de sélection des fonds d'écrans animés, il faudra positionner des filtres d'intention par exemple comme ceci:

Vous pourrez utiliser le système de gestion des fichiers de préférences pour stocker les paramètres saisis par l'utilisateur.

 

Installation automatique d'un live wallpaper

Depuis l'API 17 (jelly bean), il est possible de lancer automatiquement l'écran de preview sur le live wallpaper. Il suffit de lancer une intention:

Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT,
new ComponentName(this, MonLiveWallpaperService.class));
startActivity(intent);