« 2010年1月 | メイン | 2010年3月 »

2010年2月

2010/02/28

Interface誌2010年4月号

Android特集だった。
配達ミスにより遅れてしまい、あせってしまった(CQ出版の方、ありがとうございます)。


他の雑誌と一線を画するのは、Androidアプリについて書かれていないこと。
一番アプリに近いのが、NDK。
あとは、このボードで動かすには、というような記事だ。
しばらく前に組込みLinuxの特集があったのだが、そんなイメージだ。
Android OSに深く突っ込むよりも、まずは動かせる環境について展開しているような感触を受けた。

ネットに出てる情報と差別化するのは、難しいのだろうなぁ。
私も記事が書けるほどの情報があればいいのに。

Javaのenum

アプリをやっているので、Javaのコードも書かねばならん。
どうも、慣れない・・・。

今回使いたかったのは、enum。


まず、Javaにenumはあるのか?から。
ある。
大昔にやったときは、ひたすらfinal使って書いていたような記憶があるが、まあ時代は変わるということか。

では使おう。

このソースでしか使わないから、privateでいいや。

private enum ETest {
ENONE,
EFIRST,
};

エラー。
どうやら、privateのenumはいかんらしい。
なんでだ?

eclipseがいうには、publicでなくてはならないらしい。
protectedもだめだった。
が、なにもなしは通った。
package公開(だっけ?)はpublic扱いということか。

定義の仕方は、C++と同じ。
typedefとかしなくても使えるので、Cと同じ、とは書かない。

では、使ってみよう。

ETest val = ETest.NONE;

これは、よし。
classと同じような扱いになるので、クラス名から書かねばならん。
これはC++と違うな。
C++はCの流れを引き継いでいるから、enumはenumだ。
もし同じようにしたければ、classかnamespaceにenum定義をすることになろう。
ただその場合も、enum名ではなくclass名で解決することになる。

では、switchさせてみよう。

switch(val) {
case ETest.NONE:
break;
case ETest.FIRST:
break;
}

エラー。
どうやら、ここのcaseでは、ETest.がいらないらしい。
何でだ??
valはETest型だから、省略できる、ならば理解はできる。
書くとエラーとは何事だ!

他と書き方を共通にしたいから、許してくれないかなぁ。

ブレゼンハムはいらん

  • 組込み
  • 直線

というだけで、無条件にブレゼンハムを使わねば!と思い込んでいた。

が、よく考えてみると、全然高速で計算する必要がない。
そうならば、実装が軽くなるように作る方がいいよな。

何というか、金槌を持ったら全部釘に見える、という言葉があるが、まさにそんな状況であった。
あぶないあぶない。

2010/02/27

まだgitに慣れん

Androidの本体は、repoとかgitとかで最新版ソースファイルを取ってくることができる。
非常にありがたい。

そのありがたさを十分に享受するには、取ってくるためのツールを使いこなさねば。
SVNはTortoiseSVNがあったからお手軽だったのだが、gitやrepoはコマンド入力のみだ(今のところ)。
まだまだ慣れていません。


バージョン管理ツールで慣れが必要なのは、

  • コミット
  • マージ

だと思う。

コミットは、分散型なので、ローカルにしか影響しないコミットが可能。
pushしない限り、本物のリポジトリには影響を与えないので、自分で修正した箇所はcommitだけさせておくとよいのだ。

マージで問題になるのは、コンフリクト。
自分の修正が本物のリポジトリによる修正とぶつかった場合。
SVNだと「コンフリクトしました」といわれて、「>>>」「===」「<<<」みたいなコメントが入ったソースファイルができあがる。
gitは?

ここを読むと、似たようなものみたいだ。
git-statusするとわかるようなので、pullして確認すればよいのかな。


eclairをrepo syncして新しくしたのだが、BT関係のところがビルドできない。

DEVICE_OUT_FM_HEADPHONEやらTTYやらが、ALSAの方には入っているのだけれども、eclairのframeworksに入っていないのだ。
確か、frameworks/base/include/media/AudioSystem.hだったと思う。
そのファイルだけ最新版に置き換えるとよかったような。

repo syncしてそれが消えてしまったのかいな。
今回は、BT側のソースを変更してビルドさせることにした。
commitしておけば、警告してくれると思うのだがなぁ。

ブレゼンハム

昔書いたような気がするけど、まあいいや。
眠たいのでね。


直線を描こう!

座標(x1, y1)-(x2, y2)に直線を引く。
数学ならば、傾きと切片がすぐに出てくる。

が、コンピュータで描くときにはそんな計算をすることは少ない。
なぜなら、計算が遅いからだ。
CPUの説明書を見てみるとわかるが、整数演算と浮動小数演算が同じ速度で実現できることはあまりない。
VLIWみたいなのだと得意なものかもしれんが、よくわからん。

とにかくまあ、整数演算の方が速い。
だから、可能な限り整数で演算させたい。
そんなこんなでブレゼンハムさんが考えた方式があるのだ。
よくできている。

コンピュータから見た直線というのは、隣り合うピクセルが8方向で接続している必要がある。
そこをうまく使っているのだな。


あまりに眠たいので、今日はここまで。
余裕があれば、自分でローカル変数を制限して試してみよう。

2010/02/26

AbsoluteLayoutしかない

いや、他に方法はあるのかもしれんが・・・。

