LiveWallpaper(1)基礎編

今回は、Android2.1(Eclair)から使用出来るLiveWallpaperの作成の仕方を紹介します。
LiveWallpaperの構造は、
・WallpaperService
・WallpaperService.Engine
から成り立っています。
WallpaperService.EngineはSurfaceHolderインターフェースを継承したクラスを保持しており、SurfaceViewの使用方法を踏まえていれば簡単に扱う事が出来ます。
TechBoosterで紹介した、SurfaceViewの記事は以下2つです。
是非本エントリを読む前に復習しておくとよいでしょう。
・SurfaceViewで高速描画する(1)
・SurfaceViewで高速描画する(2) ゲームプログラミングの基本
今回から二回に分けて、LiveWallpaperを取り上げたいと思います。
以下続きにて、詳細な使用方法を紹介していきます。
LiveWallpaperを作成する為に必要なことは、以下の4点。
- WallpaperServiceの作成
- WallpaperService.Engineの作成
- Engineにて取得できるSurfaceHolderを使用し描画部分を作成
- AndroidManifestファイルの編集
Touchした座標に「TechBooster」と文字が表示されるサンプルを使用しながら、これらについて触れていきます。

1.WallpaperServiceの作成
LiveWallpaperを作成する場合は、プロジェクトを作成する際にActivityの作成のチェックをしないでおきます。(後で図入れ)
パッケージファイル以下に、新規にjavaファイルを作成し、WallpaperServiceクラスを継承したクラスを作成します。
WallpaperServiceクラスには、WallpaperService.Engineの実体を返す抽象MethodであるonCreateEngine()が在りますので、忘れずにOverrideしましょう。
public class LiveWallpaperSample extends WallpaperService {
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public Engine onCreateEngine() {
// Engineを継承したクラスのオブジェクトを返す
return new MyEngine();
}
.......省略
2.WallpaperService.Engineの作成
WallpaperService.Engineクラスを継承したクラスを作成します。
前述の通り、SurfaceHolderを継承したクラスを使用するため、SurfaceViewでのSurfaceHolder使用の際と同様にCallbackMethodである下記3つのMethodをOverrideします。
・onSurfaceChanged()
・onSurfaceCreated()
・onSurfaceDestroyed()
class MyEngine extends Engine{
.....省略
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
}
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
super.onSurfaceCreated(holder);
doDraw(0,0);
}
@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
}
Sampleでは特にSurfaceView変更時の処理を記述しませんでしたので、SurfaceCreate時に描画関数を呼んでいるのみになります。
3.Engineにて取得できるSurfaceHolderを使用し描画部分を作成
SurfaceHolderを取得しCanvasへの書き込みを行います。
WallpaperService.Engine#getSurfaceHolder() を用いることで、SurfaceHolderを取得することが出来ます。
以下は、 onTouchEvent() にて取得した座標に TechBooster と書き込みを行うサンプルです。
onTouchEvent()が有効になるように、onCreate()内でWallpaperService.Engine#setTouchEventsEnabled() を呼び出しています。
class MyEngine extends Engine{
....省略
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
// デフォルトではtouchEventで画面のTouchを受け取れない。
//
setTouchEventsEnabled(true);
}
@Override
public void onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_MOVE || event.getAction() == MotionEvent.ACTION_DOWN) {
doDraw((int)event.getX(),(int)event.getY());
}
super.onTouchEvent(event);
}
public void doDraw(int posX, int posY){
Canvas canvas = getSurfaceHolder().lockCanvas();
Paint paint = new Paint();
canvas.drawColor(Color.BLACK);
paint.setTextSize(24);
paint.setColor(Color.WHITE);
canvas.drawText("TechBooster", posX, posY,paint);
getSurfaceHolder().unlockCanvasAndPost(canvas);
}
4.AndroidManifestファイルの編集
最後に、AndroidManifestへのApplicationの構成の記述です。
以下内容を忘れずに踏まえる必要があります。
・uses-feature要素に android:name=”android.software.live_wallpaper”
・serviceとして WallpaperService を登録
・android:permission=”android.permission.BIND_WALLPAPER”
・meta-data タグに 設定用のリソースを指定する(今回は空)
AndroidManifest.xml
<uses-feature android:name="android.software.live_wallpaper" /> <uses-sdk android:minSdkVersion="7" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <service android:label="TcbLiveWallpaperSample" android:name=".LiveWallpaperSample" 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/res_sample" /> </service> </application>
res_sample.xml
<?xml version="1.0" encoding="utf-8"?> <wallpaper xmlns:android="http://schemas.android.com/apk/res/android" />
次回には、Engineにおける紹介できなかったMethodの扱いに触れていきます。