android 动态壁纸开发

2023-05-22,,

转:http://www.eoeandroid.com/thread-100389-1-1.html

android 动态壁纸开发
参考:http://www.ophonesdn.com/article/show/278
推荐:http://www.oschina.net/code/snippet_203635_7426
http://blog.csdn.net/homebei2/article/details/6079580
resources/articles/live-wallpapers.html

自己做了一个非常简单的 只是想了解过程 源码见附件 步骤如下:

1、新建一个Android工程  然后进入工程的/res/文件夹,删除layout这个文件夹,当然里面的main.xml也会被删除的,对于Live Wallpaper来说传统的布局文件是不需要的。

2、在res下面新建一个xml文件夹 然后新建一个mylivewallpaper.xml 内容如下:

Java代码

    <?xml version="1.0" encoding="utf-8"?>
    <wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
    android:thumbnail="@drawable/icon"
    />

复制代码

这里的android:thumbnail值得是你这个动态壁纸的小图标 会在你选着动态壁纸的时候出现 如下图:

这个可以自己选一个好看一点的

3、开始编写代码了  直接看吧

Java代码

    package com.lp.wallpaper;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.os.Bundle;
    import android.os.Handler;
    import android.service.wallpaper.WallpaperService;
    import android.view.MotionEvent;
    import android.view.SurfaceHolder;
    public class MyWallpaper extends WallpaperService{
    private Handler handler = new Handler();
    @Override
    public void onCreate() {
    System.out.println("service onCreate");
    super.onCreate();
    }
    @Override
    public void onDestroy() {
    System.out.println("service onDestory");
    super.onDestroy();
    }
    @Override
    public Engine onCreateEngine() {
    System.out.println("service onCreateEngine");
    return new MyEngine();
    }
    private class MyEngine extends Engine{
    private float x = 200;
    private float y = 300;
    private Paint mPaint;
    private boolean mVisible = false;
    private Runnable drawThread = new Runnable() {
    public void run() {
    drawWallpaper();
    }
    };
    public MyEngine(){
    System.out.println("MyEngine");
    mPaint = new Paint();
    mPaint.setColor(Color.RED);
    mPaint.setAntiAlias(true);
    mPaint.setStrokeWidth(4);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setTextSize(24);
    }
    @Override
    public Bundle onCommand(String action, int x, int y, int z, Bundle extras, boolean resultRequested) {
    // TODO Auto-generated method stub
    System.out.println("onCommand");
    return super.onCommand(action, x, y, z, extras, resultRequested);
    }
    @Override
    public void onCreate(SurfaceHolder surfaceHolder) {
    System.out.println("onCreate");
    super.onCreate(surfaceHolder);
    //作用是使壁纸能响应touch event,默认是false
    setTouchEventsEnabled(true);
    }
    @Override
    public void onDestroy() {
    System.out.println("onDestroy");
    super.onDestroy();
    handler.removeCallbacks(drawThread);
    }
    @Override
    public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset) {
    // TODO Auto-generated method stub
    System.out.println("onoffsetsChanged");
    super.onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep, xPixelOffset, yPixelOffset);
    }
    @Override
    public void onVisibilityChanged(boolean visible) {
    System.out.println("onVisibilityChanged");
    mVisible = visible;
    if (visible) {
    //开始
    handler.postDelayed(drawThread, 50);
    } else {
    handler.removeCallbacks(drawThread);
    }
    }
    @Override
    public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    System.out.println("onSurfaceChanged");
    // TODO Auto-generated method stub
    super.onSurfaceChanged(holder, format, width, height);
    }
    @Override
    public void onSurfaceCreated(SurfaceHolder holder) {
    System.out.println("onSurfaceCreated");
    super.onSurfaceCreated(holder);
    }
    @Override
    public void onSurfaceDestroyed(SurfaceHolder holder) {
    System.out.println("onSurfaceDestoryed");
    // TODO Auto-generated method stub
    super.onSurfaceDestroyed(holder);
    handler.removeCallbacks(drawThread);
    }
    @Override
    public void onTouchEvent(MotionEvent event) {
    System.out.println("onTouchEvent");
    // TODO Auto-generated method stub
    super.onTouchEvent(event);
    }
    private void drawWallpaper() {
    SurfaceHolder holder = getSurfaceHolder();
    Canvas canvas = holder.lockCanvas();
    drawTime(canvas);
    holder.unlockCanvasAndPost(canvas);
    //循环执行
    handler.postDelayed(drawThread, 50);
    }
    private void drawTime(Canvas canvas) {
    Date date = new Date(System.currentTimeMillis());
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    String dataStr = sdf.format(date);
    canvas.save();
    canvas.drawColor(0xff00ff00);
    canvas.drawText(dataStr, x, y, mPaint);
    canvas.restore();
    }
    }
    }

