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

复制代码

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

我们一一来解释:
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. //这里 调用setTouchEventsEnabled(true);即可
  19. @Override
  20. public void onCreate(SurfaceHolder surfaceHolder) {
  21. System.out.println("onCreate");
  22. super.onCreate(surfaceHolder);
  23. //作用是使壁纸能响应touch event,默认是false
  24. setTouchEventsEnabled(true);
  25. }
  26. //取消callback
  27. @Override
  28. public void onDestroy() {
  29. System.out.println("onDestroy");
  30. super.onDestroy();
  31. handler.removeCallbacks(drawThread);
  32. }
  33. //当显示的时候 绑定callback 不显示时  取消callback
  34. @Override
  35. public void onVisibilityChanged(boolean visible) {
  36. System.out.println("onVisibilityChanged");
  37. mVisible = visible;
  38. if (visible) {
  39. //开始
  40. handler.postDelayed(drawThread, 50);
  41. } else {
  42. handler.removeCallbacks(drawThread);
  43. }
  44. }
  45. @Override
  46. public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
  47. System.out.println("onSurfaceChanged");
  48. // TODO Auto-generated method stub
  49. super.onSurfaceChanged(holder, format, width, height);
  50. }
  51. @Override
  52. public void onSurfaceCreated(SurfaceHolder holder) {
  53. System.out.println("onSurfaceCreated");
  54. super.onSurfaceCreated(holder);
  55. }
  56. //取消callback
  57. @Override
  58. public void onSurfaceDestroyed(SurfaceHolder holder) {
  59. System.out.println("onSurfaceDestoryed");
  60. // TODO Auto-generated method stub
  61. super.onSurfaceDestroyed(holder);
  62. handler.removeCallbacks(drawThread);
  63. }
  64. //处理点击事件 比如说 点击时 出现水波等
  65. @Override
  66. public void onTouchEvent(MotionEvent event) {
  67. System.out.println("onTouchEvent");
  68. // TODO Auto-generated method stub
  69. super.onTouchEvent(event);
  70. }
  71. //得到surfaceholder和canvas 并调用核心处理方法
  72. private void drawWallpaper() {
  73. SurfaceHolder holder = getSurfaceHolder();
  74. Canvas canvas = holder.lockCanvas();
  75. drawTime(canvas);
  76. holder.unlockCanvasAndPost(canvas);
  77. //循环执行
  78. handler.postDelayed(drawThread, 50);
  79. }
  80. //核心处理方法
  81. private void drawTime(Canvas canvas) {
  82. }
  83. }

复制代码

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. <application
  7. android:icon="@drawable/icon"
  8. android:label="@string/app_name">
  9. <service
  10. android:label="@string/app_name"
  11. android:name=".MyWallpaper"
  12. android:permission="android.permission.BIND_WALLPAPER">
  13. <intent-filter>
  14. <action android:name="android.service.wallpaper.WallpaperService" />
  15. </intent-filter>
  16. <meta-data android:name="android.service.wallpaper" android:resource="@xml/mylivewallpaper" />
  17. </service>
  18. </application>
  19. </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

