2011/09/30

[pasori]NfcPcdライブラリの説明 (2)

https://github.com/hirokuma/NfcPcd

 

それでは、続きを。
見られてなくてもいいんだ、いいんだ。。。


このライブラリの特徴は、FeliCa Liteの片側認証をサポートしていること。
SONYさんのサイトにある、FeliCa Lite 個別化カード鍵標準生成アルゴリズムに対応したのだ。

http://www.sony.co.jp/Products/felica/business/tech-support/index.html#Lite04

24byteの個別化マスター鍵から、カード鍵CKを作り出すのだ。
当然、MACの計算もするので、片側認証もできる。
そのためには1次発行もしないといけないので、それもサポート。

ただ、1次発行をきちんとするとFeliCa Liteのシステムブロックに書き込みができなくなるので、ソース的にできるところまでしか実装していない。

 

片側認証をサポートすると、PaSoRiでカードエミュレーションしてIDmやデータ部を偽装できても、CKまでは難しい。
もちろん、カードを入手して、ランダムチャレンジを繰り返せば、そのカードのCKを得ることはできる。
が、各カードでCKが異なるので、被害があるのはそのカードだけに抑えられる。
(全カードでCKが同じなら、発行済みのカード全てが危険にさらされる。)

 

FeliCa Liteにそこまで求めるのか?と言われると困るのだけど、少なくとも「手持ちのFeliCaカードが家の鍵になります」よりは安全だろう。
携帯電話に専用アプリをインストールするタイプならまだしも、どんなFeliCaカードでもOKってことはIDmくらいしか見ないと考えてよいのではないだろうか。

 

と思ったが、FeliCaを使うサービスのセキュリティをSONYさんがチェックしないことはあり得るだろうか?
私が考えつくことくらい、ふさがれているような気がする。
まあ、そっちの方がいいんだけどね。

2011/09/29

[pasori]NfcPcdライブラリの説明 (1)

https://github.com/hirokuma/NfcPcd

 

私にしてはがんばって作った、PaSoRiをAndroid 3.1以上で使うためのライブラリ。
ちょいと説明をしておこう(といいつつ、「1」なんて書いてしまった)。
もしかすると、使ってくれる人がいるかもしれんし・・・。


私が知らないライブラリを使うときに知りたいのは、どのくらい何をせんと動かないの?だ。

https://github.com/hirokuma/NfcPcd/blob/master/sample/src/com/nfcpcdsample/MainActivity.java

ソースファイルとしては、これくらい書けばとりあえず動く。
このソースは、ボタンを押すとNFC-Fとしてポーリングして、それでだめならFeliCaとしてポーリングして、それでもだめならNFC-Aとしてポーリングする、ということをやっている。
ポーリングするとIDmなりUIDなりが取得できるので、それを出力した後、搬送波を停止させている。

 

Android3.1以上にある「USB Host」機能を使っているが、そこはcom.blogpost.hiro99ma.pcd.UsbHostというクラスに処理をまとめて、あまり手間がかからないんじゃないかな、と思うようにしている。
なので、USB挿抜に関するListenerをimplementsせんといかん。
挿入は、実は通知がないみたいだ。

 

com.blogpost.hiro99ma.pcd.UsbHostでやっているのは、インテントフィルターの登録などだ。
もう少し融通が利いた方がいいのかもしれんが、よくわかってない。
 
とりあえず動かしてみよう、であれば簡単だと思うが、どうだろうねぇ。
 

2011/09/27

[C++]参照もforward classでOKなの?

Qtの魅力は、画面作成をGUIでできることじゃなかろうか。
昔の私は「GUIで作ると汎用過ぎて描画が遅くなるじゃろう」と相手にしなかったのだが、歳をとった。
作りやすさと、メンテナンスの容易さ、そして組み込み機器の高速化など、いろいろな要因があるのじゃ。

 

まあ、それはいいや。

 

Qt Labのページを見ながら、ブラウザを作ってみた。
うん、書いてあるとおりにやるだけでたいがいのことはできそうだ。

さて、ここでURLを扱うQUrlというクラスを扱う必要があった。
引数なのだが、参照型だ。

func(const QUrl& url)

こんなの。
説明には「class QUrl; がいる」とあるのだが、ポインタならまだしも、参照も同じようにやれるのか?

まあ、やってみると確かにそうだった。
参照って、どういう解決のされ方をしてるんだろう?

ポインタの場合、引数はアドレス値を渡すだけだから、ポインタ型の一般的なサイズさえわかればいい。
だから名前解決するだけのforward class(クラスの前方参照、という訳でいいのか?)でよいのだ。

実体の場合、コピー渡しになるので、classのサイズがわからないとスタックを使う量が決まらない。
なので、includeが必要になる。

参照は、既に存在するメモリをそのまま使うので、スタックは必要ない。
そういう意味ではポインタと同じような扱いになりそうだ。アドレスを渡す必要もないけど、結果としてはアドレスなのかな?
あるいはレジスタでそのまま・・・とかはコンパイラレベルの話になりそうだ。

気にはなるが、もう寝よう。

2011/09/25

[a500]フレキを修理してみよう

SANY0001

 

断線が確認できるのは、丸で囲んだところ。

これ以上引っ張り出せないので、このままやらんといかん。
うーん、難しい・・・。

このフレキは、LCDコントローラっぽいところにつながっている。
ピン数は8本なのだが、そのうち3本がつながってて太い線になっている。
ってことは、たぶん8bitデータバスになっていて、下位3bitはいらない(5bit制御?)ってことなのだろう。

 