复制代码

实现的效果是一个动态改变的时间 如下图:

我们一一来解释:
onCreateEngine() :

启动一个WallpaperService.Engine 这个engine才是负责绘制壁纸以及响应与用户交互事件的核心部件 这个方法也是必须要重写的 并且是WallpaperService和service的主要区别

onOffsetsChanged():

这个一般在几个屏幕滑动的时候调用 而且 当你拖动A屏幕向B屏幕过度时 会随着B屏幕的显示面积的变大或者变小一直调用这个方法

onVisibilityChanged()

这个是屏幕显示或者不显示的时候调用的 必须完全覆盖屏幕才会调用

onCommand()

可以给壁纸发送一些命令 让其执行

onTouchEvent()
处理壁纸的点击时间的

setTouchEventsEnabled(true)

作用是使壁纸能响应touch event,默认是false

其他的看名字应该就知道了 呵呵

这里也说下Engine的惯用写法吧

Java代码

    private class MyEngine extends Engine{
    //这里定义一个线程
    private Runnable drawThread = new Runnable() {
    public void run() {
    drawWallpaper();
    }
    };
    //构造方法里面 一般初始化Paint对象
    public MyEngine(){
    System.out.println("MyEngine");
    mPaint = new Paint();
    mPaint.setColor(Color.RED);
    mPaint.setAntiAlias(true);
    mPaint.setStrokeWidth(4);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setTextSize(24);
    }
    //这里 调用setTouchEventsEnabled(true);即可
    @Override
    public void onCreate(SurfaceHolder surfaceHolder) {
    System.out.println("onCreate");
    super.onCreate(surfaceHolder);
    //作用是使壁纸能响应touch event,默认是false
    setTouchEventsEnabled(true);
    }
    //取消callback
    @Override
    public void onDestroy() {
    System.out.println("onDestroy");
    super.onDestroy();
    handler.removeCallbacks(drawThread);
    }
    //当显示的时候 绑定callback 不显示时  取消callback
    @Override
    public void onVisibilityChanged(boolean visible) {
    System.out.println("onVisibilityChanged");
    mVisible = visible;
    if (visible) {
    //开始
    handler.postDelayed(drawThread, 50);
    } else {
    handler.removeCallbacks(drawThread);
    }
    }
    @Override
    public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    System.out.println("onSurfaceChanged");
    // TODO Auto-generated method stub
    super.onSurfaceChanged(holder, format, width, height);
    }
    @Override
    public void onSurfaceCreated(SurfaceHolder holder) {
    System.out.println("onSurfaceCreated");
    super.onSurfaceCreated(holder);
    }
    //取消callback
    @Override
    public void onSurfaceDestroyed(SurfaceHolder holder) {
    System.out.println("onSurfaceDestoryed");
    // TODO Auto-generated method stub
    super.onSurfaceDestroyed(holder);
    handler.removeCallbacks(drawThread);
    }
    //处理点击事件 比如说 点击时 出现水波等
    @Override
    public void onTouchEvent(MotionEvent event) {
    System.out.println("onTouchEvent");
    // TODO Auto-generated method stub
    super.onTouchEvent(event);
    }
    //得到surfaceholder和canvas 并调用核心处理方法
    private void drawWallpaper() {
    SurfaceHolder holder = getSurfaceHolder();
    Canvas canvas = holder.lockCanvas();
    drawTime(canvas);
    holder.unlockCanvasAndPost(canvas);
    //循环执行
    handler.postDelayed(drawThread, 50);
    }
    //核心处理方法
    private void drawTime(Canvas canvas) {
    }
    }

