LiveWallPaper 动态壁纸是从Android2.1就开始带有的一个新的特性。它让我们能够将本来毫无生气的静态的手机屏幕背景替换成 从 随着音乐的活力和脉动而跳跃的声线 到 手指抚过能激起阵阵涟漪的静默的池塘。显示当前天气情况、展示幻灯片甚至是表现烟火特效也只是android百变动态壁纸的冰山一角。
现在让我们揭开它神秘的面纱。看看这些神奇的应用是如何做到的。
下面我们就开始完成一个动态壁纸项目:
1.首先创建一个新的android项目:
注意:Activity的名字可以先空着。关闭Activity项左边的复选框。
2. 创建项目后,我们需要为新项目中的androidmanifest.xml文件中添加新的属性。
它看起来就像下面这样:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="classroom.studio"
android:versionCode="1"
android:versionName="1.0">
<application android:label="@string/app_name">
<service android:name=".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>
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="8" />
</manifest>
注释:
<service> 定义了一个,将运行在背景上并且对事件有响应的Android服务。android:permission="android.permission.BIND_WALLPAPER" 意思是任何程 序调用我们的服务都需要有一个指定的权限。Android的Home程序已经具备了该权限,所以它会工作得很好。
< intent-filter >这个标签告诉Android它是个什么样的服务。
< meta-data>标签让它知道在哪能找到关于wallpaper的额外信息。android:resource被设为"@xml/wallpaper"(名字任意,但得对应上),这个值最好设置在res/xml/wallpaper.xml 文件。以下便是该xml文件的内容。
<?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/thumbnail"
/>
这个 wallpaper的metadata(元数据)指定了这个程序的作者的名字、该程序的介绍以及一个缩略图。所有这些分别存储在string.xml以及drawable文件中。他们将在使用者选择该使用哪个动态壁纸应用的时候以列表的形式显示出来。
因此我们还需要创建一个string.xml文件。如下所示
<resources>
<string name="app_name">自转的立方体</string>
<string name="service_name">CS_livewallpaper</string>
<string name="author">ClassroomStudio 教室工作室</string>
<string name="description">来自CS工作室的动态壁纸
</string>
</resources>
我们可以AVD中看到这个文件实际所起的作用。如下图三所示
同时我们也需要删除掉一个Layout中的文件 res/layout/main.xml。因为我们不会在这个程序中使用它。
3:实现Service类,控制动态壁纸的内容显示。
其实动态壁纸就是一个Service服务,在后台不断运行渲染,来实现桌面内容的变化(这样是为什么动态壁纸会很耗电的原因)。
LiveWallpaper将由Service的子类WallpaperService 来处理。关键点是要实现Engine类。
核心代码是:
package classroom.studio;
import android.service.wallpaper.WallpaperService;
public class Wallpaper extends WallpaperService {
@Override
public Engine onCreateEngine() {
return new MyEngine();
}
private class MyEngine extends Engine {
// 从这里实现引擎。。。
}
}
4.实现Engine类,构建绘图引擎。
因为这个MyEngine一定要是Wallpaper里的一个类,所以在类的封闭的大括号中声明了它。MyEngine 扩展了由Android提供的Engine类。以下的代码是带有所有要用到的方法的MyEngine 纲要。
1 private class MyEngine extends Engine {
2 @Override
3 public void onCreate(final SurfaceHolder holder) {
4 super.onCreate(holder);
5 }
6 @Override
7 public void onDestroy() {
8 super.onDestroy();
9 };
10 @Override
11 public void onSurfaceCreated(final SurfaceHolder holder) {
12 super.onSurfaceCreated(holder);
13 }
14 @Override
15 public void onSurfaceDestroyed(final SurfaceHolder holder) {
16 super.onSurfaceDestroyed(holder);
17 }@Override
18 public void onSurfaceChanged(final SurfaceHolder holder,
19 final int format, final int width, final int height) {
20 super.onSurfaceChanged(holder, format, width, height);
21 }
22 @Override
23 public void onVisibilityChanged(final boolean visible) {
24 super.onVisibilityChanged(visible);
25 }
26 @Override
27 public void onOffsetsChanged(final float xOffset,
28 final float yOffset, final float xOffsetStep,
29 final float yOffsetStep, final int xPixelOffset,
30 final int yPixelOffset) {
31 super.onOffsetsChanged(xOffset, yOffset, xOffsetStep,
32 yOffsetStep, xPixelOffset, yPixelOffset);
33 }
34 }
需要注意的是每个方法应该总是调用其基类方法。
在Engine的整个生命周期中,Android会在特定的命令下调用这些方法。下面就是整个句子。
onCreate
onSurfaceCreated
onSurfaceChanged (1+ calls in any order)
onOffsetsChanged (0+ calls in any order)
onVisibilityChanged (0+ calls in any order)
onSurfaceDestroyed
onDestroy
以上摘录自:http://www.cnblogs.com/ClassroomStudio/archive/2010/08/13/CS_livewallpaper.html
5.注意事项:
1)不要用Thread,应直接使用Handler与Runnable接口对象组合运行。
使用Thread会产生一些莫名其妙的问题,比如:壁纸预览时报错;壁纸设置时报错;壁纸设置后闪一下即消失变为默认静态壁纸;壁纸设置后停止运行但切换到待机状态再切回还是能运行的。
2)可以指定一个Activity为动态壁纸设置界面
需在壁纸设置文件中这样指定:
<?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/mani1" //该动态壁纸的图片
android:settingsActivity="com.skyd.mantrawheel.Main" //指明setting的activity
/>
并且该Activity必须在AndroidManifest.xml中这样注册:
<activity android:name=".Main" android:label="@string/app_name" android:exported="true"></activity>
注意:指定Activity应该放在 <meta-data android:name="android.service.wallpaper" android:resource="@xml/wallpaper" />中的"@xml/wallpaper"文件内指明。
3)最好指定uses-feature标记
在AndroidManifest.xml中指定如下代码会使程序在市场中对不支持动态壁纸功能的用户隐藏:
<uses-feature android:name="android.software.live_wallpaper" />
4)设置接收onTouchEvent事件时要指定setTouchEventsEnable(true),默认情况是不接收该事件的。
同时注意必须在onCreate(SurfaceHolder surfaceHolder)中指定,如果你放在onSurfaceCreated(SurfaceHolder holder)中指定,你会很郁闷地发现动态壁纸在2.1 版本的系统中可以运行,2.2版本却报错。