いや・・・もっと冷静に考えねば。
普通は一番太い線はGNDではなかろうか。
いやいや、そもそもそんな推測をするよりも、全部ちゃんと接続しないといかんだろう。
ここで手抜きをしても意味がない。

ないけど・・・大変だ・・・。

2011/09/24

[a500]フレキの位置が悪いこともいいたい

確かに、私はフレキに圧迫をかけ過ぎた。圧迫祭だった。
しかしこの構造はどうなの?と思う。

 

lcd

私が見たとき、すでにこんな断面だった。
作ってる側もフレキの折り曲げ部分が気になっているのだろう、補強したりしていた。
私のA500は、フレキの上にカプトンではなく黒いビニルテープみたいなものがあったのだが、なんとなくはがしそうになった形跡が見えた。
これはもしかすると、工場の人が作ったときに「まずい」と思って、ちょっとはがそうとした形跡じゃなかろうか。
まあ、蓋を外した時点でそういう推測がもう無意味なんだけどね。

フレキを折り曲げるとき、間に丸い棒みたいなものがあればここまでひどく折れ曲がることはないと思う。
けど、それをやるとコストが高くなるし、そもそも工場でそれをやるのは難しかろう。
そんなわけで、これは設計が悪いといわざるを得ない。

安いから仕方ないんだよ。
私が不良品扱いにしなかったのが悪かったんだ。
それはわかっているんだけど、もうちょっと製品の品質は高いと思ったんだけどなぁ。

[a500]反省の弁

買ったものを分解するのは、仕方ないことだ。
たくさんのものを分解し、たくさんのものを壊してしまっている。
しかし、壊した分、知識も増えていったと思う。
仕事で壊すより、自分のものを壊した方が精神的にもいいしね。
(いや、よく壊すけどさ。。)

 

さて、今回A500の液晶を使えなくしてしまった件の反省をしよう。

まず1つ思いつくのは、紙を挟むという考えが安易すぎたこと。
なぜフレキの上に紙を挟もうと思ったかというと、フレキを押すとバックライトがちかちかしたからだ。
よくわからないが、きっと圧迫される力が変化しないようにすればいいと思ったのだろう。
そして、それは最初うまくいったのだ。
しかし何度も蓋を付けたり外したりしているうちに、紙がフレキを押したり離したりして、負荷が高くかかってしまったのだろう。

いつしか、フレキは切断されてしまった。


しかし、私はフレキに詳しくない。
もしかすると、切断されていないのかもしれない。
それに、切断されているのならば接続すればいいじゃないの。

さっき、全部分解して、見た。
フレキの接続は私には厳しい。
液晶と切断の部分が近くて、どうしていいかわからん。
本数は少ないのだけど、ここは技術のなさが哀しい。

本体側っぽい基板とLCDとは、なんか太めのケーブルで接続されている。
ここが大丈夫なら画面は出そうな気がなんとなくするなあ。
もしフレキがバックライトの制御しかしていないのならば、本数が少ないのも頷ける。
LVDSはシリアルだから本数が少ないのだろうと思ってたけど、バスで照明レベルの制御をしているとか。

 

まあ、わからんけどね。
とりあえずヤケ酒を飲もう。

[a500]やはり初期不良で修理すべきだった・・・

液晶のバックライトが、A500の持ち方によってちかちかする。

まあ、それくらいだからいいと思っていたのだが・・・。


ネットの情報を見ながら、分解。

きっと、バックライト部分の接触が悪くなっているんだろう、くらいの気持ちだった。
分解は比較的簡単で、精密ドライバ2本でできた(少し傷はついたが、あまり気にしない)。

「持ち方によって」というのは、A500を電源ボタンを上にして持った場合の左下、USB付近の押さえ方次第なのだ。
なぜか、そこに力を軽くかけるだけでバックライトの付き方が変わる。
不思議なものだ。

分解してみると、そこにはUSBのコネクタしかない。
やはり押すとちかちかするし、USBのコネクタを外すと押してもどうもない。
しかし・・見たところUSBが関係していそうにない。

その下を見ると、保護テープっぽいものが少しめくれていた。
そこには、フレキがあった。
フレキを押すと、ちかちかしやすい。
うーん、フレキの接触不良は手が出せないな・・・。

圧迫しにくいように紙を挟んでやると、なんかよさそうだ。
よさそうだった。

その程度にして、さっさと蓋をつけなおした。


蓋をつけると、SDカード部分を覆うカバーが動かなくなってしまった。
どうやら、蓋に押さえつけられてしまったようだ。

しかたないので、蓋をまた外して、つけて、を3回くらい繰り返して、なんとか動くようになった。

そして電源を入れると・・・画面が表示されない・・・。
緊急事態だ。

きっと、蓋を外すときに精密ドライバで切ってしまったに違いない、と思ったのだが、どうもそうでもない。
紙を置いたフレキは、よく見るとL字になって角に沿っているのではなく、まったく折り曲げられているようなのだ。
そこに紙を置いて圧迫度が増してしまったために、完全に断線してしまったのではなかろうか。

とにかくまあ、広い液晶画面が使えなくなってしまったようだ。


HDMI出力は有効で、今はテレビに映し出して使っている。
マウスとキーボードが使えるので、そこまで困らないかもしれないが、効率は悪いな。

SDK for NFC Starter Kitを試す

3連休なので(といいつつ、昨日は仕事だったのだが。。)、SDK for NFC Starter Kitを試してみた。
SDK for NFC Starter Kitはこちらから。

作ったサンプルは、githubに置いた。
やるのは、Type-AとFeliCaのUIDを表示するだけ。

https://github.com/hirokuma/Felica1

こんなので正しいんだかどうだか・・・。


C#で作ったのだが、いろいろと手間がかかった。

