Warning: include(/home/users/2/lolipop.jp-a-virtual/web/dhmo/dhmo/wp-content/advanced-cache.php): failed to open stream: No such file or directory in /home/users/2/lolipop.jp-a-virtual/web/dhmo/dhmo/wp-settings.php on line 74

Warning: include(/home/users/2/lolipop.jp-a-virtual/web/dhmo/dhmo/wp-content/advanced-cache.php): failed to open stream: No such file or directory in /home/users/2/lolipop.jp-a-virtual/web/dhmo/dhmo/wp-settings.php on line 74

Warning: include(): Failed opening '/home/users/2/lolipop.jp-a-virtual/web/dhmo/dhmo/wp-content/advanced-cache.php' for inclusion (include_path='.:/usr/local/php/5.4/lib/php') in /home/users/2/lolipop.jp-a-virtual/web/dhmo/dhmo/wp-settings.php on line 74
便利な壁紙作ってみた~ライブ壁紙作り方~① – Androidアプリつくったった

便利な壁紙作ってみた~ライブ壁紙作り方~①

新しい壁紙つくってみた

今回はこのアプリとそのソースを2回に渡って徹底公開したいと思います。

新しい壁紙つくってみた

 

 

 

 

 

 

 

 

 

 

レシピは
・絵心             ・・・・・・・・(もしくは絵心を持つ協力者)
・折れない心          ・・・・・・・・用意できるだけ
・壁紙のコーディングへの慣れ  ・・・・・・・・1回書けばなれる
ということでさっそく作っていきたいと思います。

① Manifest.xml
② wallpaper.xml
③ Main.java
設定画面を盛り込む場合
④ 再びManifest.xml
⑤ setting.xml
⑥ Preference.java

①Manifest.xml
『minSdkVersion』の設定
ライブ壁紙は初めからあったものではなくAPI7(Android2.1)から登場したものなので、
<uses-sdk android:minSdkVersion=”7″ />
の記述が必要です。

余談ですが、今も0.1%ほどAndroid1.6以下の方がいるらしいです。

『壁紙であることの宣言』
下の一行が必要です。

<uses-feature android:name=”android.software.live_wallpaper” />

『壁紙のサービスの宣言』

赤字の場所をプロジェクトに合わせ変更してください。

<!– ライブ壁紙本体 –>
<service
android:enabled=”true”
android:permission=”android.permission.BIND_WALLPAPER”
android:label=”@string/app_name”
android:name=”.Main“>              ・・・壁紙のサービスを実行するjavaファイル
<intent-filter>
<action android:name=”android.service.wallpaper.WallpaperService”></action>
</intent-filter>
<meta-data
android:name=”android.service.wallpaper”
android:resource=”@xml/wallpaper“>     ・・・壁紙の(簡単な)仕様を書いたXMLの名前
</meta-data>
</service>

 ② wallpaper.xml

resフォルダの下にxmlという名前でフォルダを作成します。その中に

簡単な壁紙の仕様を書いたXMLファイルを作ります。
android:resource=”@xml/wallpaper”と宣言したので
wallpaper.xmlとしてますが実際の宣言に合わせここも変更してください。

ファイルの中身はこれだけです。赤字は環境に合わせ変更してください。

① /thumbnailは壁紙選択時に出てくる左側の小さなサムネイルのこと

② @string/descriptionはその右にある説明文です。

<?xml version=”1.0″ encoding=”UTF-8″?>
<wallpaper
xmlns:android=”http://schemas.android.com/apk/res/android”
android:thumbnail=”@drawable/thumbnail“  ・・・    ①
android:description=”@string/description“  ・・・   ②
android:settingsActivity=”jp.gr.java_conf.rcd.Preference”
/>

③Main.java
ポイントは以下の部分です。
1.extends WallpaperServiceと壁紙のサービスを継承していること
2.コンストラクタで設定情報を受け取ること

