Wednesday, 12 July 2017

Créer un Live Wallpaper sous Android

Créer un Live Wallpaper sous Android



  • Un live wallpaper a un contenu dynamique, ce qui permet d�avoir des animations. C�est donc � vous de g�rer les diff�rentes �tapes de dessin sur le wallpaper. Pour cela, on utilise les deux classes Runnable et Handler.

    Le handler envoi le runnable (ici drawer) dans le messageQueue associ� � l�UI Thread afin qu�il soit ex�cut�. Ce runnable se charge de dessiner sur le wallpaper gr�ce � la m�thode draw() qu�on expliquera plus tard. R�p�ter plusieurs fois ce m�canisme nous permet d�avoir une animation.

    Quand le wallpaper doit s�arr�ter, la variable visible (qui stocke la visibilit� actuelle du wallpaper) passe � false dans les m�thodes onSurfaceDestroyed()et onVisibilityChanged() ce qui stoppera l�animation (m�thode handler.removeCallbacks(drawer).)

    Quand le wallpaper devient visible, la variable visible passe � true dans la m�thode onVisibilityChanged() , ce qui relance l�animation du wallpaper (m�thode handler.post(drawer).)

    Voyons maintenant comment on dessine sur le wallpaper, la m�thode facilitant cette op�ration est la m�thode draw() :

    private void draw() {
    SurfaceHolder holder = getSurfaceHolder();
    Canvas canvas = null;
    try {
    canvas = holder.lockCanvas();
    if (canvas != null) {
    float x = (width * random.nextFloat());
    float y = (height * random.nextFloat());
    drawImage(canvas, x, y);
    }
    } finally {
    if (canvas != null)
    holder.unlockCanvasAndPost(canvas);
    }
    handler.removeCallbacks(drawer);
    if (visible) {
    //On re-poste le runnable apr�s un petit laps de temps
    handler.postDelayed(drawer, 4000);
    }
    }


    La m�thode qui permet de dessiner l�image dans le canvas est d�crite ci-dessous�:

    private void drawImage(Canvas canvas, float x, float y) {
    canvas.drawColor(Color.WHITE);
    canvas.drawBitmap(androidPic, x-(androidPic.getWidth()/2), y-(androidPic.getHeight()/2), null);
    }


    Sans oublier de d�clarer la variable qui repr�sente l�image qu�on veut dessiner�:

    Bitmap androidPic = BitmapFactory.decodeResource(getResources(), R.drawable.android);


    Explications :

    Nous avons utilis� un Canvas, ce qui nous permet de dessiner de mani�re r�p�titive sur la Surface du wallpaper. Cette surface est fournie par la classe ��SurfaceView��.

    Afin de manipuler cette surface on utilise l�interface SurfaceHolder. On obtient le canvas grace � la m�thode lockCanvas(), puis on dessine sur un point du canvas avec la m�thode drawImage().Ce point est obtenu al�atoirement gr�ce � ses coordonn�s (x,y).

    Enfin la m�thode unlockCanvasAndPost(canvas) est appel� pour que le canvas soit d�ssin� sur la surface du wallpaper.

    Gestion des �v�nements tactiles�:


    Cela se fait gr�ce � la m�thode onTouchEvent(MotioEvent event), cette m�thode poss�de le m�me comportement que la m�thode draw(), sauf que cette fois les coordonn�es du point o� s�effectue le dessin sont obtenus � l�endroit ou l�interaction utilisateur est effectu�e.

    @Override
    public void onTouchEvent(MotionEvent event) {
    float X = event.getX();
    float Y = event.getY();
    SurfaceHolder holder = getSurfaceHolder();
    Canvas canvas = null;
    try {
    canvas = holder.lockCanvas();
    if (canvas != null) {
    canvas.drawColor(Color.WHITE);
    drawImage(canvas, X, Y);
    }
    } finally {
    if (canvas != null)
    holder.unlockCanvasAndPost(canvas);
    }
    handler.removeCallbacks(drawer);
    if (visible) {
    handler.postDelayed(drawer, 4000);
    }
    super.onTouchEvent(event);
    }

    Ce qui donnera :
    import java.util.Random;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.os.Handler;
    import android.service.wallpaper.WallpaperService;
    import android.view.MotionEvent;
    import android.view.SurfaceHolder;

    public class MyLiveWallpaper extends WallpaperService {

    private static Random random = new Random() ;

    @Override
    public Engine onCreateEngine() {
    return new LiveWallpaperEngine();
    }

    private class LiveWallpaperEngine extends Engine {

    private final Handler handler = new Handler();
    private final Runnable drawer = new Runnable() {
    @Override
    public void run() {
    draw();
    }
    };

    private boolean visible = true;
    private int width;
    private int height;
    Bitmap androidPic = BitmapFactory.decodeResource(getResources(), R.drawable.android);

    public LiveWallpaperEngine() {
    handler.post(drawer);
    }

    @Override
    public void onCreate(SurfaceHolder surfaceHolder) {
    super.onCreate(surfaceHolder);
    setTouchEventsEnabled(true);
    }

    @Override
    public void onDestroy() {
    super.onDestroy();
    handler.removeCallbacks(drawer);
    }

    @Override
    public void onSurfaceCreated(SurfaceHolder holder) {
    super.onSurfaceCreated(holder);
    }

    @Override
    public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    this.width = width;
    this.height = height;
    super.onSurfaceChanged(holder, format, width, height);
    }

    @Override
    public void onSurfaceDestroyed(SurfaceHolder holder) {
    super.onSurfaceDestroyed(holder);
    this.visible = false;
    handler.removeCallbacks(drawer);
    }

    @Override
    public void onVisibilityChanged(boolean visible) {
    this.visible = visible;
    if (visible) {
    handler.post(drawer);
    } else {
    handler.removeCallbacks(drawer);
    }
    }

    @Override
    public void onTouchEvent(MotionEvent event) {
    float X = event.getX();
    float Y = event.getY();
    SurfaceHolder holder = getSurfaceHolder();
    Canvas canvas = null;
    try {
    canvas = holder.lockCanvas();
    if (canvas != null) {
    canvas.drawColor(Color.WHITE);
    drawImage(canvas, X, Y);
    }
    } finally {
    if (canvas != null)
    holder.unlockCanvasAndPost(canvas);
    }
    handler.removeCallbacks(drawer);
    if (visible) {
    handler.postDelayed(drawer, 4000);
    }
    super.onTouchEvent(event);
    }

    private void draw() {
    SurfaceHolder holder = getSurfaceHolder();
    Canvas canvas = null;
    try {
    canvas = holder.lockCanvas();
    if (canvas != null) {
    float x = (width * random.nextFloat());
    float y = (height * random.nextFloat());
    drawImage(canvas, x, y);
    }
    } finally {
    if (canvas != null)
    holder.unlockCanvasAndPost(canvas);
    }
    handler.removeCallbacks(drawer);
    if (visible) {
    //On re-poste le runnable apr�s un petit laps de temps
    handler.postDelayed(drawer, 4000);
    }
    }

    // Permet de dessiner limage dans le canvas
    private void drawImage(Canvas canvas, float x, float y) {
    canvas.drawColor(Color.WHITE);
    canvas.drawBitmap(androidPic, x-(androidPic.getWidth()/2), y-(androidPic.getHeight()/2), null);
    }
    }
    }


    Derni�re �tape, on d�clare notre service dans l�AndroidManifest.xml avec l�action ��android.service.wallpaper.WallpaperService�� et la permission ��android.permission.BIND_WALLPAPER�� qui autorise l�utilisation du Live Wallpaper.
    Notons aussi l�ajout de la balise uses-feature , qui indique � Google Play que votre application contient un Live Wallpaper, pour que celle�ci soit visible qu�aux utilisateurs ayant un device supportant les live wallpapers.

    ?xml version="1.0" encoding="utf-8"?
    manifest
    package="com.tuto.android"
    android_versionCode="1"
    android_versionName="1.0"

    uses-sdk android_minSdkVersion="10" /
    uses-feature android_name="android.software.live_wallpaper"/uses-feature

    application
    android_label="@string/app_name"
    android_icon="@drawable/ic_launcher"

    service
    android_label="@string/my_live_wallpaper"
    android_name=".MyLiveWallpaper"
    android_permission="android.permission.BIND_WALLPAPER"
    intent-filter
    action android_name="android.service.wallpaper.WallpaperService"/action
    /intent-filter
    meta-data android_name="android.service.wallpaper"
    android_resource="@xml/mywallpaper"/meta-data
    /service
    /application

    /manifest

    Sans oublier le String.xml�:
    ?xml version="1.0" encoding="UTF-8"?
    resources

    string name="app_name"Live Wallpaper/string
    string name="my_live_wallpaper"My Live Wallpaper/string
    string name="wallpaper_description"My first live wallpaper/string

    /resources


    Remarque�:


    Pour g�rer les pr�f�rences de votre wallepaper, cr�ez une Pr�f�renceActivity qui permettra de d�finir les configurations de votre fond d��cran. La r�cup�ration des valeurs de vos pr�f�rences s�effectue � l�aide des SharedPreference. Pour cela, ajoutez les lignes suivantes � votre ��wallpaper.xml��:

    android:settingsActivity="MyPreferenceActivity"/


    sans oublier de d�clarer votre activit� dans l�AndroidManifest.xml.

    Lancez maintenant votre application, s�lectionnez le Live Wallpaper que vous avez cr�� afin d�obtenir le r�sultat suivant�:



  • Cr�er un Live Wallpaper sous Android


    Conclusion


    Voila, j�esp�re que cet article vous � permis de mieux comprendre comment fonctionnent les live wallpapers,le code du projet est disponible ici.
    Maintenant place � votre imagination pour cr�er vos propre fond d��cran anim�s.

download
alternative link download

Like the Post? Do share with your Friends.