サンプルをそのままビルドさせても動かなかったが、これは開発環境が推奨されているものじゃないからかも。
うちは、Visual C# 2010 Expressでやっているのだ。
DllImport周りに設定が必要だった。

C#でのメッセージ受付がよくわからずに困ってた時間が長い。
単にHWNDの取得方法を間違ってただけだった。

よくわからないのが、felicalib_nfc_stop_dev_access()直後にfelicalib_nfc_stop_poll_mode()を呼ぶと固まってしまうこと。
間にsleepを挟めばなんとかなったのだが、stop_dev_access()が非同期なのかな?

2011/09/20

No funciona

SDカードなどのmount/unmountを実施するEjectSDアプリ。
昨日はアイコンだけ(機能に変化無し・・・)でアップしたのだが、コメントが増えていた。

 

No funciona en galaxy s

 

どうやら、GalaxySでは動きません、というスペイン語らしい。

スペイン語を1つ覚えた(のか?)のはよかったが、動かんのか・・・。

 

持っていないので確認できないのが困ったところだ。
まあ、まずは先にアイコン再描画を考えた方がいいのかもしれんが、別のこともやりたいしなぁ・・・。

2011/09/19

署名用のPK8とPEMをつくる

keytoolでつくったkeystoreからpk8とpemをつくろうとしたけど、断念した。
opensslを使って変換させたりしたけど、どうもうまくできていないようだ。

もう、keystoreは忘れよう。
eclipseでやるときはkeystoreを使い、Android.mkでやるときはpk8とpem。
割り切ろう。


pk8とpemを作るのに、スクリプトを作った。
コマンドを打ち込むだけだと、忘れるからファイルにしてしまうのだ。

#!/bin/sh
development/tools/make_key foobar  '/C=JP/ST=nnn/L=mmm/O=xxx/OU=yyy/CN=zzz’

こうすると、foobar.pk8とfoobar.pemができるので、build/target/product/securityにコピーする。

Android.mkに追加。

LOCAL_CERTIFICATE := foobar

これだけ。
いつものようにmmなどでビルドすると、out以下にapkがコピーされる。
そのときには、すでにfoobarで署名済みだ。

make_keyするとき、パスワードはつけない方がいいかも。
署名時にキー入力を求められるので、mでビルドさせたまま外出、なんてことができなくなりそうだ。

AppWidgetのアイコンは難しい

あれからEjectSDのアイコンを描き続けているが・・・難しい。

アイコンの中に文字を入れる

画像として文字を入れてしまうと、dpiの違いによって文字がつぶれてしまう。
それよりなにより、読みにくい。
うまい方法はあるのかもしれんが、私の技術では無理だ。

周りとバランスがとれない

アイコンだけ描いていて「おっ、これでいいかも」と思って実機で動かしてみると、アイコンが浮いて見える。
Androidのアイコンルールに従ってみたつもりなのだが・・・。
ようやく気づいたのだが、周りはアプリのショートカットなので、アイコンの下に文字があるのだ。
私はアイコンだけで、しかもfill_parentしているので、枠いっぱいに画像が広がっている。
だから、バランスがあわないのだ。
アイコンをアプリのショートカットに近くするなら、文字を下に入れた方がよい。
そうでなければ、枠をきっちりつくってしまうか、枠がまったくなくてアイコンがあるような形がいいのかも。
意識してアイコンをみてみるように心がけようかね。

2011/09/18

AppWidgetにアイコンを表示させたいときは、大きめにするか、fill_parentにするのがよさそうだ

以前作ったAppWidgetのEjectSDは、アイコンを作り直そう。
そう思ってあれこれやっている。

まあ、デザインどうのこうのは、もうあきらめよう。センスの問題だ。
今気にしているのは、アイコンのサイズ。
これは技術でカバーできる話だ。

 

なにかというと、A500にAppWidgetを表示させた際、アイコンが小さくなってしまうのだ。
しかも、寄ってる。。。
これは確かに、イマイチといわれても仕方あるまい。


EjectSDは、おおきさが1x1だ。
本によると、1x1のAppWidgetは72x72[dp]とのこと。

dpは「density-independent pixel」ということで、とにかく160dpiの場合に1dp = 1pxという関係になるとのこと。
A500は、画面は広いけど160dpiだ。
リソースなら、res/drawable-mdpiを使うのかな。

そう思って、ldpi、mdpi、hdpiのためにそれぞれ36x36、48x48、72x72のアイコンを用意した。
が・・・アイコンは小さい。

じゃあ、とldpi、mdpi、hdpiをなくして、drawableに72x72pxのアイコンを作った。
が・・・これも小さい。
なんじゃこりゃ?


アイコンをどうやって表示させているかというと、ImageViewにsetImageViewResource()を使って貼り付けているだけだ。
ImageViewにサイズ指定なんてしてないのになあ、と思うと、ガイドラインがあった。

縦置き(portrait)と横置き(landscape)で違うのか・・・。
デザインについては、知っておかないといかんことがいろいろあるんだなぁ。

それはともかく、今は縦画面で確認しているので、AppWidgetとしては80x100pxだ。
作ったアイコンは、72x72だからこれよりも小さい。
そして小さいまま表示されるのだから、アイコンの拡大なんかはしないみたいだ。

では、大きいアイコンだったらどうなる?
512x512pxのアイコンにしてみると、AppWidget1つ分の枠にみっしり入って表示された。
横画面にしても、みっしりだ。
ということは、縮小はしてくれるらしい。
ImageViewの指定がwrap_contentだからか?