私がやりたいのは、AnimationDrawableと自前のViewの併用。
ただそれだけ。
まあ、自前のViewで好きな座標にAnimationDrawableで描画させたい、というようなことを考えている。
それが全然解決できない。

最初は自前のViewを全面に貼り、そこにちんまりAnimationDrawableさせようとしていた。
が、ViewをFILL_PARENTにしておくと、キャラクターが全面に広がって表示されてしまうのだ。
描画のタイミングを遅らせたり、一時的に非表示にしてみるなどしたけど、表示させたときには大キャラクターが表示されていた(あ、キャラクターはPNGで作った画像ね)。
これを仕様としてアプリを作ろうかとも思ったけど、さすがにそれは技術者的に嫌だった。

昨日は、Marginを設定することでWRAP_CONTENTのまま描画位置を変更することができた。
では、この方向で・・・と思ったけど、Marginを動的に変更することができていない。
やり方が悪いのかもしれんが、もうわからん!


というわけで、今まで避けてきたAbsoluteLayoutに手を染めてみた。
非推奨だったから、わざわざ覚えなくとも・・・と思っていたのだ。

使ってみると、よかった。
何で最初に試さなかったの?というくらいに。
あっさり目的が達成できた。
私の1週間を返して・・・。

非推奨とはいえ、わかって使う分には問題がないと思う。
私だって、最初の方法がうまく行けばそっちの方がよかったのだしね。
AnimationDrawableは使い勝手が難しいわぁ。

2010/02/24

アプリは難しい

比較的、ドライバやらミドルやらをやることが多いためか、アプリは難しく思う。
使うAPIが多いし、想定せんといかん人も多い。
ドライバだと、ハードと上位層とOSくらい気にしておけばいいんだけどなぁ。
まあ、彼らがわがままでないというわけではないのだがね。

今アプリで困っていることも、アプリ慣れしている人だったらあっさりわかるのかも。
経験がものを言う気がする。
毛嫌いせずに、アプリもやっていかんといかんですな。

ええ、まだアニメーションがうまくいってませんよ。
AnimationDrawableをstartさせると、onDrawがその周期で自動的に呼ばれていた。
onDrawをオーバーライドして中身を空っぽにしたにもかかわらず、アニメーションするのだ。
そしてキャラクターを別の位置に移動させても、1つ前のキャラは消えてなかった。
ここはダブルバッファがきいていると言うことか。

推測をしておき、どういうことになっているかを考えるのもまた楽しいものだ。
解決するのが一番楽しいのだがね。

2010/02/22

Themeでフルスクリーンにする

themeと書いてテーマと読む。
いつも心の中では「てーめ」と発音しているのだが・・・。


今作っているアプリは、フルスクリーンにしたい。
タイトルバーもなく、ステータスバーもなく。
すべてを我が手に置きたいのだ。

ネットで調べると、だいたいこんな手順だった。

  1. getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
  2. requestWindowFeature(Window.FEATURE_NO_TITLE);
  3. 上記をActivityのsetContentView()より前に置く

手順という感じではないな・・・。まあいい。

しかし、別のことを調べているとき、Themeというものがあることを知った。
よく使うスタイルを標準とする、みたいなものかしら。
スキン、というほどではないが、「こんなテーマで描画してね」というくらいのものだろう。

そのテーマの中に「NoTitleBar」とか「NoTitleBar.Fullscreen」などがあることを知った。
どうやら、それでもいいらしい。
ActivityのonCreate()で指定してみるとうまくいかなかったが、AndroidManifest.xmlに直接書くとうまくいった。

なんだ、これでいいやん。

続きを読む "Themeでフルスクリーンにする" »

2010/02/21

AnimationDrawableがうまくいかん

まだアニメーションをやってうまくいってない。
いかんなぁ。


私がやりたいのは、そんなに難しいことではない。

・キャラクターがアニメーションする(パタパタアニメ)
・キャラクターが移動する

これだけ。

前回は、パタパタの部分をAnimationDrawableで、移動をTranslateAnimationで実現しようとしたのだった。
が、失敗した(but, in vain)。

ならば、めんどくさいパタパタはAnimationDrawableをそのまま使い、移動は自分でやろうというのが前回までのあらすじ。


移動させるには、自分で描画しなくてはならない。
というわけで、Viewを継承したクラスを作り、それをonCreate()で生成してsetContentView()させることにした。
そうすれば、ViewはonDraw()を使って好き放題できる。

持っている本ではShapeDrawableの例があった。
自作のViewクラスのコンストラクタでShapeDrawableをnewし、なんやかや設定。
onDraw()でdrawable.draw(canvas)で描画させている。
位置は、setBounds()で設定している。
うん、簡単簡単。

・・・確かに指定した位置に描画はしてくれるのだが、パタパタしてくれない。
start()の位置やタイミングが悪いのかとあれこれ試してみたが、だめだ。

現在は、コンストラクタでもう1つViewを作り、それをアニメーションさせようとしている。
そのViewにsetBackgroundResource()してアニメーションリストを設定後、getBackground()でAnimationDrawableを取得している。
サンプルではコンストラクタでShapeDrawableをnewしているが、そこが違うのかなぁ。
でも、意味としては変わらないと思う。

ちなみに、コンストラクタで作るViewではなく、thisに対して操作するとアニメーションしてくれる。
なんかルールがあるんかねぇ。

