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しましょう。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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() を呼び出しています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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

1
2
3
4
5
6
7
8
9
10
11
12
13
<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

1
2
3
<?xml version="1.0" encoding="utf-8"?>
/>

次回には、Engineにおける紹介できなかったMethodの扱いに触れていきます。

One Comment