原文地址:http://blog.csdn.net/oldmtn/article/details/9177123
学习到的知识总结:
先贴上我的AndroidManifest.xml的内容。
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.testlivewallpaper"
- android:versionCode="1"
- android:versionName="1.0" >
-
- <uses-sdk
- android:minSdkVersion="8"
- android:targetSdkVersion="16" />
-
- <application
- android:allowBackup="true"
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name"
- android:theme="@style/AppTheme" >
- <service
- android:name="com.example.testlivewallpaper.Wallpaper"
- android:label="@string/service_name"
- 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/wallpaper" />
- </service>
- </application>
-
- </manifest>
1. 自己编写的动态壁纸相关的类必须从WallpaperService类派生。
2. 需要自己提供一个xml描述的wallpaper,该wallpaper作为你选择动态壁纸时候的预览图片。
我这里为:
- <meta-data
- android:name="android.service.wallpaper"
- android:resource="@xml/wallpaper" />
其中wallpaper内容为:
- <?xml version="1.0" encoding="utf-8"?>
- <wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
- android:author="@+string/author"
- android:description="@string/description"
- android:thumbnail="@drawable/cold" />
3.因为动态壁纸是一种服务,是给系统的壁纸管理程序调用的,所以可以不需要Activity。
当然你也可以添加一个Activity,然后给出列表,提供多个LiveWallpaper供用户选择。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
参考链接1:
地址:http://blog.csdn.net/blogercn/article/details/7407647
安卓从2.1开始支持动态墙纸编程,英文名字叫live wallpaper 。自己编写的动态壁纸必须从WallpaperService类派生,并且在重载其方法onCreateEngine里实现自己的动态效果。其代码如下,SimpleWallpaperEngine是我们基于Engine类派生的类:
public Engine onCreateEngine() {
return new SimpleWallpaperEngine();
}
上面retun返回的代码就是我们用Engine类的派生类创建的对象,其实现过程使用surfaceview更新。所以要学习动态墙纸编程,最好是已经熟练的掌握了surfaceview使用技巧。在Engine类里,有很多方法,我们需要重载以下三个方法,
1.创建壁纸
public void onCreate(SurfaceHoldersurfaceHolder){...}
2.释放壁纸
public void onDestroy(){...}
3.VisibilityChanged是用来设置当前动态壁纸可见时显示动画。当其不可见时,壁纸会停止运行,不显示动画,代码如下:
- @Override
- public void onVisibilityChanged(boolean visible) {
- canDraw = visible;
- if (visible) {
- drawDroid();
- } else {
- handler.removeCallbacks(drawRequest);
- }
- }
drawDroid是我写的一个简单的根据随机数画线的函数,代码如下:
- private void drawDroid() {
- final SurfaceHolder holder = getSurfaceHolder();
- Canvas canvas = null;
- try {
- canvas = holder.lockCanvas();
- if (canvas != null) {
- paint.setColor(Color.BLUE);
- paint.setStrokeWidth(10);
- paint.setStyle(Style.STROKE);
- nx = (int) (rand.nextFloat() * virtualWidth);
- ny = (int) (rand.nextFloat() * virtualHeight);
- m_path.lineTo(nx, ny);
- canvas.drawPath(m_path, paint);
- }
- } finally {
- if (canvas != null) {
- holder.unlockCanvasAndPost(canvas);
- }
- }
- handler.removeCallbacks(drawRequest);
- if (canDraw) {
- handler.postDelayed(drawRequest, 33);
- }
- }
由于动画是使用surfacewive实现的,所以我们也要重载surfacewive的方法:
1. 建立
onSurfaceCreated
2. 释放
onSurfaceDestroyed
3. 大小变化,横竖屏操作,与用户交互时修改
onSurfaceChanged
如果需要添加用户交互,需要重载
public voidonTouchEvent(MotionEvent event)
surfacewive使用线程更新屏幕,我们可以使用Runnable接口创建一个线程,把我们的绘画函数放进去,并把他添加到窗口handler回调里,代码如下:
- private final Runnable drawRequest = new Runnable() {
- @Override
- public void run() {
- try {
- Thread.sleep(1000);
- drawDroid();
- } catch (InterruptedException e) {
-
- e.printStackTrace();
- }
- }
- };
完整的代码如下“:
- package com.androidbook.simplelivewallpaper;
-
- import java.util.Random;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.graphics.Path;
- import android.graphics.Paint.Style;
- import android.os.Handler;
- import android.service.wallpaper.WallpaperService;
- import android.view.MotionEvent;
- import android.view.SurfaceHolder;
-
- public class SimpleDroidWallpaper extends WallpaperService {
-
- private final Handler handler = new Handler();
-
- @Override
- public Engine onCreateEngine() {
- return new SimpleWallpaperEngine();
- }
-
- class SimpleWallpaperEngine extends WallpaperService.Engine {
-
- boolean canDraw = true;
- private int virtualHeight;
- private int virtualWidth;
- Paint paint = new Paint();
- Path m_path = new Path();
- volatile int ox = 0, oy = 0, nx = 100, ny = 200;
- final Random rand = new Random();
-
- private final Runnable drawRequest = new Runnable() {
- @Override
- public void run() {
- try {
- Thread.sleep(1000);
- drawDroid();
- } catch (InterruptedException e) {
-
- e.printStackTrace();
- }
- }
- };
-
- public SimpleWallpaperEngine() {
- m_path.lineTo(ox, oy);
- }
-
- @Override
- public void onCreate(SurfaceHolder surfaceHolder) {
- super.onCreate(surfaceHolder);
-
-
- setTouchEventsEnabled(true);
- virtualHeight = getDesiredMinimumHeight();
- virtualWidth = getDesiredMinimumWidth();
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- handler.removeCallbacks(drawRequest);
- }
-
- @Override
- public void onVisibilityChanged(boolean visible) {
- canDraw = visible;
- if (visible) {
- drawDroid();
- } else {
- handler.removeCallbacks(drawRequest);
- }
- }
-
- @Override
- public void onOffsetsChanged(float xOffset, float yOffset,
- float xOffsetStep, float yOffsetStep, int xPixelOffset,
- int yPixelOffset) {
- super.onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep,
- xPixelOffset, yPixelOffset);
- }
-
- @Override
- public void onSurfaceCreated(SurfaceHolder holder) {
- super.onSurfaceCreated(holder);
- }
-
- @Override
- public void onSurfaceChanged(SurfaceHolder holder, int format,
- int width, int height) {
- super.onSurfaceChanged(holder, format, width, height);
-
- drawDroid();
- }
-
- @Override
- public void onSurfaceDestroyed(SurfaceHolder holder) {
- super.onSurfaceDestroyed(holder);
- canDraw = false;
- handler.removeCallbacks(drawRequest);
- }
-
- private void drawDroid() {
- final SurfaceHolder holder = getSurfaceHolder();
- Canvas canvas = null;
- try {
- canvas = holder.lockCanvas();
- if (canvas != null) {
- paint.setColor(Color.BLUE);
- paint.setStrokeWidth(10);
- paint.setStyle(Style.STROKE);
- nx = (int) (rand.nextFloat() * virtualWidth);
- ny = (int) (rand.nextFloat() * virtualHeight);
- m_path.lineTo(nx, ny);
- canvas.drawPath(m_path, paint);
- }
- } finally {
- if (canvas != null) {
- holder.unlockCanvasAndPost(canvas);
- }
- }
- handler.removeCallbacks(drawRequest);
- if (canDraw) {
- handler.postDelayed(drawRequest, 33);
- }
- }
-
- @Override
- public void onTouchEvent(MotionEvent event) {
-
- super.onTouchEvent(event);
- }
- }
- }
完整的XML文件如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:Android="http://schemas.android.com/apk/res/android"
package="com.androidbook.simplelivewallpaper"
android:versionCode="1"
android:versionName="1.0">
<application
android:icon="@drawable/icon"
android:label="@string/app_name"
android:debuggable="true">
<activity
android:name=".SimpleLiveWallpaperMenuActivity"
android:label="@string/app_name">
<intent-filter>
<action
android:name="android.intent.action.MAIN" />
<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:label="@string/wallpaper_name"
android:name="SimpleDroidWallpaper"
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/droid_wallpaper" />
</service>
</application>
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="8" />
<uses-feature
android:name="android.software.live_wallpaper" />
</manifest>
其实我们这里创建的墙纸不需要Activity类,只是一种服务,是被墙纸管理程序调用的,所以对于eclipse生成的工程,你可以去掉XML中有关Activity窗口的声明,同时资源文件里你也可以去掉layout\main.xml文件和源代码文件夹里的Activit文件。当然,我们的墙纸如果支持自定义设置,那你也是需要Activit,那时你需要定义一个Activit供墙纸设置程序调用,以修改自定义墙纸默认设置。需要注意的是,设置文件需要在我们在/res/文件夹中新建一个名为xml的文件夹,名为livewallpaper.xml,内容为如下:
- <?xml version="1.0" encoding="utf-8"?>
- <wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
- android:settingsActivity="ca.jvsh.livewallpaper.LiveWallpaperSettings"
- android:thumbnail="@drawable/icon"/>
然后把设置的值引入到你自己的墙纸类中调用。墙纸设置类一般会派生于PreferenceActivity,以在作用户操作后保存设置内容!