アニメーションでゴミが残る

実家に帰るつもりだったけど、思った以上に体が疲れていたのでやめた。

歳ですな。


Androidのアニメーションを試しているが、Translationなどで動かしたときにゴミが残ってしまうのだ。

  

わかりにくいかもしれないが、左図は画面左上が黒と白で点滅しているのだ。
(まあ、ここに載せているのは静止画だが・・・)
TranslateAnimationで移動させると同時に、AnimationDrawableで動かしてもいる。
そのせいで、最初の表示位置がブリンクしているのか?

右図は移動中の様子だが、ゴミを残しながら移動しているのだ。
移動のアニメーションが終わると再描画が走るようで、ちゃんとなる。
なるけど、やはり移動中も見えてほしくないですな。。。

現在対処中なので、何かわかったら書こう。


AnimationDrawableを止めてTranslateAnimationだけでもゴミが残った。
ブリンクの方はなさそうである。

TranslateとDrawableの開始順序を入れ替えてみたけど、関係なし。


解決その1

右図の現象、足跡が残る件がなんとかなった。
PNG画像の端っこまで画像を描いていたので、1pixだけ削ってみたのだ。
そうすると、残らなくなった。

けどさ・・・なんか納得はできない。
Tipsってやつなのか?
invalidateの領域判定が1pix小さいってことなのだろうか。

Javaの座標って、確かピクセルとピクセルの間を数える、みたいなのを大昔勉強したときに読んだような気がする。AWTの勉強だったか。
探したけど、見つからん・・・。
(sx, sy)-(ex, ey)で直線を引くと、終点は(ex-1, ey-1)までしか描画されない、とかそんな内容だったような。

試しに、1pixの真四角をアニメーションで移動させてみた。
予想通り、右側と下側の線が消え残っている。

というわけで、アニメーションさせる場合は、画像の右端と下側は1pix残しておくようにするのが無難、としておこう。


残件

TranslateAnimationとAnimationDrawableの組み合わせ問題が残っている。
書いていなかったが、実はTranslateAnimationで移動中、黒い塗りつぶしが広がっているのだ。
これはおそらく、

・TranslateAnimationは移動している領域のinvalidate領域を設定
・AnimationDrawableは移動していない領域(すなわち左上の原点付近)のinvalidate領域を設定
・領域がORされて、黒い塗りつぶしが広がっている
・AnimationDrawableは描画位置を左上と認識しているがTranslateAnimationによって移動されていて実際には描画するものがないため、黒いブリンクになっている。

ということではなかろうか。

そうなると、AnimationDrawableはTranslateAnimationと組み合わせられないことになってしまう。
なぜなら、TranslateAnimationは自動的に(勝手に)フレームワークがアニメーションさせることになっているからだ。
残念だなぁ。

android.view.animationの系列は、視覚効果的なものに使い、キャラクターを動かしたいというような目的では使わない方がよさそうですな。
手抜きができればよい、というところだったので、納得して使うのをやめよう。

続きを読む "アニメーションでゴミが残る" »

2010/02/20

[Q5]ファームアップデートについて考える

CoviaさんのBBSを見ると、ときどき「ファームアップデートに失敗する」という記事が出てくる。
頻繁に出てくるところを見ると、個人の技能的なものではなく、何かあるんだろうという気がする。

私のところでは、失敗したことがない。
失敗している人だと、
・SDカードを替えるとうまくいった。
・一度違うファームアップデートしてからだとうまくいった。
などがあったように思う。


SDカードの相性は、これはあると思う。
今の仕事でSDカードに関するテストをしていたのだが、SDカードではうまくいくがSDHCではうまくいかない、とか、SDHCでもこのSDHCはうまくいかない、とか、一度こうやってフォーマットした後にこうやってフォーマットするとうまくいく、とか。
なんかあるみたい。
私のお薦めは、一度WindowsXP(SP2以降?)でフォーマットした後に、Panasonicのフォーマッタでパラメータを変更せずにフォーマットする、だ。
フォーマット後のファイルシステムを見てみたのだが、BPBの部分などがMicrosoftでフォーマットするとこうなっている、みたいなものがあるようなのだ。
LinuxのVFATファイルシステムがどこを判断しているか調べていないのだが、FAT32の仕様書通りではなく、Microsoftのフォーマットを解析した作りになっているんではないかなー、という推測だ。
まあ、FAT32の仕様書をMicrosoftが出したのは比較的最近だったような気がするしね。

もしかすると、HPのフォーマッタだとうまく行きやすい、ということもあるかもしれん。使ったことないけど、BeagleBoardのSDカードフォーマット説明にはHPのツールを指定していたのだ。
BeagleBoardのPDFに書いてあるリンク先は切れていた。。。これでいいのかな?


気にしているのは、ファームウェアだ。
これはなんで発生するのだろう?

Covia版のファームは、SmartQ5というファイルをSDカードに置き、本体の+キーを押しながら電源をONすると始まる。
ちなみに、SDカードに置いたAndroidを起動させるときは、単に電源をONするだけだ。
だから、+キー押しというのは特殊な動作だろう。