public MyEngine(Resources r){
// 設定画面を取得
prefs = Main.this.getSharedPreferences(SHARED_PREFS_NAME, 0);
// 設定画面の変更をリスナーする
prefs.registerOnSharedPreferenceChangeListener(this);

}
設定が途中で変更された事を感知する必要がある(状況、時間が設定条件と絡みがある場合)
下記のように設定しておくとよい。

@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
try{
drawFrame();
}catch(NullPointerException ne){
drawFrame();
}
}

3.描画処理
高速描画を目的にSurfaceHolderを利用しています。
時間経過ととも画像を書き変えていますが、このメソッドで
下の3つのようにメインの動きを行っています。

1更新間隔の設定、
2条件に合ったランダム画像の選定
3絵の上に設定どおり文字を設置して描画する

void drawFrame() {
SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try{
c= holder.lockCanvas();

Paint p = new Paint();
p.setTextSize(30);
p.setAntiAlias(true);
c.drawColor(Color.WHITE);

Calendar cal = Calendar.getInstance();
weekJudge(c, p, cal);
}finally{
if(c!=null){
holder.unlockCanvasAndPost(c);
}
handler.removeCallbacks(drawThread);
}
//ここで更新時間を決める(処理時間+ここの設定…ミリ秒)
if (visible){ handler.postDelayed(drawThread, 12000);}
}

4.スレッドを利用して描画を行わせるクラスですが3.のdrawFrameでまとめてしまったので
こんなにシンプルになります。

private final Runnable drawThread = new Runnable() {
@Override
public void run(){
drawFrame();

}
};

5.見えていないときはちゃんと中断しておく
具体的にはonVisibilityChangedを設定します。これやっておかないと
見えていない状態でも壁紙を動かしてしまうので電池がすさまじく消費します。
見えている時だけ仕事していればいいよ、教えてあげましょう。

@Override
public void onVisibilityChanged(boolean visible) {
this.visible = visible;
if (visible) {
drawFrame();
}
else {
handler.removeCallbacks(drawThread);
}
}

ゴミの比教えたる

実際にアプリで使用されているソースを公開します。
有料ですが15分以内に動きをチェックして払い戻しを押せば
99円かからずに済むので動きもチェックしてみてください。
>>こちらからダウンロードできます<<

実際に組み込まれているソースの方が分かりやすいですよねってことで、以下に実際に使われているMain.javaを公開してあります。ごさんこうくださいませ。

 

 

 

 

 

パッケージ,インポートは略しています。

