facebook twitter hatena line google mixi email

Android/ライブ壁紙作成/サンプルソース

提供: 初心者エンジニアの簡易メモ
移動: 案内検索

画面スライドに合わせて、画像が切り替わるライブ壁紙サンプル

  • AndroidLiveWallService.java
package info.nonip.AndroidLiveWallService;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Handler;
import android.service.wallpaper.WallpaperService;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.util.Log;
public class AndroidLiveWallServiceActivity extends WallpaperService {
  /** Called when the activity is first created. */
  /** 描画用のハンドラを用意 **/
  private final Handler mHandler = new Handler();
  @Override
  public Engine onCreateEngine() {
    // 描画用の自作Engineクラスを返す
    return new LiveEngine();
  }
  /** 描画を行うEngineクラス **/
  public class LiveEngine extends Engine {
    // ここに描画用の処理を記述していく
    /** イメージ **/
    private Bitmap image;
    /** x座標 **/
    private int x = 0;
    /** y座標 **/
    private int y = 0;
    private int imageSelect = 1;
    /** 描画用のRunnableオブジェクト **/
    private final Runnable drawRunnable = new Runnable(){
      public void run(){
        // 描画メソッドを呼び出す
        drawFrame();
      }
    };
    /** 表示状態フラグ **/
    private boolean visible;
    /** コンストラクタ **/
    public LiveEngine(){
      image = BitmapFactory.decodeResource(getResources(), R.drawable.image2);
    }
    /** Engine生成時に呼び出される **/
    @Override
    public void onCreate(SurfaceHolder surfaceHolder){
      super.onCreate(surfaceHolder);
      // タッチイベントを有効
      setTouchEventsEnabled(true); 
    }
    /** Engine破棄時に呼び出される **/
    @Override
    public void onDestroy(){
      super.onDestroy();
      mHandler.removeCallbacks(drawRunnable);
      if (image != null) {
       // Bitmapデータの解放
       image.recycle();
       image = null;
     }
    }
    /** 表示状態変更時に呼び出される **/
    @Override
    public void onVisibilityChanged(boolean visible){
      this.visible = visible;
      if(visible){
        drawFrame();
      }else{
        mHandler.removeCallbacks(drawRunnable);
      }
    }
    /** サーフェイス生成時に呼び出される **/
    @Override
    public void onSurfaceCreated(SurfaceHolder surfaceHolder){
      super.onSurfaceCreated(surfaceHolder);
      Log.i("tag1", "onSurfaceCreated");
    }
    /** サーフェイス変更時に呼び出される **/
    @Override
    public void onSurfaceChanged(SurfaceHolder holder,int format, int width , int height){
      super.onSurfaceChanged(holder, format, width, height);
      drawFrame();
      Log.i("tag1", "onSurfaceChanged");
    }
    /** サーフェイス破棄時に呼び出される **/
    @Override
    public void onSurfaceDestroyed(SurfaceHolder holder){
      super.onSurfaceCreated(holder);
      visible = false;
      mHandler .removeCallbacks(drawRunnable);
      Log.i("tag1", "onSurfaceDestroyed");
      if (image != null) {
       // Bitmapデータの解放
       image.recycle();
       image = null;
     }
    }
    /** オフセット変更時に呼び出される **/
    @Override
    public void onOffsetsChanged(float xOffset, float yOffset, float xStep, float yStep, int xPixels, int yPixels){
      drawFrame();
      //Log.i("tag1", "xOffset=" + xOffset + " xStep=" + xStep + " xPixels=" + xPixels);
      imageSelect = (int)Math.floor(xOffset / xStep);
    }
    /** キャンバスで描画を行う **/
    private void drawFrame(){
      final SurfaceHolder holder = getSurfaceHolder();
      Canvas c = null;
      try{
        // キャンバスをロック
        c = holder.lockCanvas();
        if(c != null){
          // 描画
          c.drawColor(Color.GREEN);
          _changeImage();
          c.drawBitmap(image, x, y, null);
        }
        x = 0;
        y = 0;
      }finally{
        // Canvas アンロック
        if(c != null){
          holder.unlockCanvasAndPost(c);
        }
      }
      // 次の描画をセット
      mHandler.removeCallbacks(drawRunnable);
      if(visible){
        mHandler.postDelayed(drawRunnable, 60);
      }
    }
    private void _changeImage() {
      if (imageSelect == 0) {
        image = BitmapFactory.decodeResource(getResources(), R.drawable.image0);
      } else if (imageSelect == 1) {
        image = BitmapFactory.decodeResource(getResources(), R.drawable.image1);
      } else if (imageSelect == 2) {
        image = BitmapFactory.decodeResource(getResources(), R.drawable.image2);
      } else if (imageSelect == 3) {
        image = BitmapFactory.decodeResource(getResources(), R.drawable.image3);
      } else if (imageSelect == 4) {
        image = BitmapFactory.decodeResource(getResources(), R.drawable.image4);
      }
      //Log.i("tag1", "imageSelect=" + imageSelect);
    }
    /** タッチイベント **/
    @Override
    public void onTouchEvent(MotionEvent event){
      // 画面をタッチすると画像を切り替える
      switch(event.getAction()){
      case MotionEvent.ACTION_UP:
        /*
        if(flag){
          image = BitmapFactory.decodeResource(getResources(), R.drawable.image);
          flag = false;
        }else{
          image = BitmapFactory.decodeResource(getResources(), R.drawable.image2);
          flag = true;
        }
        */
      }
    }
  }
}
  • res/xml/wallpaper.xml