Androidの起動は、内部的にはQi→uboot→kernel→init・・・となる(たぶん)。
ちゃんと調べるには、SmartQ5を分解して、UARTをとってこないとわからん。
SmartQ5のインストーラを調べたところからすると、単にcvkk-firmware-8MをFLASHに書き込んでいるだけだ。
その後再起動しているのだが、そこから先はわからん。
ただ、3つに分けて書き込んでいて、1つは/system、1つは/data、そしてcvkk-firmware-8M本体を2箇所に。
cvkk-firmware-8Mを解凍させると、kernelとか入っているので、参照するようにしているのだろう。
ここに、Qiやubootも入っているのかも。

これは、他のファームウェアアップデートも同様か。
SmartQ5としてはubuntuもあるので、そのファームを使っているとCoviaが想定しているファームと異なるのかもしれない。

そうならば、Covia版が想定しているファームウェアまで戻してやり、アップデートするとうまくいくかもしれない。
まあ、そのファームがどれか、というのが難しいところだがね。

続きを読む "[Q5]ファームアップデートについて考える" »

[Q5]SDカード起動版Android(再)

さて、Covia版Kernelを使って、SDカードからAndroidを起動させる方法をまとめてみよう。
長きにわたったため、情報が分散してしまったのだ。

Coviaさんの努力結果だけもらうようで気が引けていたのだけど、内蔵のiNANDが使いすぎで壊れてしまうというのも、哀しい。
長く使うため!ということで、少し省略したような形で載せておこう。

Coviaさんに感謝の意を示しつつ、以下を読み進めていただきたい。

【追記 2010/02/20】
最新版のファームウェアで動かなかった場合は、古いものを使ってみるといいかもしれない。
私は2009/11/30版での動作を確認している。


まず、いるもの。

  • SmartQ5ファームウェア
  • Linux環境(Ubuntuとか、VMwareとか)
  • u-bootのmkimage (apt-getする)
  • SDカード(私は16GBのを使っているが、2GBはほしいか)

こんなものか。
私は、WindowsXP+VMware(Ubuntu8.10)でやっている。
Ubuntuじゃないのがよかったけど、Androidの環境構築でそう書いてあったので、もうめんどくさかった。

※追記(2009/12/23 0:32)

mkimageは、ubuntuの場合はapt-getでできるようだ。

# sudo apt-get install uboot-mkimage


抜き取り

まず、SmartQ5ファームウェアからいろいろと取り出す。

記事 : [Q5]upgrade.sh

記事 : [Q5]SDカードからもブート

SmartQ5Extractorというツールを使うと、SmartQ5ファイルからいろいろと取り出せる。
いるのは、

  • rootfs.tar.gz
  • homefs.tar.gz
  • initramfs.igz

の3つ。

SmartQ5ファイルの構造

息抜き。
SmartQ5ファームウェアファイルには、いろいろ詰まっている。
解析するのは面倒なので、回答ツールを探してきた方が早い。中国語のツールだけど、使う分には何となくわかる。

でも、バイナリ好きならば自分で何とかしたいところ。
私は人が調べた情報を使う。

smartq-initramfs

ここが見つかったのが昨日なのだが、それまでは困り果てていたのだ。
ダウンロードしてfw-utils/firmware-headers.hを見ると、ヘッダ部の情報がわかる。

qi:56
u_boot:76
zimage:96
initramfs:116
rootfs:136
homefs:156

これがあれば、だいたい自動化できそうな気がする。

initramfsの解凍

記事 : [Q5]覚え書き

最初の2つはまあいいとして、initramfs.igz。
これは、initramfs形式をu-boot形式にしたもの。
initramfs形式は、CPIO+tgzだ。
u-boot形式は、ヘッダが64byteついたもの。

解凍スクリプト

#!/bin/sh
dd if=initramfs.igz bs=64 skip=1 > initramfs.img.gz
gzip -d initramfs.img.gz
mkdir initramfs
pushd initramfs
cpio -idm < ../initramfs.img
popd
rm initramfs.img

cvkk-firmware-8M

解凍したinitramfsの中から、ファイルを取り出す。

usr\cvkk\upgrade\firmware\cvkk-firmware-8M

SmartQ5Extractorにかけると、kernelを取り出せる。
SmartQ5をExtractorしてとれるkernelは、インストーラ用のkernelだろう。

ファイル名はzimage。以下ではzimage-cvkkとして使っている。

init、init.rc、init.smdk6410.rc

記事 : rootfsに関するある結論

これらのファイルは、動いているAndroidからSDカードにコピーするのが手っ取り早い。
cvkk-firmware-8Mを解凍したinitramfs.igzにはなさそうだ。
rootfs.tar.gzあたりに秘密がありそうだが、うまく解凍できない。

ここまで

ここまでで、SmartQ5ファイルなどから必要となるファイルは一式取り出した。


initramfs.igzの作成

ここからは、ほぼLinuxで作業する。
cygwinでもできそうだけど、不安なのでやめた。

initramfs.cpio.gzの作成

どこかにディレクトリを掘る。
そこに、init、init.rc、init.smdk6410.rcを放り込む。

ここの真ん中辺りにあるスクリプトを取り出し、実行できるようにする。
第1引数にさっき掘ったディレクトリを、第2引数に生成したいファイル名をつけて実行。

これで、initramfs.cpio.gzは完成。

initramfs.igzの作成

最初に言っておくが、igzという拡張子はSmartQ5Extractorがつけていたからそう呼んでいるだけで、正式ではないと思う。