fill_parentにして72x72アイコンに戻すと、みっしり表示された。
なーんだ、そういうことか。
そんなわけで、AppWidgetにアイコンを表示させるときは、wrap_contentにしてアイコンを大きめに作って縮小してもらうか、fill_parentにしておくのがよさそうだ。
デザインのどこをいじるとどうなるかわかってないので、時間がかかって仕方がない。

2011/09/17

Android 3.1以上でPaSoRiを動かせそうなライブラリを公開

JavaもAndroidもFeliCaもNFCも、なんとなく中途半端な知識しかない。
ないのだが、せっかく作ったので公開してみたくなるのは仕方ないだろう。
githubに、Android 3.1以上でPaSoRiを動かせるんじゃないかな、と思うライブラリを公開しました。

git clone git://github.com/hirokuma/NfcPcd.git

 

ProGuardをかけてみたので、うまく動くかどうかわからんです。


プロジェクトの設定で、ライブラリを追加

Java Build Path > Libraries

libnfcpcd.jarを追加。

 

AndroidManifest.xmlに、以下が必要。

manifest内

<uses-feature android:name="android.hardware.usb.host"></uses-feature>

activity内

<intent-filter>
    <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>

<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/device_filter" />

 

ソースファイルにも手が入る。

Activityソース

Activityクラスに「implements com.blogpost.hiro99ma.pcd.UsbHost.UsbListener」を付ける。
USB挿抜検知用(動くと思う)。

eclipseでやっていると、メソッドが足りん、といわれるので、いわれるままに追加。

@Override
public void inserted() {
    // 挿された!    
}
 
@Override
public void removed() {
    // 抜かれた!
}

やってみたけど、挿された方はうまくいかんかったです。

onCreate()で、UsbHostのonCreate()を呼んでやるのも必要。

・・・
説明が面倒になったので、サンプルも置きました。
はてさて、どうなることやら。

[ビルド]antとProguard

過去記事:2010/09/23 16:53


「俺はミドルなんて知らねえ! アプリに生きるぜ!!」という方もおられよう。

私はeclipseが、というよりも、eclipseの自動補完とかがないととてもJavaでアプリを作ることができない。
Ctrl+Oがなかったらと思うと、そら恐ろしい。

ただ、eclipseなしでも、コマンドラインから開発はできる。
つまり、ビルドできる。
今日のAndroid Developer Blogに、Proguardを使う場合にはコマンドラインでビルドせんといかん、とあったので、Proguradはやってないけど(やれよ)コマンドラインでのビルド手順を書いておこう。

今回はWindowsでやったので、コマンドプロンプトは「>」です。



まず、プロジェクトの作成。

の前に、自分の環境を知っておこう。

> android list targets

これで、自分がビルドできるターゲット一覧が出てくる。

うちは全部はインストールしていないので、こんだけだ。

いるのは、赤文字の部分。
プロジェクト作成字に指定するのだ。

Available Android targets:

id:
1 or "android-4"

     Name: Android 1.6

     Type: Platform

     API level: 4

     Revision: 3

     Skins: HVGA (default), QVGA, WVGA800, WVGA854

id:
2 or "android-8"

     Name: Android 2.2

     Type: Platform

     API level: 8

     Revision: 2

     Skins: HVGA (default), QVGA, WQVGA400, WQVGA432, WVGA800, WVGA854

id:
3 or "Google Inc.:Google APIs:8"

     Name: Google APIs

     Type: Add-On

     Vendor: Google Inc.

     Revision: 2

     Description: Android + Google APIs

     Based on Android 2.2 (API level 8)

     Libraries:

      * com.google.android.maps (maps.jar)

          API for Google Maps

     Skins: WVGA854, WQVGA400, HVGA (default), WQVGA432, WVGA800, QVGA


> android create project --target "android-8"
   --name AntTest --path .\AntTest --activity AntTestActivity
   --package jp.typepad.hirokuma.AntTest

 

長いので改行させたが、本来は1行で書く。
実行すると、

  • --targetで指定したターゲット向けに、

  • --nameで指定したプロジェクト名で、

  • --pathに指定したディレクトリを作成し、

  • --activityで指定したアクティビティ名の、

  • --packageで指定したパッケージで

プロジェクトを作成する。

--targetは文字でなく数字でもよい。

あとは、できたディレクトリに移動して、ビルドするだけ。

> cd AntTest

> ant

お手軽。



eclipseで作ったプロジェクトと違うのは、たぶんbuild.xmlというファイルが作成されることだろう。

これに従ってantはビルドしているようだ。
たぶん、Proguardを使うときは、build.xmlに細工をするのだろうな。

「もう既にeclipseで作ったプロジェクトをantでビルドしたいんだけど…」という場合が、たぶんAndroid Developer Blogに書かれている方法だな。
うん、そうだ。
ant releaseとすると、ビルドできるな。

なになに、local.propertiesというファイルもできるので、そこにkeystoreとかを登録しておくと署名済みのapkファイルができるだと?

これも試しておくか・・・。

Windowsの場合は、パスのデリミタが\\となるので注意が必要だな。

ファイルのパスを取得することが多いので、ツールを入れておくと便利。

私はFileMenu Toolsというものを使っている。

Explorerの右クリックで「ファイルパスをコピー」ということもできるのだ。

local.propertiesを編集してからant releaseすると・・・
おお、パスワードを訊かれるようになった。
打ち込むと(「***」とはならず、普通の入力なので注意)、できたような気がする。

むむ、ちょっと待て!

2回パスワードを訊かれたので、打ち間違えたのかと思っていたのだがそうではない。

1回目はkeystoreのパスワードで、2回目はaliasのパスワードだ。

そして、keystoreのパスワードが違うとビルドエラーになるのだが、aliasの方は特に文句をいわれない。

