サンプルプログラム工場

AAKAKA Appで使われているプログラムのサンプルコードをそのまま公開!

サンプルプログラム工場 > android > [Android]ライブ壁紙(LiveWallPaper)のサンプル#tryLiveWallPaper00
Google Play AAKAKAxSOFTへ

[Android]ライブ壁紙(LiveWallPaper)のサンプル#tryLiveWallPaper00

実行ファイル(APK)やサンプル(zip)をダウンロードする
tryLiveWallPaper00の実行イメージ

●ライブ壁紙をサーフェイスビューを使って作る。
設定画面から壁紙の内容を変更できるようにする。
PreferenceActivityを使って簡単にデータを保存したりロードしたり

●AndroidManifest.xmlでメインのアクティビティでなく、ライブ壁紙のサービスを登録する。

●デバッグするには
 android.os.Debug.waitForDebugger();
が必要。だけど、実際にデバッガにつないでないときはコメントアウトするとかしないと固まったままになる。

●ライブ壁紙を選択する画面で設定ボタンを出すには
livewallpaper.xmlのsettingsActivityで起動するプリファレンスアクティビティを指定する必要がある。
AndroidManifest.xmlでActivityの登録する必要がある。

●検索した事
 engine onOffsetsChanged
 android ライブ壁紙 Activity
 android Live Wallpaper Preference
 preferenceActivity 値の取得

●開発環境
 Eclipse IDE バージョン: 4.2.1

ライブ壁紙はActivityは使わない、そのかわりにWallpaperServiceを使う

package com.example.trylivewallpaper00;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.Intent.ShortcutIconResource;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Bitmap.Config;
import android.graphics.Path;
import android.graphics.Rect;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.service.wallpaper.WallpaperService;
import android.service.wallpaper.WallpaperService.Engine;
import android.util.Log;
import android.view.SurfaceHolder;
import android.widget.Toast;

// ______________________________________________________________________________
/**
 * ライブ壁紙サービス(アクティビティは無いから、これがそれのかわり)
 *
 */
public class LiveWallpaper extends WallpaperService {

	// ______________________________________________________________________________
	@Override	// 最初に呼ばれる
	public void onCreate() {
		
			
		// デバッガを待つ
		android.os.Debug.waitForDebugger();
		
		super.onCreate();
	}
	
	// ______________________________________________________________________________	
	@Override	// 解放されるときに呼ばれる
	public void onDestroy() {
		
	}
	
	// ______________________________________________________________________________
	@Override	// ライブ壁紙を作り出すときに呼び出される
	public Engine onCreateEngine() {
		
		// TODO 自動生成されたメソッド・スタブ
		return new WallpaperEngine();
	}
	
	
	
	
	// ______________________________________________________________________________
	/**
	 * ライブ壁紙エンジン
	 *
	 */
	class WallpaperEngine extends Engine {

		private static final String TAG = "WallpaperEngine";
		private static final int FRAME_DRAW_INTERVAL = 100;
		
		// コンテキスト
		private Context mContext;
		// 表示状態
		private boolean	mVisible;
		// ペイント
		private Paint mPaintLine = new Paint();
		private Paint mPaintFill = new Paint();
		// 描画更新用
		private Handler mHandlerDrawFrame = new Handler();
		private Runnable mRunnableDrawFrame = new Runnable() {
			
			@Override
			public void run() {
				
				// 描画処理
				onDrawFrame();
				
				// またちょっと待ってから表示を開始する
				mHandlerDrawFrame.postDelayed(this, FRAME_DRAW_INTERVAL);
			}
		};
		
		// これに対して絵を描き込む
		private Bitmap mBitmapBackScreen;
		private Canvas mCanvasBackScreen;
		
		private static final int BACKSCREEN_WIDTH = 512;
		private static final int BACKSCREEN_HEIGHT = 512;
		
		// ______________________________________________________________________________
		/**
		 * コンストラクタ
		 */
		public WallpaperEngine() {
			
			this.mContext = LiveWallpaper.this.getApplicationContext();
			
			// 直線用ペインの初期化
			final Paint paintLine = this.mPaintLine;
			
			paintLine.setColor(0xffffffff);
			paintLine.setAntiAlias(true);
			paintLine.setStrokeWidth(5);
			paintLine.setStyle(Paint.Style.STROKE);
			paintLine.setStrokeCap(Paint.Cap.ROUND);
			
			// 塗りつぶしようペイントの初期化
			final Paint paintFill = this.mPaintFill;
			
			paintFill.setColor(0xffffffff);
			paintFill.setAntiAlias(true);
			paintFill.setStrokeWidth(5);
			paintFill.setStyle(Paint.Style.FILL);
			paintFill.setStrokeCap(Paint.Cap.ROUND);
			
			
			// 背景用のバックスクリーン
			this.mBitmapBackScreen = Bitmap.createBitmap(BACKSCREEN_WIDTH, BACKSCREEN_HEIGHT, Config.ARGB_8888);
			this.mCanvasBackScreen = new Canvas(this.mBitmapBackScreen);
			
			this.mCanvasBackScreen.drawColor(0xff000000);
			this.drawSampleShape(this.mCanvasBackScreen);
		}
		