さっき作ったinitramfs.cpio.gzにu-bootのヘッダを付ける作業をここでやる。
それには、u-bootのmkimageというコマンドを使う。

記事 : [Q5]やってしまった・・・

こんな使い方になる。

$ mkimage -A arm -O linux -T ramdisk -C gzip -n 'initramfs' -d initramfs.cpio.gz initramfs.igz

実際には、私はinitrd.igzというファイル名にした。ロングファイルネームは不安でね。


組み込む

menu.lst

title Covia
kernel /boot/zimage-cvkk
initrd /boot/initrd.igz
param nosplash
logo /boot/android.bmp4

zimage-cvkkは、cvkk-firmware-8Mから取り出したzImage。
こちらを使わないと、Coviaさんが対応してくれたドライバ類が入っていないだろう。
改行コードがLFのみとなるように気をつけよう。

SDカード

boot用にvfatを先頭に、swapに1つ、/systemに1つ、/dataに1つ。
4つパーティションが必要になる。
つまりまあ、これ以上は入らない。拡張パーティションはよく知らん。

パーティションは適当に。
オリジナル似合わせて、swapは128Mでよいのかな?
/systemは基本的に広がらないので、ぎりぎりのサイズでもよいか。
アプリは/dataに入るから、ここを大きく取るのがいいのでは。

編集

init.rcを書き換える。
mount先を変更。

mount ext3 /dev/block/mmcblk1p3 /system
mount ext3 /dev/block/mmcblk1p3 /system ro remount

mount ext3 /dev/block/mmcblk1p4 /data nosuid nodev


/system/etc/init.smdk6410.shでswapの設定をしているから、これも忘れないように。

mkswap /dev/block/mmcblk1p2
swapon /dev/block/mmcblk1p2


あとは、起動するだけである。

みんなできたかな?

[fyi]機能削減可能

機能の追加・削除(主に削除か?)するしくみを、OEFSがやってるらしい。

http://itpro.nikkeibp.co.jp/article/NEWS/20100219/344811/

こういうのがほしかったのだよ。
私もやろうとはしているものの、アプリレベルでしかできてない。
rilとか使わないけど、入れてるからなぁ。

リンク先に画面があったけど、WindowsCEのPlatform Builderみたいな画面だな。
こんなのがあると、どのファイルとどの機能が関係あるのか、などというのがわかるので、勉強中のみとしてはありがたい。
ああ、ありがたやありがたや。

続きを読む "[fyi]機能削減可能" »

2010/02/19

Javaには詳しくない私の疑問

1つ前の記事で、XMLファイルのonClick属性にメソッド名を書いておくと、ボタンを押したときに呼ばれる、ということを書いた。

さて、あれはどうやって実現されているのだろう?
Javaはコンパイルするとclassファイルになり、そこにバイトコードが書かれているイメージだ。
ただ、ここはAndroid。正確にはJavaではない。
最後にできるのも、dexだし。

だけど、私はJavaに詳しくない。
あなたに話すネタもない。。。

だが、確かJavaは関数名やファイル名をそのままclassファイルに格納していたと思う。
そのしくみがあるから、JUnitなんかも使い勝手よくできるとかなんとか。
携帯向けのJavaアプリでは、関数名などを短くすることでサイズを削減させるとか。
XMLファイルをうまくコンパイルしてやれば、同じことができそうな気がする。
つまり、onClick属性をclassファイルに落とし込む、というような。

しかし・・・私にとって、文字列で関数を扱うというのは気が重たい。
別に私が取り扱うわけではないのだが、「文字列を」「全文一致で検索して」「関数を呼ぶ」というステップになるのが重たいのだ。
だって、普通にアドレス呼び出しであれば、一発やん。
もし仮想関数だったとしても、2ステップ。
しかし文字列比較となると、文字数分を1文字1文字比較しなくてはならん。
頻繁に呼び出すような関数であれば、確実にボトルネックだよなぁ。

まあ、ここはボタン操作みたいなUIだからいいや、という判断なのかも。
それに、コンパイル時にハッシュ値とかに変換してるかもしれんし。
いや、変換してくれているに違いない。

そんなどうでもいいことを考える金曜日の夜であった。

Android1.6ではonClickListenerがこう書ける

備忘録だ。

以前に読むだけ読んで、記憶にはあったけど何のことか忘れていた変更点。


Android1.6からは、XMLのレイアウトファイルに

<Button android:onClick="myClickHandler" />

などと書いておくと、ソース上で

class MyActivity extends Activity {
public void myClickHandler(View target) {
// やること
}
}

書くことができる

GUIのエディタはここまで吐きだしてくれるかしら?

最近やってること

すごく眠い。
寒いし。
のんびり本を読みながら酒でも飲みたいわ。

というのが、最近やっていることではない。
まあ、やってることには違いないが。


SmartQ5を触るのは、しばらくやめている。
BeagleBoardもそのままだ。

やっているのは、アプリ側。
あまりに基礎的なことも知らないので、妨げになりつつある。
Activityはわかるけど、インテントはあやふやだし。
今まで作ってみたアプリも、画面遷移しないのでインテントがない。
すべてを理解することはできないだろうが、一通りの基本は触りたいものだ。

が、そんなに一通り触っていたら一生が終わってしまう。
並行して、アプリを実現している実装の確認もしていく。
取りかかったのは、ステータスバーの実現方法。
PNGファイルは見つかったので、そこから手を伸ばしていこう。