そんなものなのか・・・?

> jarsigner -verify -verbose -certs XXX.apk

とすると、署名済みかどうかわかるそうだ。

署名はできていたのだが、aliasのパスワードは、そのときに付けるものなのか?

いや、eclipseからやると確認されるな。

うーむ。。。
まあいいや。

 

local.propertiesにProguardをインストールしたパスを追加。

パスは、proguard.jarの入っているlibまでを書かねばならん!

気付くのに時間がかかったわい。

 

次は、2つのファイルをサイトからダウンロードして、build.xmlと同じ場所に置く。

最後に、build.xmlへの編集が必要。

先頭の<?xml・・の次の行に追加。

<!DOCTYPE project [

       <!ENTITY add-proguard-release SYSTEM "add-proguard-release.xml">

]>

<project name・・・の次の行に追加。

&add-proguard-release;

これで終わりらしい。

ant releaseすると、時間がかかりながらもビルドできた。



特にLVLが入っていなくても、使えるみたいだ。

が、Blogを読むと、このまま動かしてもCRASHすることがあるらしい。

procfg.txtを編集して、-keep public classとして登録するようだ。

よくわからんので、読んでおきたまえ。

 

登録はめんどくさいなぁ。

が、やらんと動かんなら、仕方ないな。

実際に動かさないとわからんのだったら、全classを試してみないといかんことになるが、事前にわからんのかいな?

ある程度はprocfg.txtに登録してあるので、外部から呼ばれることがあるclassだけを追加すればよさそうな気がするが・・・。

 

obf/mappin.txtに、どのようにobfされたかが出ているみたいだ。

何かなと思ってみると、このクラスはこの名前に変更しました、というものみたい。

そういえば、Javaって名前がそのままファイルサイズにつながるという記事をどこかで読んだことがある。

難読化するのとサイズを小さくするのを兼ねているのだな。

とまあ、あまり興味がないわりには最後までやってみましたとさ。
めでたしめでたし。

[java]引数にfinalをつけるとどうなるのだろう (2)

http://hiro99ma.blogspot.com/2011/09/javafinal-1.html

なんだかよくわからなくなってきた。

final byte[] a = new byte[5];

こんなことをしても、バイトコードでは変化がなかった。
もしかすると、finalはバイトコードに現れる類のものではないのかもしれない。

上記のコードに続けて、

a = new byte[3];

などとすると、こっちはエラーになる。
そうなると、finalはバイナリレベルではなくコンパイルレベルでやっているだけということか。


これでようやく、議論の意味がわかった。

引数にfinalをつけても、確かに意味がない。
私みたいにfinalをよくわかってない人にとっては「書き換えないんだろう」とすら思ってしまう。
そう考えると、引数ではfinalを付けない方が親切かも。

もし、「a = new byte[3]」みたいにしないことでコンパイル時の最適化が狙えるのであれば、それは関数内で最初に「final byte[] b = a;」のように引き取った方がいいのかもしれん。

C/C++のconstとは違うもの、という認識を強く持っておかねば。

 

IBMの記事があったので、載せておかねば。

http://www.ibm.com/developerworks/jp/java/library/j-jtp1029/

 

あれ・・・ということは、戻り値をfinalで戻す、ということはできず、それはメソッドがfinalってことになるのか??
ってことは、static classのフィールド(オブジェクト型)を返す関数なんて、最悪ではないか!

ライブラリを作り直さねば・・・。

SDK for NFC Starter Kit β版のドキュメントを見る

M575_NFCAccessLibraryFunctionOverview_1.1j.pdf

概要が書いてあるので、まず目を通す。

ライブラリにはプラグインがあって、そのパスはレジストリに書く。
インストーラがやってくれるのだが、再頒布可能なファイルにはインストーラが入ってなかった。
だめなのかな?
でも、Lite版のアプリとともにライブラリを頒布する場合のライブラリインストールにはインストーラを使ってくださいと書かれている。
なら、いいのかな?

 

また、注意事項がいくつか。

まず、捕捉コマンドの発行ができないとのこと。
ん? InListPassiveTargetを投げられないということですかい?
しくみとしては、poll mode開始関数を実行すると、定期的に裏でポーリングされ、捕捉されたらWindowメッセージで通知されるとのこと。
何気なく使っているポーリングだけど、SONYさん(FNさん?)としては使われたくないコマンドってことなのかなぁ。

 

R/Wは複数のアプリで共有できるとのこと。
「1つのR/Wは、最大8個のアプリで共有できる」とある。R/W複数接続もあり(もってないけど)?
アプリごとのアクセス権(排他制御)もライブラリでできるらしい。
たぶん、アプリはライブラリにアクセス権を獲得しにいき、とれたらアクセスできるのだろう。
んで、アクセスはプロセス単位とのこと。
Windowsのしくみは詳しくないが、アプリケーション=プロセス、でいいのかな。
なお、マルチスレッドには対応してない。

複数で共有したとき、捕捉したら誰に通知が行くかというと、登録が早いひと。プロセスが使用権を解放しないと次のプロセスが使えないので、必ず解放せよ、ということだ。


M579_PC_SC_1.1j.pdf

これは、PC/SCについての資料で、TypeBのはなしらしい。
PC/SCはわからん・・・というよりも、知らないと潔く言わねばなるまい。

Personal Computer / Smart Cardの略。
WindowsでICカードを使うための標準APIらしい。
http://developers.orangetags.jp/words/pc-sc

TypeBチャレンジするときに、また読むかもしれない。
今は、おいておこう。


M577_NFCAccessLibrary_1.2j.pdf

