2011年10月4日火曜日

ichannel風のどの画面でもテロップ



いつでもどの画面でもテロップが表示され続けるアプリを作った。
Yahoo!の国内ニュースを取得してテロップで流し続けて
ドラッグで移動できるので邪魔にならない場所に移動できるが、消す方法が無いので我ながらかなりうざい。。。

コード整理したらマーケットに上げよーっと。

2011年9月30日金曜日

freeのPDF Viewer


Androidで使えるfreeでソースが手に入るPDF Viewerが欲しかったので探したがあまりいいのがなかった。
でもapvはい感じだった。
ただ、日本語の表示が出来なかったのでIPAフォントを入れて日本語表示できるようにした。
ソースは以下においてある。
https://github.com/matsuhiro/APV-Custom

コードを取得したら、
$ cd pdfview/scripts
$ ./build-native.sh
を実行するとnativeコードのライブラリができるので、
eclipseでプロジェクトをインポートしてあげれば動くはず。

拡大縮小の時に画面がチラつくが、表示の速さは実用レベルだw

これを自分用にカスタマイズしていこーっと。

写真は京都の鴨川です。3月のライオンにも出てきたところです。いいトコだった。マタ行きたい。

2011年9月12日月曜日

WindowsPhoneとAndroidのゲーム




WindowsPhoneゲームプログラミングの本を読んでみた。
発売前の本だけど、MSの人がブログ上でレビューアを募集していたので
メールしてみたらやらせてくれた。
9月末に発売する予定のようですが、内容はC#とか知らない自分でも十分に読める内容だったし、
量も程良いのでゲームプログラム以外でもWindowsPhoneアプリの入門には丁度よいかも。
WindowsPhoneの本自体は、ebookで公開されている。けどねぇ。。。
900ページ超の大作、しかも英語なので、読むとしてもこちらは検索してリファレンスとして使うくらいでしょうかね(^^ゞ


WindowsPhone自体はXNAとSilverlightの組み合わせで書くわけだけど、
Androidのアプリとか他のモバイルアプリを作ったことがある人はSilverlightで作るアプリは
とっつきやすいと思う。
XNAについては「ゲームってこう作るもんなのね。」という感想。
Silverlightは、フツーにXAML(ザムルとよむらしい。まあXMLですよね)でUIを書いて
UI部品のコールバックを書いてイベントドリブンで処理が進んでいく感じです。
Androidのアプリ開発と感覚が近いです。
でも、XNAの方は、初期化→コンテンツロード→状態更新→描画→状態更新→描画・・・
みたいに、状態更新と描画が繰り返し呼ばれる。しかも1/30秒ごとに。
じゃあイベントの処理(タッチとかジェスチャーとか)をどう処理するのか?というと
状態更新の中で、XNAのフレームワークの中にあるTouchPanelというクラスから
ReadGesture()のようなメソッドをコールしてイベントがあったら処理をする。
といった感じの処理でイベントキューから自分でイベントを取得して処理する感じだ。
フツーはアプリのフレームワーク側でやっているようなイベントキューからの
イベント取得処理をアプリ側でやる感じだと思う。


Androidでゲーム書くときは?
と思ったけどOpenGLでゲーム作ると少しだけど似た感じになるかな?
GLSurfaceView.RendererをimplするとonDrawFrameが繰り返し呼ばれて
その中で描画処理を行う。
イベント処理はというとGLSurfaceViewをオーバーライドして、onTouchEventの中でイベント処理をする。
なので、Androidは、描画は勝手に呼び出されるコールバックで行うけど
イベント処理はイベントドリブンで。
といった感じになっている。
onDrawFrame()の呼び出しはどこで行われているのかというと
frameworks/base/opengl/java/android/opengl/GLSurfaceView.java
の中。
GLをAndroidで使おうとするとGL専用のスレッドが勝手に作られるけど、
その中のguardedRun()でonDrawFrameがコールされている。
で、ソース見てみたらwhile(true)で延々コールしていた。
AndroidでJavaからGLを使うと勝手に繰り返しの描画が行われるみたいで
気おつけるべきだなーっと感じた。まあ、そうしないためのインテーフェースは用意されていたけど。


WindowsPhoneもAndroidもゲームを作るための仕組みはあるけど、
イベント処理はAndroidの方が楽そう。
でも描画や状態の更新が1/30secごとに呼び出されるというのは
ゲームを作る上では結構大事かも。(処理が重かったりすると描画がすっ飛ばされてコマ落ちみたいになることもあるみたいだけど。)
Androidはwhile(true)で処理しているから描画タイミングのすべてを把握できないのかも。
まあ、ソースをパッと見ただけなので、どこかのmethod内にタイミングを図るための仕組みが入っているかもです。

ただ、ゲームでないアプリを作るのであればWindowsPhoneのがよいかも。
ExpressionBlendがすごいので、いい感じのUIを作りやすいのはWindowsPhoneだと思う。

なんかモヤモヤした文章になってしまった。
やっぱりコード書いて確認しなきゃはっきりわからんね。
DevQuizも時間切れだし、こんど時間つくろ。

2011年9月4日日曜日

localにgitのserverを作ってみる。

githubでソース管理してもいいんだけど、タダアカウントだと全部公開されてしまうので
自分のPCにgitのserverたてようかと調べた。
思いの外はまったし、Web上の情報も足りないとこがあったりして
イイ感じにまとまってなかったので、自分でまとめる

git-coreとgit-daemon-runをapt-getして以下を実行する

$ sudo emacs /etc/sv/git-daemon/run

中身を以下のような感じで編集するとgitの公開用のフォルダが/home/user/gitになる
- exec chpst -ugitdaemon \
- "$(git --exec-path)"/git-daemon --verbose --base-path=/var/cache /var/cache/git
+ #exec chpst -ugitdaemon \
+ # "$(git --exec-path)"/git-daemon --verbose --base-path=/var/cache /var/cache/git
+ exec chpst -ugitdaemon "$(git --exec-path)"/git-daemon --verbose --base-path=/home/user/git --export-all --enable=receive-pack


デーモンの再起動をしする
$ sudo sv restart git-daemon
レポジトリを作る
$ sudo git clone --bare /home/user/git/test
ownerを変える。自分はこれではまってしまった。。。
$ sudo chown -R gitdaemon .

適当なディレクトリで
$ mkdir test
$ cd test
$ git init
$ git remote add origin git://localhost/test.git
$ echo "This is README" > README
$ git add README
$ git commit -m "initial commit"
$ git push origin master

$ git branch hoge
$ git checkout hoge
READMEを適当に変更して
$ git add README
$ git commit -m "hoge commit"
$ git push origin hoge
$ git branch -r
origin/hoge
origin/master
こんなかんじで、localにgitのサーバを作って、そんなかでソースの管理ができる。
まあ、ひとつのPCで完結するならサーバにする必要も無いんだけど
PC複数ある時とかはいいかも。
蛇足として、写真は上高地の川の中の画像です。
雨が降ってましたが川はとても透明でした。
youtubeに動画上げてみました。岩魚がおよいでます。

2011年6月29日水曜日

StatusBarのなかみ



以前、StatusBarに情報表示させるアプリを作った際に
ステータスバーでも自作のViewが表示出来ればいのにーと思ったのでStatusBarについて調べた。自分用のメモなので分かりにくくても仕方がない。

android.app.NotificationManager.notify(String tag, int id, Notification notification)
がアプリからコールされて、そのなかでenqueueNotificationWithTag()がコールされる。
サービスとプロセス間通信していいて、インターフェースのStubは
INotificationManager.Stubで、その実態の中で
com.android.server.StatusBarManagerService.addNotification()
がコールされている。
これも中でIPCのI/Fの
com.android.internal.statusbar.IStatusBar.addNotification()
をコールしている。
これの実態は
./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
にIStatusBar.Stubの拡張として定義されているのだが、これがeclipseのパッケージに含まれてないんだよなー。なぜ??
まあいいや。
んで、それを
./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
内で利用しているので、
StatusBarService.java内で作られたViewに対して、プロセス間通信を利用して
android.app.NotificationManagerから情報を渡していっている。
情報はStatusBarIcon implements Parcelableをプロセス間でわたして行っている。といったかんじ。

StatusBarIconView.set()からコールされているgetIcon()の中をみると
r = context.getPackageManager().getResourcesForApplication(icon.iconPackage);
みたいな感じにで、他のパッケージのリソースを取得している。
こうやれば他のパッケージが持っているリソースを利用出来るっぽい。
getIcon()の中でリソースのIDをとってDrawableを作成している。
なので、アイコンは自在に変更できそうもない。という結論。

プロセス間通信しまくりで、最終的にはSystemのUIに行ってしまったので、
やっぱり自作Viewの表示は無理そうだ。
でも、ソースを見ていて
./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
は面白かった。
Handlerを拡張して自作のHandlerを作成して、
そのハンドラーに対して
mHandler.obtainMessage(MSG_UPDATE_NOTIFICATION, 0, 0, ne).sendToTarget();
みたいにMessageをsendしている。
handleMessageってどんな時に使うのが正解なんだろう?
と思っていたけど、このようにプロセス間通信で情報を取得して
それをUIの変更に反映させたい時には、プロセス間通信用のI/Fの中で
MessageをsendすることでUIスレッドに処理を変えてやることで、いい感じの実装になると感じた。

Handlerとかの仕組みって、どうやって思いついたんだろ?
本当はそれが一番知りたい。。。

2011年6月28日火曜日

androidのbuildが32bitでも出来るようになってた?


androidのソースの中身が更新されていて64bitじゃなきゃビルド無理ーな部分が消えていた。
実際、何も変更加えなくてもbuildできた。
でも、HPには8GBのRAMが必要って書いてあったけど、virtual machineじゃないからOK??
良く解らん。


マシンのスペックを晒すと以下のような感じ。

$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=10.04
DISTRIB_CODENAME=lucid
DISTRIB_DESCRIPTION="Ubuntu 10.04.2 LTS"


$ cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 23
model name : Intel(R) Core(TM)2 Quad CPU Q9550 @ 2.83GHz
stepping : 10
cpu MHz : 2003.000
cache size : 6144 KB
physical id : 0
siblings : 4
core id : 0
cpu cores : 4
apicid : 0
initial apicid : 0
fdiv_bug : no
hlt_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs bts aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm sse4_1 xsave lahf_lm tpr_shadow vnmi flexpriority
bogomips : 5652.55
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:

processor : 1
vendor_id : GenuineIntel
cpu family : 6
model : 23
model name : Intel(R) Core(TM)2 Quad CPU Q9550 @ 2.83GHz
stepping : 10
cpu MHz : 2003.000
cache size : 6144 KB
physical id : 0
siblings : 4
core id : 1
cpu cores : 4
apicid : 1
initial apicid : 1
fdiv_bug : no
hlt_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs bts aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm sse4_1 xsave lahf_lm tpr_shadow vnmi flexpriority
bogomips : 5652.46
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:

processor : 2
vendor_id : GenuineIntel
cpu family : 6
model : 23
model name : Intel(R) Core(TM)2 Quad CPU Q9550 @ 2.83GHz
stepping : 10
cpu MHz : 2003.000
cache size : 6144 KB
physical id : 0
siblings : 4
core id : 2
cpu cores : 4
apicid : 2
initial apicid : 2
fdiv_bug : no
hlt_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs bts aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm sse4_1 xsave lahf_lm tpr_shadow vnmi flexpriority
bogomips : 5722.90
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:

processor : 3
vendor_id : GenuineIntel
cpu family : 6
model : 23
model name : Intel(R) Core(TM)2 Quad CPU Q9550 @ 2.83GHz
stepping : 10
cpu MHz : 2003.000
cache size : 6144 KB
physical id : 0
siblings : 4
core id : 3
cpu cores : 4
apicid : 3
initial apicid : 3
fdiv_bug : no
hlt_bug : no
f00f_bug : no
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs bts aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm sse4_1 xsave lahf_lm tpr_shadow vnmi flexpriority
bogomips : 5652.50
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:


$ cat /proc/meminfo
MemTotal: 3355252 kB
MemFree: 842344 kB
Buffers: 196160 kB
Cached: 1619120 kB
SwapCached: 3308 kB
Active: 1101240 kB
Inactive: 1249040 kB
Active(anon): 221664 kB
Inactive(anon): 320800 kB
Active(file): 879576 kB
Inactive(file): 928240 kB
Unevictable: 0 kB
Mlocked: 0 kB
HighTotal: 2498184 kB
HighFree: 624792 kB
LowTotal: 857068 kB
LowFree: 217552 kB
SwapTotal: 9823708 kB
SwapFree: 9809132 kB
Dirty: 112 kB
Writeback: 0 kB
AnonPages: 532084 kB
Mapped: 44960 kB
Shmem: 7456 kB
Slab: 98232 kB
SReclaimable: 85304 kB
SUnreclaim: 12928 kB
KernelStack: 2616 kB
PageTables: 6432 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 11501332 kB
Committed_AS: 1298504 kB
VmallocTotal: 122880 kB
VmallocUsed: 70356 kB
VmallocChunk: 34300 kB
HardwareCorrupted: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 4096 kB
DirectMap4k: 36856 kB
DirectMap4M: 872448 kB


全然関係ないけど、bloggerにも「+1」ボタンが増えていますね。

2011年6月15日水曜日

TYPE_SYSTEM_ALERTでいつでも一番上


なんか震災から落ち着かない日々が続いていたので、
全然かけてなかったけど書くかな。

Dock4DroidとかWave Launcherなど、Androidにおいて、
すべての画面で例外なく一番上にUI部品を配置する方法についてメモを取っておく。

基本的には
http://harehare1110.blogspot.com/2011/04/android-view.html
を参照すればそのようなことができる。
でもTYPE_SYSTEM_OVERLAYを使うとキーイベントとかが全部捨てられてしまうので、
TYPE_SYSTEM_ALERTを使う。
http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html
にWindowManager.LayoutParamsの説明がある。

public static final int FLAG_LAYOUT_NO_LIMITS
Since: API Level 1
Window flag: allow window to extend outside of the screen.

とか試してないけど、面白そうなフラグもあった。

で、自分でも試したいので、サンプルを作った。以下に置いてある。
https://github.com/matsuhiro/TestForTYPE_SYSTEM_OVERLAY
気をつけるのは、
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
をManifestに書くくらいで、作ったソースのフラグとかは以下のよううな感じ。
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
    WindowManager.LayoutParams.WRAP_CONTENT,
    WindowManager.LayoutParams.WRAP_CONTENT,
    WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
    WindowManager.LayoutParams.FLAG_FULLSCREEN |
    WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
    PixelFormat.TRANSLUCENT);
  WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
FLAG_NOT_FOCUSABLEを入れてあげないと裏側の画面がうまく動かない。。。
でもAndroidってフォーカスが当たっているところにイベント配信する仕組みだったような??
InputMethodもViewキッカケだと起動しないみたいだし。
なんでもかんでも好きなようには出来ないかもですね(^^ゞ


調べてみて思ったのは、Dock4DroidとかWave Launcherなどのランチャーなら
こういった仕組みは便利だけど、それ以外だとちょっと使い道がなさそうということ。
今ランチャー以外で考えつくのは、C2DMとかのキッカケで全画面に
このようなViewを貼りつけて強制的に端末を操作不能にするとか?
うーむ。なんか危ないなこの仕組。
面白いけど、端末ベンダーの証明書で署名されていないアプリは
使えないようにしたほうがいいじゃねぇかな。