public class Main extends WallpaperService{
// 設定画面クラスのパス
public static final String SHARED_PREFS_NAME = &quot;jp.mdlab.livewallpaper.Preference&quot;;
String listStr=&quot;&quot;;
Boolean checkboxStr=false;
String editStr=&quot;&quot;;
Drawable drawable;
int imageOrder;
Random rand;
int resourceId;
/** 背景画像リソースID配列 */
//なし
protected int[] imageResources1 = {
R.drawable.hamu2,
R.drawable.hamu13,
R.drawable.hamu18,
};
//燃やせるゴミ
protected int[] imageResources2 = {
R.drawable.hamu1,
R.drawable.hamu10,
R.drawable.hamu14,
R.drawable.hamu21

};
//燃やせないゴミ
protected int[] imageResources3 = {
R.drawable.hamu5,
R.drawable.hamu9,
R.drawable.hamu19,
R.drawable.hamu23
};
//資源ゴミ
protected int[] imageResources4 = {
R.drawable.hamu3,
R.drawable.hamu8,
R.drawable.hamu15,
R.drawable.hamu22,
};
//プラマーク
protected int[] imageResources5 = {
R.drawable.hamu6,
R.drawable.hamu16,
R.drawable.hamu25,

};
//危険ゴミ
protected int[] imageResources6 = {
R.drawable.hamu7,
R.drawable.hamu12,
R.drawable.hamu17,
};
//古紙・新聞紙
protected int[] imageResources7 = {
R.drawable.hamu4,
R.drawable.hamu11,
R.drawable.hamu20,
R.drawable.hamu24
};
@Override
public void onCreate() {
super.onCreate();
}

@Override
public void onDestroy() {
super.onDestroy();
}

@Override
public Engine onCreateEngine() {
return new MyEngine(getResources());
}

public class MyEngine extends Engine
implements SharedPreferences.OnSharedPreferenceChangeListener{
SharedPreferences prefs;
private final Handler handler = new Handler();
private boolean visible;

/**
* コンストラクタ
*/
public MyEngine(Resources r){
// 設定画面を取得
prefs = Main.this.getSharedPreferences(SHARED_PREFS_NAME, 0);
// 設定画面の変更をリスナーする
prefs.registerOnSharedPreferenceChangeListener(this);

}

/**
* 設定画面が変更されたときに呼ばれる
*/
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
try{
drawFrame();
}catch(NullPointerException ne){
drawFrame();
}
}

// ================================================================
/**
* 描画
*/
void drawFrame() {
SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try{
c= holder.lockCanvas();

// ---------------------------
// 描画処理など
// ---------------------------
Paint p = new Paint();
p.setTextSize(30);
p.setAntiAlias(true);
// c.drawColor(Color.WHITE);

Calendar cal = Calendar.getInstance();
weekJudge(c, p, cal);
}finally{
if(c!=null){
holder.unlockCanvasAndPost(c);
}
handler.removeCallbacks(drawThread);
}
//ここで更新時間を決める(処理時間+ここの設定…ミリ秒)
if (visible){ handler.postDelayed(drawThread, 12000);}
}

/**
* @param c
* @param p
* @param cal
*/
private void weekJudge(Canvas c, Paint p, Calendar cal) {
// 設定画面を取得
prefs = Main.this.getSharedPreferences(SHARED_PREFS_NAME, 0);
// 設定画面の変更をリスナーする
prefs.registerOnSharedPreferenceChangeListener(this);

//プリファレンス情報を読み込む
int type=0;
Drawable drawable=null;
Random rand;
// 今日の曜日(1:sunday~7:sturday)
switch(cal.get(Calendar.DAY_OF_WEEK)){
case 1://日曜日
rand = new Random();
//設定を読み込む
type=Integer.parseInt(prefs.getString(&quot;list_key7&quot;, &quot;1&quot;));
drawable = resouceSelect(type, drawable, rand);
drawable.setBounds(0, 0, c.getWidth(), c.getHeight());
drawable.draw(c);
//文字を書く処理
//editTextを取得
editStr=prefs.getString(&quot;edittext_key7&quot;, &quot;&quot;);
c.drawText(&quot;I am Marquis Hamlet&quot;, 100, 170, p);
if(editStr.length()!=0){
c.drawText(&quot;&quot;+editStr, 100, 320, p);
}
break;
case 2://月曜日
rand = new Random();
//設定を読み込む
type=Integer.parseInt(prefs.getString(&quot;list_key&quot;, &quot;1&quot;));
drawable = resouceSelect(type, drawable, rand);
drawable = resouceSelect(type, drawable, rand);
drawable.setBounds(0, 0, c.getWidth(), c.getHeight());
drawable.draw(c);
//文字を書く処理
//editTextを取得
editStr=prefs.getString(&quot;edittext_key&quot;, &quot;&quot;);
// c.drawText(&quot;I am Marquis Hamlet&quot;, 100, 170, p);
if(editStr.length()!=0){
c.drawText(&quot;&quot;+editStr, 100, 170, p);
}
break;
case 3://火曜日
rand = new Random();
//設定を読み込む
type=Integer.parseInt(prefs.getString(&quot;list_key2&quot;, &quot;1&quot;));
drawable = resouceSelect(type, drawable, rand);
drawable.setBounds(0, 0, c.getWidth(), c.getHeight());
drawable.draw(c);
//文字を書く処理
//editTextを取得
editStr=prefs.getString(&quot;edittext_key2&quot;, &quot;&quot;);
if(editStr.length()!=0){
c.drawText(&quot;&quot;+editStr, 100, 170, p);
}
break;
case 4://水曜日
rand = new Random();
//設定を読み込む
type=Integer.parseInt(prefs.getString(&quot;list_key3&quot;, &quot;1&quot;));
Log.v(&quot;水曜日のTYPE&quot;,&quot;type = &quot;+type);
drawable = resouceSelect(type, drawable, rand);
drawable.setBounds(0, 0, c.getWidth(), c.getHeight());
drawable.draw(c);
//文字を書く処理
//editTextを取得
editStr=prefs.getString(&quot;edittext_key3&quot;, &quot;&quot;);
if(editStr.length()!=0){
c.drawText(&quot;&quot;+editStr, 100, 170, p);
}
break;
case 5://木曜日
rand = new Random();
//設定を読み込む
type=Integer.parseInt(prefs.getString(&quot;list_key4&quot;, &quot;1&quot;));
drawable = resouceSelect(type, drawable, rand);
drawable.setBounds(0, 0, c.getWidth(), c.getHeight());
drawable.draw(c);
//文字を書く処理
//editTextを取得
editStr=prefs.getString(&quot;edittext_key4&quot;, &quot;&quot;);
if(editStr.length()!=0){
c.drawText(&quot;&quot;+editStr, 100, 170, p);
}
break;
case 6://金曜日
rand = new Random();
//設定を読み込む
type=Integer.parseInt(prefs.getString(&quot;list_key5&quot;, &quot;1&quot;));
drawable = resouceSelect(type, drawable, rand);
drawable.setBounds(0, 0, c.getWidth(), c.getHeight());
drawable.draw(c);
//文字を書く処理
//editTextを取得
editStr=prefs.getString(&quot;edittext_key5&quot;, &quot;&quot;);
if(editStr.length()!=0){
c.drawText(&quot;&quot;+editStr, 100, 170, p);
}
break;
case 7://土曜日
rand = new Random();
//設定を読み込む
type=Integer.parseInt(prefs.getString(&quot;list_key6&quot;, &quot;1&quot;));
drawable = resouceSelect(type, drawable, rand);
drawable.setBounds(0, 0, c.getWidth(), c.getHeight());
drawable.draw(c);
//文字を書く処理
//editTextを取得
editStr=prefs.getString(&quot;edittext_key6&quot;, &quot;&quot;);
if(editStr.length()!=0){
c.drawText(&quot;&quot;+editStr, 100, 170, p);
}
break;

default://曜日が分からなかった場合
//文字を書く処理
//editTextを取得
editStr=prefs.getString(&quot;edittext_key&quot;, &quot;&quot;);
c.drawText(&quot;I am Marquis Hamlet&quot;, 100, 170, p);
break;
}
}
private Drawable resouceSelect(int type, Drawable drawable, Random rand) {
int imageOrder;
int resourceId;
switch(type){
case 1:
try{
imageOrder = (Math.abs(rand.nextInt()) % imageResources1.length);
resourceId = imageResources1[imageOrder];
drawable = getResources().getDrawable(resourceId);
}catch(NotFoundException ne){
imageOrder = (Math.abs(rand.nextInt()) % imageResources1.length);
resourceId = imageResources1[imageOrder];
drawable = getResources().getDrawable(resourceId);
}
break;
case 2:
try{
imageOrder = (Math.abs(rand.nextInt()) % imageResources2.length);
resourceId = imageResources2[imageOrder];
drawable = getResources().getDrawable(resourceId);
}catch(NotFoundException ne){
imageOrder = (Math.abs(rand.nextInt()) % imageResources2.length);
resourceId = imageResources2[imageOrder];
drawable = getResources().getDrawable(resourceId);
}
break;
case 3:
try{
imageOrder = (Math.abs(rand.nextInt()) % imageResources3.length);
resourceId = imageResources3[imageOrder];
drawable = getResources().getDrawable(resourceId);
}catch(NotFoundException ne){
imageOrder = (Math.abs(rand.nextInt()) % imageResources3.length);
resourceId = imageResources3[imageOrder];
drawable = getResources().getDrawable(resourceId);
}
break;
case 4:
try{
imageOrder = (Math.abs(rand.nextInt()) % imageResources4.length);
resourceId = imageResources4[imageOrder];
drawable = getResources().getDrawable(resourceId);
}catch(NotFoundException ne){
imageOrder = (Math.abs(rand.nextInt()) % imageResources4.length);
resourceId = imageResources4[imageOrder];
drawable = getResources().getDrawable(resourceId);
}
break;
case 5:
try{
imageOrder = (Math.abs(rand.nextInt()) % imageResources5.length);
resourceId = imageResources5[imageOrder];
drawable = getResources().getDrawable(resourceId);
}catch(NotFoundException ne){
imageOrder = (Math.abs(rand.nextInt()) % imageResources5.length);
resourceId = imageResources5[imageOrder];
drawable = getResources().getDrawable(resourceId);
}
break;
case 6:
try{
imageOrder = (Math.abs(rand.nextInt()) % imageResources6.length);
resourceId = imageResources6[imageOrder];
drawable = getResources().getDrawable(resourceId);
}catch(NotFoundException ne){
imageOrder = (Math.abs(rand.nextInt()) % imageResources6.length);
resourceId = imageResources6[imageOrder];
drawable = getResources().getDrawable(resourceId);
}
break;
case 7:
try{
imageOrder = (Math.abs(rand.nextInt()) % imageResources7.length);
resourceId = imageResources7[imageOrder];
drawable = getResources().getDrawable(resourceId);
}catch(NotFoundException ne){
imageOrder = (Math.abs(rand.nextInt()) % imageResources7.length);
resourceId = imageResources7[imageOrder];
drawable = getResources().getDrawable(resourceId);
}
break;
default:
break;
}
return drawable;
}

private final Runnable drawThread = new Runnable() {
@Override
public void run(){
drawFrame();

}
};

@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
}