ライブラリの詳細。
といっても、30ページほどしかないのでそこまで身構えることはない。

さっき「捕捉したらWindowメッセージで通知」と書いたが、あれはコールバックのことらしい。
WinProc()がコールバックされて、そこのメッセージによって処理を切り分けるというやり方なのかな。
(Windowsに詳しくないので、基本がわかってない。)

API一覧は17個。
API仕様には18個。差は、一覧にfelicalib_nfc_poll_and_start_dev_access()が漏れているからだ。
そして、2.1.9, 2.1.10が欠番だ。

ヘッダにあるLIBRARY_APIは22個。
載っていないのは、以下の4つ。

  • felicalib_nfc_set_pnp_callback_parameters
  • felicalib_nfc_start_plug_and_play
  • felicalib_nfc_stop_plug_and_play
  • felicalib_nfc_set_watching_interval

最初3つは、R/WのUSB挿抜を監視できるのかな。
最後のは、何のwatchingかわからんな。ヘッダの最後にあるから、pnpの監視間隔ではなくポーリングの間隔のような感じがする(試してない)。

 

私が一番気になるのは、API説明に「S_OK」「E_FAIL」とあるけど、ヘッダファイルには定義がないことだ。
API概要には「true/falseです」と書いてある。
Win32のS_OKは0らしいので、C++のtrueは1扱いとなることを考えると、S_OKではだめだ。
サンプルソースを見ると、戻り値を反転したものが真だったらエラーにしているので、true/falseを使っているということになる(戻り値0を反転したら真になるからね)。

SDK for NFC Starter Kit β版来たる

「来る」は、こういうとき「きたる」と読む。
「夜来る」とか。
でも「夜来たる」の方がわかりやすいよな。

そんなわけで、噂のあれが出た。
SDK for NFC Starter Kitだ。

http://blog.felicalauncher.com/?p=3264

商用利用はできないが、私は売ったりしないからいいや。


ダウンロードしたzipを解凍すると、ファイルがたくさんできる。
今、見ながらやっているので、行きつ戻りつすると思うが我慢しておくれ。

 

英語版と日本語版の両方が入っているので、ドキュメントは半分のファイルしか見ないと思えばよさそうだ。

サンプルのバイナリがあるので、NDEFのType3 Tagを読むexeをWindows XP SP3 32bit版で動作させた。
コマンドプロンプトから実行するタイプで、引数にREADとかWRITEなんかを指定する。
PaSoRi RC-S370を接続し、zipに入っていたドライバもインストールし、コマンドプロンプトからType3Tag.exeを実行すると、PaSoRiの上に置いたNDEFフォーマットされているFeliCa Liteからの情報が標準出力に現れた。

 

というところで、今日は力尽きた。

2011/09/14

Androidのアイコンについて調べてみた

風呂に入って冷静になってみると、アイコンが今ひとつなのは致命的だ。

機能がよくても使ってもらえないとかいうよりも、ウィジェットのようにホーム画面に置くアイコンが貧弱だと、周りとの調和を乱してしまうからだ。

調和を乱すのは、いかん。
和をもって尊しとなす、だっけ。
自重せねば。


アイコンについて調べると、ガイドラインについて説明してくださった人がいた。
ありがたい。

http://blog.asial.co.jp/693

おっと、元のガイドラインを載せておかねば。

http://developer.android.com/guide/practices/ui_guidelines/icon_design.html

 

EjectSDで私が使っているのは、48x48のみ。
こりゃいかんな。
hdpi~ldpiまで取りそろえねば。
launcherにあたるのかな? ならば 36x36、48x48、72x72だ。

 

そしてルールは・・・守ってない項目がほとんど。
がんばろう。

 

しかし、「設定」のアイコンは、なんかわかりにくいと思った。
私はさっき眺めるまで、車のタイヤだとばかり思っていた。
矢印が付いていて、なにかを設定するツマミのようなものなのだろうな。
うーん、まあそれ以外はわかるからいいか。

2011/09/13

[app]アイコンは大切だ

久しぶりにAndroid Marketを見ると、コメントが増えていた。
うれしいかぎりである。

 

SD Ejectのアイコンが残念、というコメントがあった。
うーむ、私としてはシンプルで気に入っていたのだが。
とはいえ、ICONIA A500で作っているにもかかわらず、アイコンのサイズが合ってないのはいかんと思っていた。
アイコンは大切だ。

 

あと、アイコンの再描画がうまくいってない、というのが気になった。
むむむ、それはいかん。
直したい。


が・・・
今週からとても忙しく、そして今週はとても体調が悪い。
仕事は休まずに済んでいるが、土日は高熱で寝込んでいたせいか、頭は痛いわ、なぜか鼻が痛いわ、肩も痛いわ、口内炎も2箇所できるわ、もうさんざんだ。

[java]引数にfinalをつけるとどうなるのだろう (1)

C++でアドレスを渡す場合、constをつけている。
同じ感覚でJavaでもfinalを書いていたのだが、AndroidのAPIではつけているものを見かけない。
ネットで調べると、侃々諤々というか、不毛というか、よくわからんごとなってきた。

ちょっとだけやってみよう。

Oracleのサーバ向けのドキュメントでは、チューニングガイドにちょっと載っていた。
http://download.oracle.com/docs/cd/E19528-01/820-1613/abebm/index.html


   1: package com.blogpost.hiro99ma;
   2:  
   3: public class FinalTest {
   4:     static void print(byte[] b) {
   5:         for(int i=0; i<b.length; i++) {
   6:             System.out.print(b[i]);
   7:         }
   8:         System.out.println();
   9:         
  10:         b[0] = 5;
  11:     }
  12:     
  13:     public static void main(String[] args) {
  14:         byte[] a = new byte[] { 1, 2, 3 };
  15:         print(a);
  16:  
  17:         for(int i=0; i<a.length; i++) {
  18:             System.out.print(a[i]);
  19:         }
  20:         System.out.println();
  21:     }
  22: }