		// ______________________________________________________________________________
		@Override	// エンジンが作られたときの呼ばれる
		public void onCreate(SurfaceHolder surfaceHolder) {
			// TODO 自動生成されたメソッド・スタブ
			super.onCreate(surfaceHolder);
		}

		// ______________________________________________________________________________
		@Override	// エンジンが破棄されるときに呼ばれる
		public void onDestroy() {
			super.onDestroy();
			
			// ハンドラーから除く
			this.mHandlerDrawFrame.removeCallbacks(this.mRunnableDrawFrame);
		}

		// 表示するオブジェクトのタイプ
		private int mObjectType = 0;
		
		// ______________________________________________________________________________
		@Override	// ホームスクリーンのアクティブ状態が変更された
		public void onVisibilityChanged(boolean visible) {
			
			this.mVisible = visible;
			
			// アクティブになった
			if (visible) {
				
				// 設定されているオブジェクトタイプを取り出す
				this.mObjectType = this.getObjectType();
				
				// 描画処理を再開
				this.mHandlerDrawFrame.postDelayed(this.mRunnableDrawFrame, FRAME_DRAW_INTERVAL);
				
			// 非アクティブになった
			} else {
				
				// 描画処理をコールバックから外す
				this.mHandlerDrawFrame.removeCallbacks(this.mRunnableDrawFrame);
			}
			
		}
		
		// ______________________________________________________________________________
		/**
		 * オブジェクトタイプを取り出す
		 * @return オブジェクトタイプ
		 */
		private int getObjectType() {
			
			// プリファレンスからオブジェクトタイプを取り出す
			SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this.mContext);
			return Integer.parseInt(pref.getString("object_type", "0"));
		}
		
		// ______________________________________________________________________________
		@Override	// サーフェイスが変更されたタイミングで呼ばれる
		public void onSurfaceChanged(SurfaceHolder holder, int format,
				int width, int height) {
			// TODO 自動生成されたメソッド・スタブ
			super.onSurfaceChanged(holder, format, width, height);
		}

		// ______________________________________________________________________________
		@Override	// サーフェイスが作られたタイミングで呼ばれる
		public void onSurfaceCreated(SurfaceHolder holder) {
			// TODO 自動生成されたメソッド・スタブ
			super.onSurfaceCreated(holder);
		}

		// ______________________________________________________________________________
		@Override	// サーフェイスが破棄されたときに呼ばれる
		public void onSurfaceDestroyed(SurfaceHolder holder) {
			// TODO 自動生成されたメソッド・スタブ
			super.onSurfaceDestroyed(holder);
		}

		
		private float mXOffset;
		private float mXOffsetStep;
		