そう、私がやりたいのはUIに手を加えることなのだ。

2010/02/17

URLが変更になるらしいお知らせ

このブログは、JUSTBLOGというジャストシステムさんのサービスを利用している。

が、4月から別のところが運営することになるとのこと。

あらまあ。

せっかくURLを覚えてきたのに残念なことである。
これを機に、しばらくブログをやめるのもよいかもしれん。

2010/02/14

[BB]追加部品購入

ほとんど触っていないBeagleboardであるが、部品だけ買ってきた。

まずは、USBハブの電源つき版。
これがないと、USB機器を取り付けたときに電力が足らんこともあるらしい。
まあ、これはSmartQ5でも使えるから、BeagleBoard用というわけでもない。

マウス。
UIがないので、マウスやキーボードが必要になってくる。
USBキーボードはSmartQ5用に買っているのがあったけど、USBマウスはパソコンで使っている1つしかなかったのだ。
もちろん、有線で一番安いのを購入。といっても、ヨドバシなので千円したがね。
まあ、これも緊急用として使えるので、BeagleBoard用という限定でもない。

そしてUSB Etherボード。
何と呼べばいいかわからん。LANボードか?
とにかく、USBで使える有線LANボードだ。
これは・・・お金を払っていない。
実家で使っていないのがあったから、もらってきたのだ。
BuffaloのLUA2-TXというやつ。
ネットで検索すると、BeagleBoardで使えそうだ。
まあ、Linuxのドライバさえあればいいんだろうけどさ。


で、何かしているかというと、BeagleBoardには何もしていない。
Androidですら動かしていない。
ネットからダウンロードして、SDカードにコピーして動かしてみればいいんだけど、SmartQ5が落ち着かないとやる気になれない。

かといって、今はSmartQ5はちょっと停滞気味・・・。
copybitもうまくいかないし、networkもうまくいかない。
寄り道して、Homeアプリの解析などをやっているところ。
やり始めたら、本業が忙しくなってきてそのまま・・・。

あまりよくないですなぁ。

2010/02/13

アニメーション中の座標はたぶん取得できない

前回の続きだ。

あれこれ調べているものの、情報がない。
それに、APIもそれっぽいのがない。
clearAnimation()させても変なところで終わるし。

で、ようやくそれっぽい記述を見つけた。
Android Developpersの、Viewクラスに関するReference
Animationの項に説明がある。

When an animation is started, the framework will take care of redrawing the appropriate views until the animation completes.

アニメーションが開始したら、フレームワークは完了するまで再描画し続ける、といったところか。再描画の面倒を見る、とか。
フレームワークが面倒を見るのだから、アプリではたぶん手が出せないよなぁ。
そういう解釈をした。

まあ、気が向いたらソースファイルを眺めてみよう。
「気が向いたら」と書くときは、あまり気が向かないことが多いのだが・・・。

2010/02/10

アニメーション中の座標を取得したい

またしてもアプリ関係だ。
どうしたんだ、私・・・。

まあ、解決していないので問題提起だけだ。


タッチパネルをタッチさせると、タッチした座標に画像を表示させようとした。
ただ表示させても寂しいので、アニメーションでじりじりと移動させようとしている。

タッチイベントを拾うのは簡単。
タッチした座標まで移動させるのも、TranslateAnimationみたいなのを使って移動させられる。
アニメーション後に座標を元に戻すか留まらせるかも、指定できる。

が、アニメーションしている間はどうすることもできない。
例えば、ボタンをアニメーションして移動させても、移動中のボタンは押しても反応しない。
記憶によると、移動前の座標にまだあると判断していたと思う(これも設定次第かもしれん)。

今回、ボタンみたいに押して動作させたいというのはない。
ないのだが、移動中の画像をタッチしたときに止めたいのだ。
そしてその位置からタッチした場所に向かうよう方向転換させたい。

させたいのだが、よくわからん。
作戦を休みに練ろう。
そして今日は寝よう。

2010/02/07

画面サイズとアプリ

実家に帰っている間、ごにょごにょとSupporting Multiple Screensを読んでいた。
ネット環境がないと仕事がはかどりませんなぁ。
幸い、英和辞典があったので助かった。
やはり、紙の媒体も置いておかないと、いざというときに不安だ。

最初に言っておくが、これは私が読んだものなので、正確さには欠けていると思う。
自分で読んでほしい。


用語

  • スクリーンサイズ(Screen size)
  • アスペクト比(Aspect ratio)
  • 解像度(Resolution)
  • 密度(Density)
  • DIP(Density Independent Pixel)

スクリーンサイズは、画面の対角線の物理的な長さ。
これは、large、normal、smallに分類する。
largeは5インチくらい、normalは3~4インチくらい、smallは2.5~3インチくらい。

アスペクト比は、longとnot long。
これは長方形か正方形か、という意味か?

解像度は、width x heightのピクセル値。
しかし、Androidアプリは解像度では動かない・・・という訳でいいのか。
  appli do not work directly with resolution。

密度は、ピクセル密度などと書いた方がわかりよいのかな。
以下densityと書きます。
同じ面積でも、densityが低ければピクセル数は少なくなるし、高ければ多くなる。
UI部品の大きさをピクセルで指定すると、densityによって見栄えが変わってくる。
これは、high(hdpi)、medium(mdpi)、low(ldpi)に分類する。
highは240dpi、mediumは160dpi、lowは120dpi。

