安卓动态壁纸开发

一般的壁纸设定,只需要在获取壁纸权限后,只需要getWallPagerManager对象来设定壁纸(静态)

与安卓应用的开发不同,动态壁纸的开发不需要传统的布局文件,也不要活动(activity)来管理,也是一种服务(WallPagerService)来维护着,里面自带有一个SurfaceHolder来进行图形的实时渲染,来达到壁纸动态的效果。

 动态壁纸的设定可分为如下三步:

  1 。创建一个 WallpagerService的子类

  2。 创建一个Engine的子类,以后所有的绘制代码都写在这个类中。

  3。 在wallpagerservice子类中的oncreate方法中,返回一个engine(我们自己创建的enginner子类)。

     4。 在res目录下 创建一个xml文件夹,在其中编写一个xml文件,内容如下:

  

  <?xml version="1.0" encoding="utf-8"?>
  <wallpaper xmlns:android="http://schemas.android.com/apk/res/android" android:thumbnail="@drawable/icon"/> 
  <!-- 红色表示 在选择动态壁纸时 显示的缩略图-->

  5。 在清单文件mainifest.xml 中进行service的配置,并在service节点内部添加绑定壁纸的权限,在节点下添加 意图过滤器和元数据,如下:

    

	<application
		android:icon="@drawable/icon"
		android:label="@string/app_name">
		<!-- 配置实时壁纸Service -->
		<service android:label="@string/app_name"
			android:name=".LiveWallpaper"
			android:permission="android.permission.BIND_WALLPAPER">
			<!-- 为实时壁纸配置intent-filter -->
			<intent-filter>
				<action	android:name="android.service.wallpaper.WallpaperService" />
			</intent-filter>
			<!-- 为实时壁纸配置meta-data -->
			<meta-data android:name="android.service.wallpaper"
				android:resource="@xml/livewallpaper" />
		</service>
	</application>
</manifest>

既然所有的核心代码都写在了Engine的子类中,所以必须的明白它的方法在什么时候回调用,下面给出我的一个测试DEMO

原理是: 背景是一个图通的bitmap 但是当手机在屏幕上面按下时,就会在按下的位置绘制出一个笑脸。
  

package com.xtu.wallpaper;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Handler;
import android.service.wallpaper.WallpaperService;
import android.view.MotionEvent;
import android.view.SurfaceHolder;

public class CuteWallPaper extends WallpaperService {

private Bitmap bg;
private Bitmap figer;
// 动态墙纸 需要提供一个渲染引擎
@Override
public Engine onCreateEngine() {
bg = BitmapFactory.decodeResource(getResources(), R.drawable.register);
figer = BitmapFactory.decodeResource(getResources(), R.drawable.one);
return new CuteEngine();
}

class CuteEngine extends Engine {

private Handler mHandler = new Handler();
private Paint paint = new Paint();
private float positionX = 10, positionY = 10;

private Runnable mRunnable = new Runnable() {
@Override
public void run() {
onPaint();
}
};

// 创建引擎对象,这个方法 只会调用一次
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
paint.setColor(Color.RED);
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
setTouchEventsEnabled(true);
}

@Override
public void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(mRunnable);
}

@Override
public void onOffsetsChanged(float xOffset, float yOffset,
float xOffsetStep, float yOffsetStep, int xPixelOffset,
int yPixelOffset) {
super.onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep,
xPixelOffset, yPixelOffset);
onPaint();
}

 

 //当壁纸的可见状态发生变化时,调用

@Override
public void onVisibilityChanged(boolean visible) {
super.onVisibilityChanged(visible);
if (visible) {
// 当壁纸为可见状态
onPaint();
} else {
// 当壁纸为不可见的时候
mHandler.removeCallbacks(mRunnable);
}
}

// 当手指接触到引擎时 调用
@Override
public void onTouchEvent(MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_DOWN){
positionX = event.getX();
positionY = event.getY();
}
super.onTouchEvent(event);
}

//画笔绘制的方法,绘制在surfaceholder上面, 注意surfaceholder.lockCanvas() 和 surfaceholder.unlockandposd()的调用(用try-catch包裹着) surfaceholder在绘制时候,由于锁定了,此时surfaceview的双//缓冲是不能用的。

private void onPaint() {
SurfaceHolder surfaceHolder = getSurfaceHolder();
Canvas canvas = null;
try {
canvas = surfaceHolder.lockCanvas();
canvas.drawBitmap(bg, new Matrix(), paint);
canvas.drawBitmap(figer, positionX, positionY, paint);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (canvas != null) {
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
mHandler.postDelayed(mRunnable, 80);
}

}
}




  
posted on 2016-03-09 21:30  2013551627  阅读(1242)  评论(0编辑  收藏  举报