		// ______________________________________________________________________________
		@Override	// 別のホームスクリーンへ移動した
		public void onOffsetsChanged(float xOffset, float yOffset,
				float xOffsetStep, float yOffsetStep, int xPixelOffset,
				int yPixelOffset) {
			
			Log.i(TAG + "onOffsetsChanged",
					"xOffset: " + xOffset + " yOffset: " + yOffset
					+ " xOffsetStep: " + xOffsetStep + " yOffsetStep: " + yOffsetStep
					+ " xPixelOffset: " + xPixelOffset + " yPixelOffset: " + yPixelOffset
					);
			
			// オフセットを取り出す
			this.mXOffset = xOffset;
			this.mXOffsetStep = xOffsetStep;
			
			//onDrawFrame();
			
			// TODO 自動生成されたメソッド・スタブ
			super.onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep,
					xPixelOffset, yPixelOffset);
		}
	
		// ______________________________________________________________________________
		/**
		 * ライブ壁紙の描画処理
		 */
		private void onDrawFrame() {
			
			// サーフェイスホルダーを取り出す
			final SurfaceHolder holder = this.getSurfaceHolder();
			
			Canvas canvas = null;
			
			try {
				
				// ホルダーからキャンバスを取り出す
				canvas = holder.lockCanvas();
				
				// ホルダーが取り出せた
				if (canvas != null) {
					
					// フレーム処理
					this.drawFrame(canvas);
				}
				
			} finally {
				
				// キャンバスがあるとき
				if (canvas != null) {
					
					//キャンバスの内容を反映させる
					holder.unlockCanvasAndPost(canvas);
				}
			}
		}
		
		// ______________________________________________________________________________
		/**
		 * キャンバスへの描画処理
		 * @param canvas
		 */
		private void drawFrame(Canvas canvas) {
			
			// カンバスのサイズ
			int width = canvas.getWidth();
			int height = canvas.getHeight();

			// オフセットは終わりは0.25-1.25になるので画面幅に合うように縮小する
			float bias = 1.0f / 1.25f;

			// バックスクリーン上でのオフセット
			float backScreenOffsetX = this.mXOffset * bias;
			
			// ホームスクリーンに当てる背面バッファの横幅
			float homeScreenWidth = BACKSCREEN_WIDTH / 5;	//←ホームスクリーンの数
			
			// 切り取り開始位置
			float clipStartX = (backScreenOffsetX * BACKSCREEN_WIDTH);
			
			// 背面のBitmapから画面への転送する位置を作る
			Rect src = new Rect((int)clipStartX, 0, (int)(clipStartX + homeScreenWidth), BACKSCREEN_HEIGHT);
			Rect dest = new Rect(0, 0, width, height);
			
			// 画面へBitmapを書き出す
			canvas.drawBitmap(this.mBitmapBackScreen, src, dest, null);
			
			// 真ん中のオブジェクトを表示する
			this.drawObject(width / 2, height / 2, canvas);

		}

		// ______________________________________________________________________________
		private void drawSampleShape(Canvas canvas) {
			
			// 塗りつぶし箇所1枚のサイズ
			int plateWidth = BACKSCREEN_WIDTH / 5;
			//Paint paint = new Paint();
			
			int colorTable[] = { 0xffffffff, 0xfff0f8ff, 0xff008b8b, 0xffffffe0, 0xffd8bfd8, };
			
			
			// 順番に塗りつぶし
			for (int i = 0; i < 5; i++) {
				this.mPaintFill.setColor(colorTable[i]);
				canvas.drawRect(i * plateWidth, 0, (i + 1) * plateWidth, BACKSCREEN_HEIGHT, this.mPaintFill);
				
			}
			
		}
		
		// ______________________________________________________________________________
		private float mObjectScale = 0.1f;
		private boolean mObjectScaleIncrement = true;	// スケールを増加させるか
		/**
		 * オブジェクトを表示する。ちょっとアニメーションするようにする
		 * @param x	表示するX座標
		 * @param y 表示するY座標
		 * @param canvas 描き込むカンバス
		 */
		private void drawObject(int x, int y, Canvas canvas) {

			// 適当に大きくなりすぎてるときは小さくするようにする
			if (2.0f < this.mObjectScale) {
				this.mObjectScaleIncrement = false;
			}
			// 小さくなり過ぎてるときは大きくするように
			if (this.mObjectScale < 0.1f) {
				this.mObjectScaleIncrement = true;
			}

			// 拡大する?
			if (this.mObjectScaleIncrement == true) {
				this.mObjectScale *= 1.05f;
			// 縮小する?
			} else {
				this.mObjectScale *= 0.95f;
			}
			
			// 拡大したりずらしたりしてから表示する
			this.mPaintLine.setColor(0xff000000);
			canvas.save();
			canvas.translate(x,  y);
			canvas.scale(this.mObjectScale, this.mObjectScale);
			
			// オブジェクトタイプに分けて描画処理を変える
			switch (this.mObjectType) {
			// 三角
			case 0:
				Path path = new Path();
				path.moveTo(0, -50);
				path.lineTo(50, 50);
				path.lineTo(-50, 50);
				path.lineTo(0, -50);
				canvas.drawPath(path, this.mPaintLine);
				
				break;
			// 四角
			case 1:
				canvas.drawRect(-50, -50, 50, 50, this.mPaintLine);
				break;
			// 円
			case 2:
				canvas.drawCircle(0, 0, 200, this.mPaintLine);
				break;
			}
			
			canvas.restore();
		}
		
	}
}

ライブ壁紙の設定用のPreferenceActivity

package com.example.trylivewallpaper00;

import android.content.Intent;
import android.content.Intent.ShortcutIconResource;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.view.Window;

public class PrefSettings extends PreferenceActivity {

	// ______________________________________________________________________________
	@Override	// 作られたときの呼ばれる
	protected void onCreate(Bundle savedInstanceState) {
		
		// ↓これはonCreateの前で呼ばないとエラー
		this.requestWindowFeature(Window.FEATURE_NO_TITLE);
		super.onCreate(savedInstanceState);
		
		// 設定プリファレンスを作る
		this.addPreferencesFromResource(R.xml.pref_settings);
	}
}

ライブ壁紙の設定をする(設定画面の有無とか)

<?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:settingsActivity="com.aakaka.ooapp012.PrefSettings" />

設定画面のPreferenceActivity

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <ListPreference android:entryValues="@array/object_value"
        android:entries="@array/object_type"
        android:title="オブジェクト"
        android:summary="画面に表示するオブジェクトを選択します。"
        android:key="object_type"/>
</PreferenceScreen>
サンプルプロジェクトをダウンロード

, , , , ,

[Android]有料版 無料版をプロジェクトで分けるサンプル#tryFreeOrPay00 [Android]JNI(ネイティブコード)のサンプル#tryJni00

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


*

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>