LiveWallpaper(1)基礎編



今回は、Android2.1(Eclair)から使用出来るLiveWallpaperの作成の仕方を紹介します。

LiveWallpaperの構造は、
・WallpaperService
・WallpaperService.Engine
から成り立っています。
WallpaperService.EngineはSurfaceHolderインターフェースを継承したクラスを保持しており、SurfaceViewの使用方法を踏まえていれば簡単に扱う事が出来ます。

TechBoosterで紹介した、SurfaceViewの記事は以下2つです。
是非本エントリを読む前に復習しておくとよいでしょう。
SurfaceViewで高速描画する(1)
SurfaceViewで高速描画する(2) ゲームプログラミングの基本

今回から二回に分けて、LiveWallpaperを取り上げたいと思います。

以下続きにて、詳細な使用方法を紹介していきます。

LiveWallpaperを作成する為に必要なことは、以下の4点。

  1. WallpaperServiceの作成
  2. WallpaperService.Engineの作成
  3. Engineにて取得できるSurfaceHolderを使用し描画部分を作成
  4. 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の扱いに触れていきます。

One Comment