Android1.5までは、スクリーンサイズ3.2インチ、解像度HVGA(320x480)、をベースとしている。
分類で言えば、normal-mdpi。


単位として、dipというものがある。
上に書いている、Density Independent Pixel、つまり密度非依存ピクセル。
ピクセル値を直接指定すると、端末によって見栄えが変わってしまう。
それをDIPで指定することで、システム側にうまくやってもらおうということだ。

dipの基準は、normal-mdpi。
もし320dpiの環境で動かしたら、2x2=4倍のピクセル数が必要になる。
ということだろう。


で、だ。

結局のところ1.5で作ったアプリをどうしたらいいんだろう?
それは、最初に書いたURLの「Strategies for Legacy Applications」に書いてある。
読んでないけど。

今のところは、その手前まで何となく把握しているつもり。
マルチ対応とリソースの関係について。


訳に自信がないので、そのつもりで。

まず、端末のdensityを元にしてアプリのリソースを自動的に選択し、スケーリングせずに画面表示させようとする。
スケーリングする、というのは、拡大縮小のことだろう。
当てはまるリソースがないならば、デフォルトのリソースを読み込んで、現在の画面の汎用的なdensityでスケーリングしようとする。
デフォルトのリソースは、densityがmediumとして考える。

これが「1. Pre-scaling of resources(such as image asserts)」の部分。
続いて「2. Auto-scaling of pixel dimensions and coordinates」があり、最後に「3. Compatibility-mode display on larger screen-sizes」となる。

pixel dimensions、は何だろう。
次元、と訳すと変なので、寸法、なのか。
densityによる計算をしたらピクセルの大きさが出てくるので、そのことだろうか。

例が書いてあるので、いつか訳したいところだ。


アプリが複数サイズの画面に対応するかどうかは、AndroidのバージョンとManifestファイルによって決まるようだ(リソースもあるけど)。

Manifestファイルに<supports-screens>を置き、そこに「android:smallScreens="true"」などと書いていくことで、対応するかしないかが決まる。

「android:xxxxScreens」は、small、normal、largeの3つ。
デフォルト値は、Android1.5までは全部false。それ以降は全部true。
あ、全部falseと書いたが、normalはtrue。
このパラメータがtrueだとその画面サイズをサポートする、つまり表示させようとすることになる。
Android 1.5以前では、デフォルトでnormalのみtrueとなるので、大きい画面要アプリだと表示されないことがあるのだろうか。
でも、SmartQ5は4.3インチでWVGAなので、large-hdpiに相当しそうな気がする。4.3なので、ぎりぎりnormal-hdpiかもしれんが。

表を見る感じでは、これからはnormalでmdpiとhdpiに対応するといいんではなかろうか。
ターゲットが決まっているのなら、そのリソースだけ用意すればいいと思う。
デフォルトのリソースさえ用意しておけば、少なくとも表示されないことはないだろう。


サンプルを見ている感じからすると、

  • layoutはport(縦長)とland(横長)
  • drawableはmdpiとhdpi

としておけばいいんでないかしら。
共通で使えるものは、デフォルトリソースへ。

2010/02/06

仕事でソースを見ると

今日も何もしてない。

今週から仕事でソースファイルを見ることになった。
今までは別作業だったので、全然そんなのをしてなかったのだ。

そうするとだな、家に帰ってソースを見る意欲が下がることがわかった。
意欲というか、家に帰ってまで見なくとも、というか。
目が疲れているだけかも・・・。

週末は実家に帰るので、ドキュメントを読むことにしようかね。
本を読みたいところだが、読んでおきたい英文があるのだ。
というと格好がいいのだが、Androidの画面サイズに関しての文章が英文だったので仕方なく。
月に1回はプリンタを使うようにしているので、わざわざ印刷したのだ。
実家ではネットにつながらないのよねぇ。

早く、全国に高速ネットワーク回線が使えるようになるとありがたい。
WiMAXでもいいんだけど、まだ来ないんだよなぁ・・・。

2010/02/04

[Q5]アプリ画面が小さい

あまりSmartQ5とは関係ないのだが、SmartQ5で動作させたときのことなのでそうしておこう。

似たようなアプリを2つ公開している私。
怖さなどをアピールしたアプリは数多くあるが、威嚇をアピールしたアプリは世界初ではないか?
威嚇が地球を救うかもしれない。
かといって、威嚇と恫喝を一緒にしてはいけない。
真の威嚇とは、相手に危害を与えることなく、自分に危害を与えさせないようにすることである。
そして、自分が強いならば威嚇はしない。それは恫喝だ。
このアプリを見て「威嚇とはどうあるべきか」を考えてほしい。

・・・すまん、適当なことを書いた。


とにかく、そのアプリをeclairを移植したSmartQ5で動かした。
SDKは1.5だ。
rotatorに対応していないのでSmartQ5は横画面しか出せないのだが、アプリ画面が小さい。
QVGAくらいになってそうなのだ。

画像が回転するため、画像の中心座標なんかは相対的に指定することはあるが、画面全体のサイズなど考慮していなかった。
していないというよりは、QVGA以上なら収まるだろう、というくらいにつくっていたのだ。
背景色を白のみにしているのも、そんな理由(だったと思う)。

