android 动态壁纸开发

转: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代码

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <wallpaper xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:thumbnail="@drawable/icon"  
  4. />  
复制代码

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



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

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

Java代码

  1. package com.lp.wallpaper;  
  2.   
  3. import java.text.SimpleDateFormat;  
  4. import java.util.Date;  
  5.   
  6. import android.graphics.Canvas;  
  7. import android.graphics.Color;  
  8. import android.graphics.Paint;  
  9. import android.os.Bundle;  
  10. import android.os.Handler;  
  11. import android.service.wallpaper.WallpaperService;  
  12. import android.view.MotionEvent;  
  13. import android.view.SurfaceHolder;  
  14.   
  15. public class MyWallpaper extends WallpaperService{  
  16.     private Handler handler = new Handler();  
  17.       
  18.       
  19.       
  20.     @Override  
  21.     public void onCreate() {  
  22.         System.out.println("service onCreate");  
  23.         super.onCreate();  
  24.     }  
  25.   
  26.     @Override  
  27.     public void onDestroy() {  
  28.         System.out.println("service onDestory");  
  29.         super.onDestroy();  
  30.     }  
  31.   
  32.     @Override  
  33.     public Engine onCreateEngine() {  
  34.         System.out.println("service onCreateEngine");  
  35.         return new MyEngine();  
  36.     }  
  37.       
  38.     private class MyEngine extends Engine{  
  39.          
  40.         private float x = 200;  
  41.         private float y = 300;  
  42.         private Paint mPaint;  
  43.         private boolean mVisible = false;  
  44.          
  45.         private Runnable drawThread = new Runnable() {  
  46.             public void run() {  
  47.                 drawWallpaper();  
  48.             }  
  49.         };  
  50.          
  51.         public MyEngine(){  
  52.             System.out.println("MyEngine");  
  53.             mPaint = new Paint();  
  54.             mPaint.setColor(Color.RED);  
  55.             mPaint.setAntiAlias(true);  
  56.             mPaint.setStrokeWidth(4);  
  57.             mPaint.setStyle(Paint.Style.STROKE);  
  58.             mPaint.setTextSize(24);  
  59.         }  
  60.   
  61.         @Override  
  62.         public Bundle onCommand(String action, int x, int y, int z, Bundle extras, boolean resultRequested) {  
  63.             // TODO Auto-generated method stub  
  64.             System.out.println("onCommand");  
  65.             return super.onCommand(action, x, y, z, extras, resultRequested);  
  66.         }  
  67.   
  68.         @Override  
  69.         public void onCreate(SurfaceHolder surfaceHolder) {  
  70.             System.out.println("onCreate");  
  71.             super.onCreate(surfaceHolder);  
  72.             //作用是使壁纸能响应touch event,默认是false  
  73.             setTouchEventsEnabled(true);  
  74.         }  
  75.   
  76.         @Override  
  77.         public void onDestroy() {  
  78.             System.out.println("onDestroy");  
  79.             super.onDestroy();  
  80.             handler.removeCallbacks(drawThread);  
  81.         }  
  82.   
  83.         @Override  
  84.         public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset) {  
  85.             // TODO Auto-generated method stub  
  86.             System.out.println("onoffsetsChanged");  
  87.             super.onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep, xPixelOffset, yPixelOffset);  
  88.         }  
  89.          
  90.         @Override  
  91.         public void onVisibilityChanged(boolean visible) {  
  92.             System.out.println("onVisibilityChanged");  
  93.             mVisible = visible;  
  94.             if (visible) {  
  95.                 //开始  
  96.                 handler.postDelayed(drawThread, 50);  
  97.             } else {  
  98.                 handler.removeCallbacks(drawThread);  
  99.             }  
  100.         }  
  101.   
  102.         @Override  
  103.         public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {  
  104.             System.out.println("onSurfaceChanged");  
  105.             // TODO Auto-generated method stub  
  106.             super.onSurfaceChanged(holder, format, width, height);  
  107.         }  
  108.   
  109.         @Override  
  110.         public void onSurfaceCreated(SurfaceHolder holder) {  
  111.             System.out.println("onSurfaceCreated");  
  112.             super.onSurfaceCreated(holder);  
  113.         }  
  114.   
  115.         @Override  
  116.         public void onSurfaceDestroyed(SurfaceHolder holder) {  
  117.             System.out.println("onSurfaceDestoryed");  
  118.             // TODO Auto-generated method stub  
  119.             super.onSurfaceDestroyed(holder);  
  120.             handler.removeCallbacks(drawThread);  
  121.         }  
  122.   
  123.         @Override  
  124.         public void onTouchEvent(MotionEvent event) {  
  125.             System.out.println("onTouchEvent");  
  126.             // TODO Auto-generated method stub  
  127.             super.onTouchEvent(event);  
  128.         }  
  129.          
  130.          
  131.         private void drawWallpaper() {  
  132.               
  133.             SurfaceHolder holder = getSurfaceHolder();  
  134.             Canvas canvas = holder.lockCanvas();  
  135.             drawTime(canvas);  
  136.             holder.unlockCanvasAndPost(canvas);  
  137.               
  138.             //循环执行  
  139.             handler.postDelayed(drawThread, 50);  
  140.         }  
  141.   
  142.         private void drawTime(Canvas canvas) {  
  143.             Date date = new Date(System.currentTimeMillis());  
  144.             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");  
  145.             String dataStr = sdf.format(date);  
  146.             canvas.save();  
  147.             canvas.drawColor(0xff00ff00);  
  148.             canvas.drawText(dataStr, x, y, mPaint);  
  149.             canvas.restore();  
  150.         }  
  151.     }  
  152.   
  153. }  