android 动态壁纸开发的更多相关文章

  1. 【Android】用Cubism 2制作自己的Live2D——来制作动态壁纸吧!

    前言- Andorid SDK下载  baidu云 提取码:19jm 这次我们就来研究一下官方的例子之一的liveWallPaper,也就是开发Android的动态壁纸 先来看看这个例子运行的结果: ...

  2. android浪漫樱花凋零动态壁纸应用源码

    android浪漫樱花凋零动态壁纸应用源码,是从那个安卓教程网拿过来的,本项目是一套基于安卓的樱花动态壁纸项目源码,安装以后桌面没有图标,但是可以在修改壁纸-动态壁纸中找到.我的分辨率是480×854 ...

  3. Android 4.1 设置默认开机动态壁纸

    最新在对Android 4.1做一些定制性的工作,刚好遇到了设置第三方动态壁纸为默认启动壁纸的问题,遂做笔记如下. 需要修改的文件为: 找到SourceCode/framework/base/core ...

  4. Android应用开发提高系列(4)——Android动态加载(上)——加载未安装APK中的类

    前言 近期做换肤功能,由于换肤程度较高,受限于平台本身,实现起来较复杂,暂时搁置了该功能,但也积累了一些经验,将分两篇文章来写这部分的内容,欢迎交流! 关键字:Android动态加载 声明 欢迎转载, ...

  5. Android Wear(手表)开发 - 学习指南

    版权声明:欢迎自由转载-非商用-非衍生-保持署名.作者:Benhero,博客地址:http://www.cnblogs.com/benhero/ Android Wear开发 - 学习指南 http: ...

  6. Android之NDK开发(转)

    Android之NDK开发 一.NDK产生的背景 Android平台从诞生起,就已经支持C.C++开发.众所周知,Android的SDK基于Java实现,这意味着基于Android SDK进行开发的第 ...

  7. Android插件化开发

    客户端开发给人的印象往往是小巧,快速奔跑.但随着产品的发展,目前产生了大量的门户型客户端.功能模块持续集成,开发人员迅速增长.不同的开发小组开发不同的功能模块,甚至还有其他客户端集成进入.能做到功能模 ...

  8. (译)cocos2d-x跨android&ios平台开发入门教程

    免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播.同时,转载时不要移除本申明.如产生任何纠纷,均与本博客所有人.发表该翻译稿之人无任何关系.谢谢合作 ...

  9. Android之NDK开发

    转自:http://www.cnblogs.com/devinzhang/archive/2012/02/29/2373729.html 一.NDK产生的背景 Android平台从诞生起,就已经支持C ...

随机推荐

  1. 世界协调时间(UTC)与中国标准时间

    整个地球分为二十四时区,每个时区都有自己的本地时间.在国际无线电通信场合,为了统一起见,使用一个统一的时间,称为通用协调时(UTC, Universal Time Coordinated).UTC与格 ...

  2. 《开课》---创业学习--训练营直播第一课--HHR

    1,分享三点:敬畏心,学习过程,带着目标学习. 2,融资是个非常专业的技术活. 3,一定不要盲目自信,在资本市场,融资永远是个小概率事件. 4,学习过程:每周解锁学习资料,固定的时间来进行作业答疑. ...

  3. 创业学习--《预判行业机会》--B-2.预判模块---HHR计划--以太一堂

    一,<开始学习> 1,行业机会的判断,是可以通过不断地训练提高自己的判准的概率的,要科学思考创业. 2,创业者在行业机会上的三个问题: a. 对市场变化,敏感性太弱,没有洞察行业的意识. ...

  4. Bugku - CTF加密篇之聪明的小羊(一只小羊翻过了2个栅栏)

    聪明的小羊 一只小羊翻过了2个栅栏 KYsd3js2E{a2jda}  

  5. Java中的基本数据类型语法补充

    变量要先赋值后使用 不给变量赋值代表什么 不赋值就使用会怎样 (会报错) 计算并赋值运算符 作用是为了让代码更加简洁.比如 a = a + 10,可以简化为 a+=10 += -= *= /= %= ...

  6. win10 免安装版本的MySQL的下载安装和配置

    一.概述 网上找了好多,发现好多不是linux系统的就是与现在新版本有出入,自己做小项目亲手实践了一下,供大家借鉴. MySQL版本:mysql-5.7.17 下载方法: 1.MySQL官方网址htt ...

  7. git 修改分支 删除分支 新增分支

    一.修改分支名 1.本地分支重命名 git branch -m oldName newName 2.将重命名后的分支推送到远程 git push origin newName 3.重新更新所有分支 g ...

  8. 1014 Waiting in Line (30分)

    1014 Waiting in Line (30分)   Suppose a bank has N windows open for service. There is a yellow line i ...

  9. c++对象初始化(翁恺c++公开课[10])

    c++对象初始化 就是去调用构造函数来完成初始化操作: 构造函数有无参数的构造函数.有参数构造函数.默认构造函数(编译器给我们实现的)...(拷贝构造函数之后说) 注意:默认构造函数只有在我们自己没有 ...

  10. 关于hrf图的做法

    要拿matlab 的spm 包功能做 Model specification ,review and estimation specify1st level 第二张图是在建模以后,通过spm中的res ...