まあ、シンプルに。
実行すると、こうなる。

123
523

予想通りだ。
classファイルは846byte。

バイトコードは、こうなってる。

// Compiled from FinalTest.java (version 1.6 : 50.0, super bit)
public class com.blogpost.hiro99ma.FinalTest {
  
  // Method descriptor #6 ()V
  // Stack: 1, Locals: 1
  public FinalTest();
    0  aload_0 [this]
    1  invokespecial java.lang.Object() [8]
    4  return
      Line numbers:
        [pc: 0, line: 3]
      Local variable table:
        [pc: 0, pc: 5] local: this index: 0 type: com.blogpost.hiro99ma.FinalTest
  
  // Method descriptor #15 ([B)V
  // Stack: 3, Locals: 2
  static void print(byte[] b);
     0  iconst_0
     1  istore_1 [i]
     2  goto 17
     5  getstatic java.lang.System.out : java.io.PrintStream [16]
     8  aload_0 [b]
     9  iload_1 [i]
    10  baload
    11  invokevirtual java.io.PrintStream.print(int) : void [22]
    14  iinc 1 1 [i]
    17  iload_1 [i]
    18  aload_0 [b]
    19  arraylength
    20  if_icmplt 5
    23  getstatic java.lang.System.out : java.io.PrintStream [16]
    26  invokevirtual java.io.PrintStream.println() : void [27]
    29  aload_0 [b]
    30  iconst_0
    31  iconst_5
    32  bastore
    33  return
      Line numbers:
        [pc: 0, line: 5]
        [pc: 5, line: 6]
        [pc: 14, line: 5]
        [pc: 23, line: 8]
        [pc: 29, line: 10]
        [pc: 33, line: 11]
      Local variable table:
        [pc: 0, pc: 34] local: b index: 0 type: byte[]
        [pc: 2, pc: 23] local: i index: 1 type: int
      Stack map table: number of frames 2
        [pc: 5, append: {int}]
        [pc: 17, same]
  
  // Method descriptor #36 ([Ljava/lang/String;)V
  // Stack: 4, Locals: 3
  public static void main(java.lang.String[] args);
     0  iconst_3
     1  newarray byte [8]
     3  dup
     4  iconst_0
     5  iconst_1
     6  bastore
     7  dup
     8  iconst_1
     9  iconst_2
    10  bastore
    11  dup
    12  iconst_2
    13  iconst_3
    14  bastore
    15  astore_1 [a]
    16  aload_1 [a]
    17  invokestatic com.blogpost.hiro99ma.FinalTest.print(byte[]) : void [37]
    20  iconst_0
    21  istore_2 [i]
    22  goto 37
    25  getstatic java.lang.System.out : java.io.PrintStream [16]
    28  aload_1 [a]
    29  iload_2 [i]
    30  baload
    31  invokevirtual java.io.PrintStream.print(int) : void [22]
    34  iinc 2 1 [i]
    37  iload_2 [i]
    38  aload_1 [a]
    39  arraylength
    40  if_icmplt 25
    43  getstatic java.lang.System.out : java.io.PrintStream [16]
    46  invokevirtual java.io.PrintStream.println() : void [27]
    49  return
      Line numbers:
        [pc: 0, line: 14]
        [pc: 16, line: 15]
        [pc: 20, line: 17]
        [pc: 25, line: 18]
        [pc: 34, line: 17]
        [pc: 43, line: 20]
        [pc: 49, line: 21]
      Local variable table:
        [pc: 0, pc: 50] local: args index: 0 type: java.lang.String[]
        [pc: 16, pc: 50] local: a index: 1 type: byte[]
        [pc: 22, pc: 43] local: i index: 2 type: int
      Stack map table: number of frames 2
        [pc: 25, append: {byte[], int}]
        [pc: 37, same]
}

お、と思ったかもしれないが、バイトコードは読んだことはない。
まあ、アセンブラも適当に読めるものだから、なんとかなるだろう。

Method #6は、デフォルトコンストラクタだろう。
Method #15は、print()。aloadはarrayでiloadはintか?
「b[0]=5」は29~31行でやっているようだ。
「b[2]=9」にすると、ちょっと変わった。

29  aload_0 [b]
30  iconst_2
31  bipush 9

うーん、iconstからbipushになったな・・・。
えーい、これならどうだ!

b[0] = 0;
b[0] = 1;
b[0] = 2;
b[0] = 3;
b[0] = 4;
b[0] = 5;
b[0] = 6;

結果は・・・

29  aload_0 [b]
30  iconst_0
31  iconst_0
32  bastore
33  aload_0 [b]
34  iconst_0
35  iconst_1
36  bastore
37  aload_0 [b]
38  iconst_0
39  iconst_2
40  bastore
41  aload_0 [b]
42  iconst_0
43  iconst_3
44  bastore
45  aload_0 [b]
46  iconst_0
47  iconst_4
48  bastore
49  aload_0 [b]
50  iconst_0
51  iconst_5
52  bastore
53  aload_0 [b]
54  iconst_0
55  bipush 6
57  bastore

2つわかった。
iconstとipushが切り替わる境目は、代入する値が5以下か6以上かであること。
もう1つは、bastoreは毎回呼ばれるということ。

bはbyteのbだろう。intにして確認。