复制代码

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



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

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

onOffsetsChanged():

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

onVisibilityChanged()

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

onCommand()

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

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

setTouchEventsEnabled(true)

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

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

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

Java代码

  1. private class MyEngine extends Engine{  
  2.         //这里定义一个线程  
  3.         private Runnable drawThread = new Runnable() {  
  4.             public void run() {  
  5.                 drawWallpaper();  
  6.             }  
  7.         };  
  8.         //构造方法里面 一般初始化Paint对象  
  9.         public MyEngine(){  
  10.             System.out.println("MyEngine");  
  11.             mPaint = new Paint();  
  12.             mPaint.setColor(Color.RED);  
  13.             mPaint.setAntiAlias(true);  
  14.             mPaint.setStrokeWidth(4);  
  15.             mPaint.setStyle(Paint.Style.STROKE);  
  16.             mPaint.setTextSize(24);  
  17.         }  
  18.   
  19.                 //这里 调用setTouchEventsEnabled(true);即可  
  20.         @Override  
  21.         public void onCreate(SurfaceHolder surfaceHolder) {  
  22.             System.out.println("onCreate");  
  23.             super.onCreate(surfaceHolder);  
  24.             //作用是使壁纸能响应touch event,默认是false  
  25.             setTouchEventsEnabled(true);  
  26.         }  
  27.                 //取消callback  
  28.         @Override  
  29.         public void onDestroy() {  
  30.             System.out.println("onDestroy");  
  31.             super.onDestroy();  
  32.             handler.removeCallbacks(drawThread);  
  33.         }  
  34.                 //当显示的时候 绑定callback 不显示时  取消callback         
  35.         @Override  
  36.         public void onVisibilityChanged(boolean visible) {  
  37.             System.out.println("onVisibilityChanged");  
  38.             mVisible = visible;  
  39.             if (visible) {  
  40.                 //开始  
  41.                 handler.postDelayed(drawThread, 50);  
  42.             } else {  
  43.                 handler.removeCallbacks(drawThread);  
  44.             }  
  45.         }  
  46.   
  47.         @Override  
  48.         public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {  
  49.             System.out.println("onSurfaceChanged");  
  50.             // TODO Auto-generated method stub  
  51.             super.onSurfaceChanged(holder, format, width, height);  
  52.         }  
  53.   
  54.         @Override  
  55.         public void onSurfaceCreated(SurfaceHolder holder) {  
  56.             System.out.println("onSurfaceCreated");  
  57.             super.onSurfaceCreated(holder);  
  58.         }  
  59.                  //取消callback  
  60.         @Override  
  61.         public void onSurfaceDestroyed(SurfaceHolder holder) {  
  62.             System.out.println("onSurfaceDestoryed");  
  63.             // TODO Auto-generated method stub  
  64.             super.onSurfaceDestroyed(holder);  
  65.             handler.removeCallbacks(drawThread);  
  66.         }  
  67.                 //处理点击事件 比如说 点击时 出现水波等  
  68.         @Override  
  69.         public void onTouchEvent(MotionEvent event) {  
  70.             System.out.println("onTouchEvent");  
  71.             // TODO Auto-generated method stub  
  72.             super.onTouchEvent(event);  
  73.         }  
  74.          
  75.         //得到surfaceholder和canvas 并调用核心处理方法  
  76.         private void drawWallpaper() {  
  77.               
  78.             SurfaceHolder holder = getSurfaceHolder();  
  79.             Canvas canvas = holder.lockCanvas();  
  80.             drawTime(canvas);  
  81.             holder.unlockCanvasAndPost(canvas);  
  82.               
  83.             //循环执行  
  84.             handler.postDelayed(drawThread, 50);  
  85.         }  
  86.                 //核心处理方法  
  87.         private void drawTime(Canvas canvas) {  
  88.               
  89.         }  
  90.     }  
复制代码

4、在AndroidManifes.xml里面注册service

Java代码

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.       package="com.lp.wallpaper">  
  4.     <uses-sdk android:minSdkVersion="7" />  
  5.     <uses-feature android:name="android.software.live_wallpaper" />  
  6.   
  7.     <application   
  8.         android:icon="@drawable/icon"   
  9.         android:label="@string/app_name">  
  10.       
  11.         <service   
  12.             android:label="@string/app_name"  
  13.             android:name=".MyWallpaper"  
  14.             android:permission="android.permission.BIND_WALLPAPER">  
  15.             <intent-filter>  
  16.                 <action android:name="android.service.wallpaper.WallpaperService" />   
  17.             </intent-filter>  
  18.             <meta-data android:name="android.service.wallpaper" android:resource="@xml/mylivewallpaper" />      
  19.         </service>  
  20.   
  21.     </application>  
  22. </manifest>  
复制代码

除了

  1. android:resource="@xml/mylivewallpaper"  
复制代码

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

  1. <uses-sdk android:minSdkVersion="7" />  
  2. <uses-feature android:name="android.software.live_wallpaper" />  
  3. 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

posted on 2014-09-17 21:21  leihupqrst  阅读(2004)  评论(0编辑  收藏  举报

导航