<?xml version="1.0" encoding="utf-8"?>
<wallpaper
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:thumbnail="@drawable/ic_launcher"
    android:description="@string/app_name"
    android:description="@string/description"
/>
  • res/value/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">AndroidLiveWallService</string>
    <string name="description">AndroidLiveWallServiceDetail</string>
</resources>
  • AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="info.nonip.AndroidLiveWallService"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk android:minSdkVersion="7" />
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <service
            android:name=".AndroidLiveWallServiceActivity"
            android:label="@string/app_name"
            android:permission="android.permission.BIND_WALLPAPER">
            <intent-filter>
                <action android:name="android.service.wallpaper.WallpaperService"></action>
            </intent-filter>
            <meta-data android:name="android.service.wallpaper" android:resource="@xml/wallpaper"></meta-data>
        </service>
    </application>
    <!-- GooglePlayにライブ壁紙であることを知らせる -->
    <uses-feature android:name="android.software.live_wallpaper" />
</manifest>


画像を追加(drawable-mdpiディレクトリに画像を追加

  • res/drawable-mdpi/ic_launcher.png
  • res/drawable-mdpi/image0.png
  • res/drawable-mdpi/image1.png
  • res/drawable-mdpi/image2.png
  • res/drawable-mdpi/image3.png
  • res/drawable-mdpi/image4.png

画像が置き換わらない場合

bin/res/をいったん消すか。プロジェクト → クリーンでキャッシュ削除可能

タッチイベントが取得できないとき

以下をonCreateメソッド内に追加する

setTouchEventsEnabled(true);

onOffsetsChangedサンプル数値

左から右へスライドしたときの数値サンプル

  • au is04 regza(全5スクリーン
onOffsetsChanged xOffset=0.0 xStep=0.25 xPixels=0
onOffsetsChanged xOffset=0.25 xStep=0.25 xPixels=-120
onOffsetsChanged xOffset=0.5 xStep=0.25 xPixels=-240
onOffsetsChanged xOffset=0.75 xStep=0.25 xPixels=-360
onOffsetsChanged xOffset=1.0 xStep=0.25 xPixels=-480
  • galaxys2(全4スクリーン
onOffsetsChanged xOffset=0.0 xStep=-1.0 xPixels=0
onOffsetsChanged xOffset=0.33333337 xStep=-1.0 xPixels=-160
onOffsetsChanged xOffset=0.6666667 xStep=-1.0 xPixels=-320
onOffsetsChanged xOffset=1.0 xStep=-1.0 xPixels=-480
  • docomo XPERIA SO-03C(全5スクリーン
onOffsetsChanged xOffset=0.0 xStep=-1.0 xPixels=0
onOffsetsChanged xOffset=0.2499912 xStep=-1.0 xPixels=-120
onOffsetsChanged xOffset=0.4999884 xStep=-1.0 xPixels=-240
onOffsetsChanged xOffset=0.7499875 xStep=-1.0 xPixels=-360
onOffsetsChanged xOffset=0.9999922 xStep=-1.0 xPixels=-480
  • docomo MEDIAS N-01D palletui(全9スクリーン
onOffsetsChanged xOffset=0.0 xStep=0.125 xPixels=0
onOffsetsChanged xOffset=0.125 xStep=0.125 xPixels=-60
onOffsetsChanged xOffset=0.25 xStep=0.125 xPixels=-120
onOffsetsChanged xOffset=0.375 xStep=0.125 xPixels=-180
onOffsetsChanged xOffset=0.5 xStep=0.125 xPixels=-240
onOffsetsChanged xOffset=0.625 xStep=0.125 xPixels=-300
onOffsetsChanged xOffset=0.75 xStep=0.125 xPixels=-360
onOffsetsChanged xOffset=0.875 xStep=0.125 xPixels=-420
onOffsetsChanged xOffset=1.0 xStep=0.125 xPixels=-480
  • emyulater(全3スクリーン
onOffsetsChanged xOffset=0.0 xStep=0.5 xPixels=0
onOffsetsChanged xOffset=0.5 xStep=0.5 xPixels=-240
onOffsetsChanged xOffset=1.0 xStep=0.5 xPixels=-480

上記数字は少しでもスライドすると変動する

その他参考値 http://sugarspotweblog.blogspot.jp/2011/07/androidlivewallpaper.html

参考

http://blog.global-eng.co.jp/android/2011/07/01/%E3%83%A9%E3%82%A4%E3%83%96%E5%A3%81%E7%B4%99%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9/