‘ライブ壁紙’ タグのついている投稿

ライブ壁紙開発時にUSBケーブルを接続しないと起動しない問題

問題というほどでもなかった。Androidのライブ壁紙作成のお話。

ライブ壁紙をステップ実行してデバッグするためにwaitForDebuggerを書いたのはいいのだけど、それを忘れてデバッグ用じゃない端末にインストールすると、一向にライブ壁紙を選択した後の「ライブ壁紙を読み込み中…」から進まない。

開発用端末でUSBケーブルを繋いでいると先に進めてしまうので、isDebuggerConnectedメソッドで分岐するようにしました。

public class MyWallpaperService extends WallpaperService {

	private final Handler handler = new Handler();

	@Override
	public Engine onCreateEngine() {
		if (android.os.Debug.isDebuggerConnected() // ここでデバッガが繋がっているか判定
				&& MyApplication.isDebuggable()) { // こっちはmanifestのdebuggableを読む実装
			android.os.Debug.waitForDebugger();    // デバッガ待機
		}
		return new MyEngine();
	}

	// do something ...

}


Androidのライブ壁紙をActivityから指定したい

アプリの一覧からアイコンを押したら、ライブ壁紙をプレビュー→壁紙に設定できる状態にできないかという話題。

ちなみに結論としてはパーミッション不足により失敗です。

ライブ壁紙の選択画面を表示させることはできるので、
Live Wallpaper – Binding an Activity to the ‘Open’ button of the market
こちらを参考にライブ壁紙選択画面の上にカスタムビューなどを表示させて誘導させるのが次善の策かと思います。

ライブ壁紙選択画面を表示するだけなら

Intent intent = new Intent(); 
intent.setAction(WallpaperManager.ACTION_LIVE_WALLPAPER_CHOOSER); 
startActivity(intent); 

でOK。

以下は失敗の記録。

上で書いたライブ壁紙選択画面表示のコードは 
LiveWallpaperをアプリから設定する方法を探ってみた|いろいろ備忘録

こちらの方法でも代替できます。

LiveWallpaperListActivityのソースコードを持ってきて追いかけてみることにしました。

LiveWallpaperListActivity.java

これを同じパッケージ内に設置して、layoutやdimen、color等を適当に用意してやることで、選択画面は同じ物を再現できます。

一応、用意したファイル

live_wallpaper_list.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="6dip" android:paddingRight="6dip" android:paddingTop="6dip" android:paddingBottom="6dip" android:minHeight="?android:attr/listPreferredItemHeight"> 
<ListView android:id="@android:id/list" android:layout_width="fill_parent" android:layout_height="fill_parent" android:drawSelectorOnTop="false"/> 
<TextView android:id="@android:id/empty" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center" android:visibility="gone" android:text="@string/live_wallpaper_empty" android:textAppearance="?android:attr/textAppearanceMedium"/> 
</LinearLayout>

live_wallpaper_entry.xml

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="6dip" android:paddingRight="6dip" android:paddingTop="6dip" android:paddingBottom="6dip" android:minHeight="?android:attr/listPreferredItemHeight"> 
<ImageView android:id="@+id/thumbnail" android:layout_width="@dimen/live_wallpaper_thumbnail_width" android:layout_height="@dimen/live_wallpaper_thumbnail_width" android:layout_gravity="center_vertical" android:scaleType="centerCrop"/> 
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dip" android:layout_marginRight="8dip" android:layout_centerVertical="true" android:layout_toRightOf="@id/thumbnail" android:orientation="vertical"> 
<TextView android:id="@+id/title_author" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:singleLine="true" android:ellipsize="marquee"/> 
<TextView android:id="@+id/description" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceSmall" android:maxLines="3"/> 
</LinearLayout> 
</RelativeLayout>

color.xml

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <color name="live_wallpaper_thumbnail_background">#000000</color> 
    <color name="live_wallpaper_thumbnail_text_color">#ffffff</color> 
</resources>

dimens.xml (値は適当にいれた)

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <dimen name="live_wallpaper_thumbnail_width">50dp</dimen> 
    <dimen name="live_wallpaper_thumbnail_height">50dp</dimen> 
    <dimen name="live_wallpaper_thumbnail_text_size">50dp</dimen> 
    <dimen name="live_wallpaper_thumbnail_text_offset">50dp</dimen> 
</resources>

で、このままでは

LiveWallpaperPreview.showPreview(this , REQUEST_PREVIEW, intent, info);

の行がコンパイルできないのでshowPreviewメソッド(staticメソッド)だけを取り出してきてLiveWallpaperListActivityに

	static final String EXTRA_LIVE_WALLPAPER_INTENT = "android.live_wallpaper.intent";
	static final String EXTRA_LIVE_WALLPAPER_SETTINGS = "android.live_wallpaper.settings";
	static final String EXTRA_LIVE_WALLPAPER_PACKAGE = "android.live_wallpaper.package";

	public void onItemClick(AdapterView<?> parent, View view, int position,
			long id) {
		final Intent intent = mWallpaperIntents.get(position);
		final WallpaperInfo info = mWallpaperInfos.get(position);
		//LiveWallpaperPreview.showPreview(this, REQUEST_PREVIEW, intent, info);
		//Intent preview = new Intent(this, LiveWallpaperPreview.class);
		String clazz = "com.android.wallpaper.livepicker.LiveWallpaperPreview";
		Intent preview = new Intent(Intent.ACTION_MAIN);
		int idx = clazz.lastIndexOf('.');
		String pkg = clazz.substring(0, idx);
		preview.setClassName(pkg, clazz);
		preview.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		preview.putExtra(EXTRA_LIVE_WALLPAPER_INTENT, intent);
		preview.putExtra(EXTRA_LIVE_WALLPAPER_SETTINGS,
				info.getSettingsActivity());
		preview.putExtra(EXTRA_LIVE_WALLPAPER_PACKAGE, info.getPackageName());
		this.startActivityForResult(preview, REQUEST_PREVIEW);
	}

先程のサイトを参考に、こんな感じで書き換え。で、実行。

FATAL EXCEPTION: main 
java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.MAIN flg=0x10000000 cmp=com.android.wallpaper.livepicker/.LiveWallpaperPreview (has extras) } from ProcessRecord{4073a338 8432:com.sample.android.TestCase/10077} (pid=8432, uid=10077) requires null 
    at android.os.Parcel.readException(Parcel.java:1322) 
    at android.os.Parcel.readException(Parcel.java:1276) 
    at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:1351) 
    at android.app.Instrumentation.execStartActivity(Instrumentation.java:1374) 
    at android.app.Activity.startActivityForResult(Activity.java:2827) 
    at com.sample.android.TestCase.LiveWallpaperListActivity.onItemClick(LiveWallpaperListActivity.java:201) 
    at android.widget.AdapterView.performItemClick(AdapterView.java:284) 
    at android.widget.ListView.performItemClick(ListView.java:3513) 
    at android.widget.AbsListView$PerformClick.run(AbsListView.java:1812) 
    at android.os.Handler.handleCallback(Handler.java:587) 
    at android.os.Handler.dispatchMessage(Handler.java:92) 
    at android.os.Looper.loop(Looper.java:130) 
    at android.app.ActivityThread.main(ActivityThread.java:3683) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:507) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
    at dalvik.system.NativeStart.main(Native Method)

とりあえずライブ壁紙の一覧とアイコンは取れるってことはわかりましたね…