今回は、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の扱いに触れていきます。