@Override
public void onDestroy() {
super.onDestroy();
handler.removeCallbacks(drawThread);
}
@Override
public void onVisibilityChanged(boolean visible) {
this.visible = visible;
if (visible) {
drawFrame();
}
else {
handler.removeCallbacks(drawThread);
}
}

@Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
drawFrame();
}

@Override
public void onSurfaceCreated(SurfaceHolder holder) {
super.onSurfaceCreated(holder);
}

@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
visible = false;
handler.removeCallbacks(drawThread);
}

@Override
public void onOffsetsChanged(float xOffset, float yOffset, float xStep, float yStep, int xPixels, int yPixels) {
// drawFrame();
}

@Override
public void onDesiredSizeChanged(int desiredWidth, int desiredHeight) {
// drawFrame();
}
}
}

 

後半戦は設定画面の追加していよいよ完成です。 お楽しみに

ここまで読んでくださった皆さんありがとうございます。

ゴミの比教えたる

 

 

 

 

 

 

 
今回はここまでです。

引き続きよろしくお願いします。

 

 

▼ 関連記事・最近の投稿は記事の下にあります。コチラもご参考ください。


About the Author

dhmo
Author:DHMO(ディベロッパー名) 仕事では自社サービス・メディアの開発を行ってます。 趣味でAndroidアプリ製作を行っています。 カラオケではランキングバトルにはまっております。 Mail: dihydromooxide7@gmail.com 

Be the first to comment on "便利な壁紙作ってみた~ライブ壁紙作り方~①"

Leave a comment

Your email address will not be published.


*