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代码
- <?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】用Cubism 2制作自己的Live2D——来制作动态壁纸吧!
		
前言- Andorid SDK下载 baidu云 提取码:19jm 这次我们就来研究一下官方的例子之一的liveWallPaper,也就是开发Android的动态壁纸 先来看看这个例子运行的结果: ...
 - android浪漫樱花凋零动态壁纸应用源码
		
android浪漫樱花凋零动态壁纸应用源码,是从那个安卓教程网拿过来的,本项目是一套基于安卓的樱花动态壁纸项目源码,安装以后桌面没有图标,但是可以在修改壁纸-动态壁纸中找到.我的分辨率是480×854 ...
 - Android 4.1 设置默认开机动态壁纸
		
最新在对Android 4.1做一些定制性的工作,刚好遇到了设置第三方动态壁纸为默认启动壁纸的问题,遂做笔记如下. 需要修改的文件为: 找到SourceCode/framework/base/core ...
 - Android应用开发提高系列(4)——Android动态加载(上)——加载未安装APK中的类
		
前言 近期做换肤功能,由于换肤程度较高,受限于平台本身,实现起来较复杂,暂时搁置了该功能,但也积累了一些经验,将分两篇文章来写这部分的内容,欢迎交流! 关键字:Android动态加载 声明 欢迎转载, ...
 - Android Wear(手表)开发 - 学习指南
		
版权声明:欢迎自由转载-非商用-非衍生-保持署名.作者:Benhero,博客地址:http://www.cnblogs.com/benhero/ Android Wear开发 - 学习指南 http: ...
 - Android之NDK开发(转)
		
Android之NDK开发 一.NDK产生的背景 Android平台从诞生起,就已经支持C.C++开发.众所周知,Android的SDK基于Java实现,这意味着基于Android SDK进行开发的第 ...
 - Android插件化开发
		
客户端开发给人的印象往往是小巧,快速奔跑.但随着产品的发展,目前产生了大量的门户型客户端.功能模块持续集成,开发人员迅速增长.不同的开发小组开发不同的功能模块,甚至还有其他客户端集成进入.能做到功能模 ...
 - (译)cocos2d-x跨android&ios平台开发入门教程
		
免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播.同时,转载时不要移除本申明.如产生任何纠纷,均与本博客所有人.发表该翻译稿之人无任何关系.谢谢合作 ...
 - Android之NDK开发
		
转自:http://www.cnblogs.com/devinzhang/archive/2012/02/29/2373729.html 一.NDK产生的背景 Android平台从诞生起,就已经支持C ...
 
随机推荐
- python opencv:色彩空间
			
RGB色彩空间 常见的色彩空间 色彩空间的转换 cv2.cvtColor(image, 转换选项) 常见的两个颜色转换 HSV与RGB YUV与RGB inRange方法 函数参数: 第一个参数:是原 ...
 - Redis注意点记录
			
场景:1主2从 1.不使用哨兵模式,则当主机宕机后,从机并不会自动切换到Master状态,仍旧是Slave,若主机重新恢复,则从机进行自动连接 2.使用哨兵模式后,主机宕机,从机会根据分配的权值在从机 ...
 - 【PAT甲级】1068 Find More Coins (30 分)(背包/DP)
			
题意: 输入两个正整数N和M(N<=10000,M<=10000),接着输入N个正整数.输出最小的序列满足序列和为M. AAAAAccepted code: #define HAVE_ST ...
 - I/O-<File区别>
			
FileInputStream FileOutputStream ObjectInputStream ObjectOutputStream 传的是对象 需要新建一 ...
 - Nginx Rewrite域名及资源重定向!(重点)
			
第一步:搭建Nginx服务 第二步:修改主配置文件 [root@ns2 ~]# vim /usr/local/nginx/conf/nginx.conf user nginx nginx; work ...
 - CSS背景图片设置
			
*{ margin:0px; padding:0px; list-style: none; text-decoration: none; font-family: Arial,'Microsoft Y ...
 - node js 判断数组中是否包含某个值
			
判断数组中是否包含某个值这里有四种方法.用的测试数据: let arr=["a","b","c"]; let arr2={"a&q ...
 - K8S-OVS使用Openvswitch为提供SDN功能支持单租户模式和多租户模式
			
k8s-ovs ============================== 最近在寻求一些工作机会,如果有kubernetes相关研发招聘的朋友,欢迎随时联系我.我的个人简历可以通过百度网盘:htt ...
 - android的ListAdapter简单用法
			
ListAdapter是一个整个Activity有且仅有一个ListView控件的Activity 使用步骤:1. 创建MyListViewAdapter(类名可以自定义) extends ListA ...
 - c++对象初始化(翁恺c++公开课[10])
			
c++对象初始化 就是去调用构造函数来完成初始化操作: 构造函数有无参数的构造函数.有参数构造函数.默认构造函数(编译器给我们实现的)...(拷贝构造函数之后说) 注意:默认构造函数只有在我们自己没有 ...