しかし、SmartQ5で動かすと、アプリ画面以外の部分が黒いのだ。
もちろん、黒い部分には何も表示されない。
うーむ。

FILLにしているので画面全体を使ってくれると思っていたのだが、何かしないといかんのか?
AndroidのSampleにあるHomeも同じになったし。
待受アプリを作ってみようとしているからには、それくらい何とかしなくては。

ここ は読んでおかねばなるまい。

2010/02/03

[Q5]libを置き換えてもだめ

安直な解を求めたい場合もあるが、それを意図したわけでもないと言うことがある。

何かというと、昨日copybitが動かなかったので、Covia版の/system/libをまるまる私がビルドしたものに上書きしたという話。
それで動けばいいや、とも思うし、置き換えて動くのならばライブラリの問題だけということもいえる。

後者かどうかを見極めたかったのだが、安直と言えば安直。


そしてまあ、だめだったのだけどね。

E/AndroidRuntime( 694): Unable to register all android natives
I/ServiceManager( 625): service 'media.audio_flinger' died
I/ServiceManager( 625): service 'media.player' died
I/ServiceManager( 625): service 'media.camera' died
I/ServiceManager( 625): service 'media.audio_policy' died
I/ ( 695): ServiceManager: 0xad08

Audio関係がだめになった。
ここは、AndroidRuntimeが起動してすぐだ。
自分でビルドしたものだと、こんな感じ。

E/ALSALib ( 640): external/alsa-lib/src/control/control.c:909:(snd_ctl_open_noupdate) Invalid CTL AndroidOut
W/AudioHardwareALSA( 640): Unable to attach mixer to device AndroidOut: No such file or directory
E/AudioHardwareALSA( 640): Unable to attach mixer to device default: No such file or directory
E/ALSALib ( 640): external/alsa-lib/src/control/control.c:909:(snd_ctl_open_noupdate) Invalid CTL AndroidIn
W/AudioHardwareALSA( 640): Unable to attach mixer to device AndroidIn: No such file or directory
E/AudioHardwareALSA( 640): Unable to attach mixer to device default: No such file or directory

ALSAが動いてなかったので、そのままエラーで進んでいったというところ。
グラフィックがSurfaceFlingerならば、音はAudioFlingerなのだな。

flingerって何だろうかと思ったら「蹴る癖のある馬」らしい。
ピッチャーとか投げる人という意味もあるようだが。
いや・・・普通に考えれば、後者か。
ハードに向けて指示を投げる人、とかか?

今のところ、自分でビルドした環境ではFlinger系はうまく動いていないな。
そこがやはり、企業と本気さが違うということか・・・。

2010/02/01

[Q5]Covia版Eclair

Coviaさんのところから、SmartQ5のEclair試作版が出ていた。
試作版を出せるところがいいですな。

試してみたが・・・やはりできがいい。
私のとは比較にならん。
当たり前といえば当たり前なのだろうが、なんかショックだ。

一番の違いは、グラフィックだろう。
まだWVGAには対応していないのだが、軽い。
その次は、ネットワーク。
ちゃんと無線LANがつながりそうだ(接続までは試してないけど)。
悔しいなぁ。


あまり深く考えていなかったのだが、EclairはAndroid2.0らしい。
今のSDKで出ている最新版は、2.1。
android.git.kernel.orgを見てみよう。
ここでは、tagsとheadsという単語が出てくる。
-bオプションで使っている名前は、headsにある。
だから、headsがブランチのことなのだろう。

frameworks.gitを見てみると、commitコメントに「android-2.1_r1 snapshot」と書かれている。
ということは、最新のeclairブランチは、Android2.1R1なのかしら。
コメントの横に「eclair」って緑色の枠が出ているは、「これが最新のeclairでとってこれるものですよ」という意味なのか。


さて、私も悔しがっているだけではだめだ。
活用できるところをもらわねば。

まずは、copybit。
構造体が変わったせいか、Cupcake版のものが使えないのだ。
昨日までがんばってみたが、どうにもだめ。
もちろん私は、Covia版のcopybitをいただいたってわけさ。
いくつかまつわるlibも一緒にコピー。

動いた!
と思ったが、もっさり。
なんでだろうと思ったら、egl.cfgがないせいか、stretchに失敗。
ならばとegl.cfgをコピー。
中を見るとfimgなんてことが書いてあった。
同じ場所に、fimgなんとかってライブラリもある。
えーい、まるごとコピーしてしまえ!

・・・動かなくなった・・・・・・・。
egl.cfgを置くことでfimgを使うようになったのだが、fimgがChunkAllocというのを使っているみたいなのだ。
これも同じディレクトリに置いているのだが、なぜか見つからないといわれる。
アクセス権もフルにしたし、そんな問題ではないのか・・・。

E/libEGL ( 650): load_driver(/system/lib/egl/libEGL_fimg.so): Cannot load library: link_image[1721]: 628 could not load needed library 'libChunkAlloc.so' for 'libEGL_fimg.so' (load_library[1051]: Library 'libChunkAlloc.so' not found)

kernelを置き換えてみるといいのだろうが、そうすると前回のchrootみたいなことをしなくてはならん。
つまり、/systemと/dataをまとめた1つのパーティションを作らねば。
ああ、昨日のまま放置しておけばあっさり試せたのに・・・。

などと繰り言は言うまい。
明日だな、明日。