29  aload_0 [b]
30  iconst_0
31  iconst_0
32  iastore
33  aload_0 [b]
34  iconst_0
35  iconst_1
36  iastore
37  aload_0 [b]
38  iconst_0
39  iconst_2
40  iastore
41  aload_0 [b]
42  iconst_0
43  iconst_3
44  iastore
45  aload_0 [b]
46  iconst_0
47  iconst_4
48  iastore
49  aload_0 [b]
50  iconst_0
51  iconst_5
52  iastore
53  aload_0 [b]
54  iconst_0
55  bipush 6
57  iastore

「aload_0 [b]」で、引数の先頭アドレスを取ってきて、その次の「iconst_x」でオフセットを設定。
その次の「iconst_y」で代入する値を決めて、その次の「iastore」で代入、というところか。

違ってたら済まん。

驚いたのは、b[0]に代入するだけのコードを立て続けに書いたのに、最適化してないこと。
まるでvolatile変数みたいだ。
デフォルトだとこうなるのかしら。

 

最初に戻って。
これの引数にfinalをつけてみよう。

   1: package com.blogpost.hiro99ma;
   2:  
   3: public class FinalTest {
   4:     static void print(final byte[] b) {
   5:         for(int i=0; i<b.length; i++) {
   6:             System.out.print(b[i]);
   7:         }
   8:         System.out.println();
   9:         
  10:         b[0] = 5;
  11:     }
  12:     
  13:     public static void main(String[] args) {
  14:         byte[] a = new byte[] { 1, 2, 3 };
  15:         print(a);
  16:  
  17:         for(int i=0; i<a.length; i++) {
  18:             System.out.print(a[i]);
  19:         }
  20:         System.out.println();
  21:     }
  22: }

実行結果は同じ。

123
523

finalでは指している先の変更は妨げることができないというのは、わかった。
では、バイトコードに違いはあるのだろうか。

// Compiled from FinalTest.java (version 1.6 : 50.0, super bit)
public class com.blogpost.hiro99ma.FinalTest {
  
  // Method descriptor #6 ()V
  // Stack: 1, Locals: 1
  public FinalTest();
    0  aload_0 [this]
    1  invokespecial java.lang.Object() [8]
    4  return
      Line numbers:
        [pc: 0, line: 3]
      Local variable table:
        [pc: 0, pc: 5] local: this index: 0 type: com.blogpost.hiro99ma.FinalTest
  
  // Method descriptor #15 ([B)V
  // Stack: 3, Locals: 2
  static void print(byte[] b);
     0  iconst_0
     1  istore_1 [i]
     2  goto 17
     5  getstatic java.lang.System.out : java.io.PrintStream [16]
     8  aload_0 [b]
     9  iload_1 [i]
    10  baload
    11  invokevirtual java.io.PrintStream.print(int) : void [22]
    14  iinc 1 1 [i]
    17  iload_1 [i]
    18  aload_0 [b]
    19  arraylength
    20  if_icmplt 5
    23  getstatic java.lang.System.out : java.io.PrintStream [16]
    26  invokevirtual java.io.PrintStream.println() : void [27]
    29  aload_0 [b]
    30  iconst_0
    31  iconst_5
    32  bastore
    33  return
      Line numbers:
        [pc: 0, line: 5]
        [pc: 5, line: 6]
        [pc: 14, line: 5]
        [pc: 23, line: 8]
        [pc: 29, line: 10]
        [pc: 33, line: 11]
      Local variable table:
        [pc: 0, pc: 34] local: b index: 0 type: byte[]
        [pc: 2, pc: 23] local: i index: 1 type: int
      Stack map table: number of frames 2
        [pc: 5, append: {int}]
        [pc: 17, same]
  
  // Method descriptor #36 ([Ljava/lang/String;)V
  // Stack: 4, Locals: 3
  public static void main(java.lang.String[] args);
     0  iconst_3
     1  newarray byte [8]
     3  dup
     4  iconst_0
     5  iconst_1
     6  bastore
     7  dup
     8  iconst_1
     9  iconst_2
    10  bastore
    11  dup
    12  iconst_2
    13  iconst_3
    14  bastore
    15  astore_1 [a]
    16  aload_1 [a]
    17  invokestatic com.blogpost.hiro99ma.FinalTest.print(byte[]) : void [37]
    20  iconst_0
    21  istore_2 [i]
    22  goto 37
    25  getstatic java.lang.System.out : java.io.PrintStream [16]
    28  aload_1 [a]
    29  iload_2 [i]
    30  baload
    31  invokevirtual java.io.PrintStream.print(int) : void [22]
    34  iinc 2 1 [i]
    37  iload_2 [i]
    38  aload_1 [a]
    39  arraylength
    40  if_icmplt 25
    43  getstatic java.lang.System.out : java.io.PrintStream [16]
    46  invokevirtual java.io.PrintStream.println() : void [27]
    49  return
      Line numbers:
        [pc: 0, line: 14]
        [pc: 16, line: 15]
        [pc: 20, line: 17]
        [pc: 25, line: 18]
        [pc: 34, line: 17]
        [pc: 43, line: 20]
        [pc: 49, line: 21]
      Local variable table:
        [pc: 0, pc: 50] local: args index: 0 type: java.lang.String[]
        [pc: 16, pc: 50] local: a index: 1 type: byte[]
        [pc: 22, pc: 43] local: i index: 2 type: int
      Stack map table: number of frames 2
        [pc: 25, append: {byte[], int}]
        [pc: 37, same]
}

まったく同じだ。
そもそも「static void print(int[] b);」なので、finalがなくなっている。

 

配列だからか?
プリミティブ型の配列だからなのか??

というところで、疲れ果てたので寝る。