复制代码

4、在AndroidManifes.xml里面注册service

Java代码

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.lp.wallpaper">
    <uses-sdk android:minSdkVersion="7" />
    <uses-feature android:name="android.software.live_wallpaper" />
    <application
    android:icon="@drawable/icon"
    android:label="@string/app_name">
    <service
    android:label="@string/app_name"
    android:name=".MyWallpaper"
    android:permission="android.permission.BIND_WALLPAPER">
    <intent-filter>
    <action android:name="android.service.wallpaper.WallpaperService" />
    </intent-filter>
    <meta-data android:name="android.service.wallpaper" android:resource="@xml/mylivewallpaper" />
    </service>
    </application>
    </manifest>

复制代码

除了

    android:resource="@xml/mylivewallpaper"

复制代码

是可以自己修改 其他的都是必须得 特别强调几个:

    <uses-sdk android:minSdkVersion="7" />
    <uses-feature android:name="android.software.live_wallpaper" />
    android:permission="android.permission.BIND_WALLPAPER"

复制代码

5、自己的一些关于方法执行顺序的测试信息:
当进入改壁纸的设置页面 但是还没有设置时
09-21 07:55:05.575: INFO/System.out(1337): service onCreate
09-21 07:55:05.614: INFO/System.out(1337): service onCreateEngine
09-21 07:55:05.634: INFO/System.out(1337): MyEngine
09-21 07:55:05.663: INFO/System.out(1337): onCreate
09-21 07:55:05.746: INFO/System.out(1337): onSurfaceCreated
09-21 07:55:05.753: INFO/System.out(1337): onSurfaceChanged
09-21 07:55:05.785: INFO/System.out(1337): onVisibilityChanged

当点击设置壁纸按钮后
09-21 07:55:19.434: INFO/System.out(1337): onTouchEvent
09-21 07:55:19.574: INFO/System.out(1337): onTouchEvent
09-21 07:55:20.283: INFO/System.out(1337): service onCreateEngine
09-21 07:55:20.294: INFO/System.out(1337): MyEngine
09-21 07:55:20.304: INFO/System.out(1337): onCreate
09-21 07:55:20.414: INFO/System.out(1337): onSurfaceCreated
09-21 07:55:20.424: INFO/System.out(1337): onSurfaceChanged
09-21 07:55:20.443: INFO/System.out(1337): onVisibilityChanged
09-21 07:55:20.443: INFO/System.out(1337): onoffsetsChanged
09-21 07:55:20.863: INFO/System.out(1337): onVisibilityChanged
09-21 07:55:21.305: INFO/System.out(1337): onSurfaceDestoryed
09-21 07:55:21.333: INFO/System.out(1337): onDestroy

在壁纸上面点击
09-21 07:55:34.654: INFO/System.out(1337): onTouchEvent
09-21 07:55:34.754: INFO/System.out(1337): onTouchEvent
09-21 07:55:34.754: INFO/System.out(1337): onCommand

启动其他程序 完全覆盖屏幕
09-21 07:56:03.855: INFO/System.out(1337): onTouchEvent
09-21 07:56:03.884: INFO/System.out(1337): onTouchEvent
09-21 07:56:04.494: INFO/System.out(1337): onVisibilityChanged

设置其他壁纸 代替自己的壁纸
09-21 07:56:34.893: INFO/System.out(1337): onSurfaceDestoryed
09-21 07:56:34.893: INFO/System.out(1337): onDestroy
09-21 07:56:34.953: INFO/System.out(1337): service onDestory

android 动态壁纸开发的相关教程结束。

《android 动态壁纸开发.doc》

下载本文的Word格式文档,以方便收藏与打印。