Androidアプリ OpenGLのライブ壁紙を作る [Android OpenGL]
AREarthライブ壁紙をリリースしてから、1日経過した。まだ、ダウンロード数は0である。
やはり、宣伝しないとだれも気付いてくれない。
それは、さておき、本日は、ライブ壁紙の作り方についてである。
Androidのアプリには、普通のアプリと「ライブ壁紙」の2種類がある。アプリは、使いたいときに起動して使う。ライブ壁紙は、ラウンチャーの壁紙用のアプリである。単なる壁紙は、画像データのみであるが、ライブ壁紙はプログラムとなっていて、アプリをインストールすると壁紙として使用できるようになる。ライブ壁紙をインストールして選択すると、「動く壁紙」になるわけである。
さて、ライブ壁紙を作ろう、というのが本日の趣旨である。
普通のアプリなら、アクティビティを作って、その中で何かを表示させたり、ビューやレイアウトを使ってGUIを構築すればよい。
ライブ壁紙はというと、アクティビティじゃなくて、WallpaperServiceの派生クラスを作ってやる必要がある。ふーん。WallpaperServiceは、アクティビティと異なり、ラウンチャー(ホーム画面)が表示されている時だけ動いていればよいので、状態遷移がアクティビティよりは単純。
あてずっぽうではあるが、Serviceの派生クラスなんだろうな。きっと。Serviceは画面を持たない、バックグラウンドで動作するようなアプリを作るときに、使用するクラス。
WallpaperServiceをextendsして派生クラスを作って、onCreateEngineでWallpaperService.Engineのインスタンスを作って、returnで戻せばよいようである。
こんな感じ。
MyWallpaperServiceを作ってみた。
エンジンの方も作らないといけない。MyEngineは、WallpaperService.Engineの派生クラスとして、以下のように定義すればよいらしい。
むむむ。SurfaceViewなのね。
SurfaceViewに描画するときって、どうするんだっけ...
OpenGL使うときは、どうするのよ...
と、ここまで調べて行き詰ってしまった。
そもそも、なんで「ライブ壁紙を作ろう」と思ったかというと、AREarthroidのライブ壁紙版を作りたかったから。
AREarthroidは、OpenGLのSurfaceViewを使っている。単なるSurfaceViewならそのまま、描画ルーチンを持ってくれば、よさそうだが、OpenGLのGLSurfaceViewを持ってこれるのか...
アクティビティみたいに、簡単にはいかないのか...
多分、簡単なやり方があるんだろうなぁ... という安易な気持ちで検索していく。
WallpaperServiceとOpenGLで検索。
なんか、的中はしなかったが、いろいろ調べていくと、GLWallpaperServiceなるものを発見。
どこが正式なサイトなのかよくわからないので、URLは載せないが、検索したらすぐに、見つかると思う。
で、GLWallpaperServiceを使用することに。
GLWallpaperService.jarがあったので、これをlibsフォルダに入れる。
WallpaperService を GLWallpaperServiceに変更する。
エンジンの方は、GLWallpaperService.GLEngineからextendsで作成する。
onCreateでレンダラーを作って、setRendererしてやると描画できる。基本、GLSurfaceView.Rendererのラッパーみたいなので、setEGLConfigChooserとか、setRenderer、setRenderMode、queueEventなどが使える。
queueEventについては、こちらを参照。
setRenderModeの記事は、この記事を参照。
MyRendererでレンダリングする。GLWallpaperService.Rendererインタフェースを実装する必要がある。GLWallpaperService.Renderer = GLSurfaceView.Renderer みたいなので、Rendererで必要なメソッドを実装する。
ライブ壁紙は、アクティビティではなく、サービスなので、AndroidManifest.xmlにserviceを定義する。
AndroidManifest.xml
ライブ壁紙を選択する際に必要になる。ライブ壁紙の定義をxml/wallpaper.xmlを作成して、行う。ファイル名は、AndroidManifest.xmlで指定したものに合わせる。
res/xml/wallpaper.xml
これで、一応は、表示させることができた。
しかし、そのままAREarthroidのレンダラーを使うと、ビットマップや3Dデータでメモリを使い過ぎ。エンジンが頻繁に生成されている模様。
アクティビティが起動するとライブ壁紙は非表示となる。このとき、WallpaperServiceのonVisibilityChangedが発生するが、GLWallpaperServiceでは、visibilityをみて、onResume、onPauseメソッドを呼び出すようになっている。
ライブ壁紙が非表示なら、GLSurfaceViewのインスタンスは必要ないので、破棄される。描画用のGLThreadも破棄されるので、テクスチャ用のビットマップやVBOも破棄されてしまうらしく、ライブ壁紙が再表示されると、挙動がおかしい。
onResumeで、ビットマップのロードを行うことでこの問題を回避した。
関連記事
OpenGLの記事を最初から読みたいなら、以下からどうぞ。
Androidアプリ開発 OpenGLを使う GLSurfaceView
サイト内を検索
やはり、宣伝しないとだれも気付いてくれない。
それは、さておき、本日は、ライブ壁紙の作り方についてである。
Androidのアプリには、普通のアプリと「ライブ壁紙」の2種類がある。アプリは、使いたいときに起動して使う。ライブ壁紙は、ラウンチャーの壁紙用のアプリである。単なる壁紙は、画像データのみであるが、ライブ壁紙はプログラムとなっていて、アプリをインストールすると壁紙として使用できるようになる。ライブ壁紙をインストールして選択すると、「動く壁紙」になるわけである。
さて、ライブ壁紙を作ろう、というのが本日の趣旨である。
普通のアプリなら、アクティビティを作って、その中で何かを表示させたり、ビューやレイアウトを使ってGUIを構築すればよい。
ライブ壁紙はというと、アクティビティじゃなくて、WallpaperServiceの派生クラスを作ってやる必要がある。ふーん。WallpaperServiceは、アクティビティと異なり、ラウンチャー(ホーム画面)が表示されている時だけ動いていればよいので、状態遷移がアクティビティよりは単純。
あてずっぽうではあるが、Serviceの派生クラスなんだろうな。きっと。Serviceは画面を持たない、バックグラウンドで動作するようなアプリを作るときに、使用するクラス。
WallpaperServiceをextendsして派生クラスを作って、onCreateEngineでWallpaperService.Engineのインスタンスを作って、returnで戻せばよいようである。
こんな感じ。
public class MyWallpaperService extends WallpaperService { @Override public Engine onCreateEngine() { return new MyEngine(); } }
MyWallpaperServiceを作ってみた。
エンジンの方も作らないといけない。MyEngineは、WallpaperService.Engineの派生クラスとして、以下のように定義すればよいらしい。
class MyEngine extends WallpaperService.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); } @Override public void onSurfaceDestroyed(SurfaceHolder holder) { super.onSurfaceDestroyed(holder); } }
むむむ。SurfaceViewなのね。
SurfaceViewに描画するときって、どうするんだっけ...
OpenGL使うときは、どうするのよ...
と、ここまで調べて行き詰ってしまった。
そもそも、なんで「ライブ壁紙を作ろう」と思ったかというと、AREarthroidのライブ壁紙版を作りたかったから。
AREarthroidは、OpenGLのSurfaceViewを使っている。単なるSurfaceViewならそのまま、描画ルーチンを持ってくれば、よさそうだが、OpenGLのGLSurfaceViewを持ってこれるのか...
アクティビティみたいに、簡単にはいかないのか...
多分、簡単なやり方があるんだろうなぁ... という安易な気持ちで検索していく。
WallpaperServiceとOpenGLで検索。
なんか、的中はしなかったが、いろいろ調べていくと、GLWallpaperServiceなるものを発見。
どこが正式なサイトなのかよくわからないので、URLは載せないが、検索したらすぐに、見つかると思う。
で、GLWallpaperServiceを使用することに。
GLWallpaperService.jarがあったので、これをlibsフォルダに入れる。
WallpaperService を GLWallpaperServiceに変更する。
public class MyWallpaperService extends GLWallpaperService { @Override public Engine onCreateEngine() { return new MyEngine(); } }
エンジンの方は、GLWallpaperService.GLEngineからextendsで作成する。
onCreateでレンダラーを作って、setRendererしてやると描画できる。基本、GLSurfaceView.Rendererのラッパーみたいなので、setEGLConfigChooserとか、setRenderer、setRenderMode、queueEventなどが使える。
queueEventについては、こちらを参照。
setRenderModeの記事は、この記事を参照。
class MyEngine extends GLWallpaperService.GLEngine { @Override public void onCreate(SurfaceHolder surfaceHolder) { super.onCreate(surfaceHolder); setEGLConfigChooser(8, 8, 8, 8, 16, 0); setRenderer(new MyRenderer()); } }
MyRendererでレンダリングする。GLWallpaperService.Rendererインタフェースを実装する必要がある。GLWallpaperService.Renderer = GLSurfaceView.Renderer みたいなので、Rendererで必要なメソッドを実装する。
class MyRenderer implements GLWallpaperService.Renderer { public void onDrawFrame(GL10 gl) { // ここで描画 } public void onSurfaceChanged(GL10 gl, int width, int height) { } public void onSurfaceCreated(GL10 gl, EGLConfig config) { } }
ライブ壁紙は、アクティビティではなく、サービスなので、AndroidManifest.xmlにserviceを定義する。
AndroidManifest.xml
<application android:label="@string/app_name" android:icon="@drawable/ic_launcher" android:theme="@style/AppTheme"> <service android:label="MyLiveWallpaper" android:name=".MyWallpaperService" 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/wallpaper" /> </service> </application>
ライブ壁紙を選択する際に必要になる。ライブ壁紙の定義をxml/wallpaper.xmlを作成して、行う。ファイル名は、AndroidManifest.xmlで指定したものに合わせる。
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" />
これで、一応は、表示させることができた。
しかし、そのままAREarthroidのレンダラーを使うと、ビットマップや3Dデータでメモリを使い過ぎ。エンジンが頻繁に生成されている模様。
アクティビティが起動するとライブ壁紙は非表示となる。このとき、WallpaperServiceのonVisibilityChangedが発生するが、GLWallpaperServiceでは、visibilityをみて、onResume、onPauseメソッドを呼び出すようになっている。
ライブ壁紙が非表示なら、GLSurfaceViewのインスタンスは必要ないので、破棄される。描画用のGLThreadも破棄されるので、テクスチャ用のビットマップやVBOも破棄されてしまうらしく、ライブ壁紙が再表示されると、挙動がおかしい。
onResumeで、ビットマップのロードを行うことでこの問題を回避した。
関連記事
OpenGLの記事を最初から読みたいなら、以下からどうぞ。
Androidアプリ開発 OpenGLを使う GLSurfaceView
サイト内を検索
Copyright Atsushi Asai Google+朝井淳
[データベースの気持ちがわかる]SQLはじめの一歩 (WEB+DB PRESS plus)
- 作者: 朝井 淳
- 出版社/メーカー: 技術評論社
- 発売日: 2015/03/03
- メディア: 単行本(ソフトカバー)
Access クエリ 徹底活用ガイド ~仕事の現場で即使える
- 作者: 朝井 淳
- 出版社/メーカー: 技術評論社
- 発売日: 2018/05/25
- メディア: 大型本
Thanks for finally talking about >Androidアプリ OpenGLのライブ壁紙を作る:AABlog:So-netブログ <Liked it!
by Warner (2022-09-22 19:46)
Ηi therе to all, how iis all, I think eveгу one iis
gettіng more from this web page, and youг vijews are nice in favor of new people.
by Bret (2022-09-24 18:00)
共有していただきありがとうございます。
by android (2023-06-27 02:03)
Thanks for sharing your thoughts about カメラ.
Regards
by Kimberly (2023-11-10 05:45)
WOW just what I was looking for. Came here by searching for
cách học giao tiếp tiếng anh
by Kimberly (2023-12-03 21:41)
Hi there I am so excited I found your web site, I
really found you by mistake, while I was browsing on Aol for something else, Anyhow I am here now and would just like
to say thanks for a tremendous post and a all round entertaining blog (I also love the theme/design), I don’t have time
to go through it all at the moment but I have saved
it and also added in your RSS feeds, so when I have time I will be back to read a great deal more, Please do keep up the great jo.
by Lino (2023-12-09 19:15)