スマートポスターについて

スマートポスターについて

スマートポスターは、URIに付加情報を加えるためのレコード

URIは、単体でも意味を持つ

スマートポスターは、モノやイベント
その他の情報を物理的なモノを得るために使う

使用例としては
映画のポスターに
スマートポスターレコードが含まれたタグを貼っておけば
ポスターへNFC端末をかざせば
タグのURLから映画の詳細のあるサイトを表示することができる

URIには、SMS 電話番号なども含めることができるため
番号を教えたり
GPSレコードでイベント会場を指し示すこともできる

つまり、スマートポスターは
かざすことで情報へ簡単にアクセスできるものになる

アプリケーションレコードの概要

アプリケーションレコードの概要

このレコードはNDEF headerへ以下の情報をセットする

TNF:0x04(NFC Forum external type)
type:android.com:pkg
payload:パッケージ名

次に、レコード作成と読み込み

これは、android.com:pkg をバイト列にしてtypeへ指定し
payloadには任意のパッケージ名を
タイプと同様の方法でバイト化したものを含める

ソースにすると
private static NdefRecord toNdefRecord(String pkg){
//パッケージ名をバイト列へ変換
byte[] pkgBytes = pkg.getBytes(Charset.forName(“US-ASCII”));

//NDEF record作成
return new NdefRecord(NdefRecord.TNF_EXTERNAL_TYPE, RTD_ANDROID_APP, new byte[0] , pkgBytes);
}

public static final byte[] RTD_ANDROID_APP = “android.com:pkg”.getBytes();

public static AndroidApplicationRecord parse(NdefRecord parseRec) throws FormatException{
if(parseRec.getTnf() != NdefRecord.TNF_EXTERNAL_TYPE){
throw new FormatException(“TNFがNFC forum well known type ではありませんでした”);
}
if(!Arrays.equals(parseRec.getType(), RTD_ANDROID_APP)){
throw new FormatException(“タイプがandroid.com:pkgではありませんでした”);
}

//読み取ったデータを文字列へ変換
String packageName = new String(parseRec.getPayload(), Charset.forName(“US-ASCII”));

return new AndroidApplicationRecord(packageName);
}

アプリケーションレコードの利用

アプリケーションレコードの利用

アプリケーションレコードは
AARともいわれる
これは、Android Application Record の略

これは、Androidが独自に定めたレコード

アプリケーションレコードには、Androidのパッケージ名を入れておくことが可能で
このレコードをNDEF Messageに含めておくことで
優先的にそのパッケージ名を持つアプリで扱うことができる
また、そのアプリが見つからない場合、
GooglePlayからアプリをダウンロードするように促す

アプリケーションレコードを含める位置は
NDEF messageのどの位置でもよいとはいっても
NDEF messageの末尾に入れることが推奨されている

注意点として Android API level 10 では
AAR非対応のため、正しく認識できない

Android でJSON

Android でJSON

JSONは javascript Obuject Notation の略

javascript で使われるデータ表記をモデルとした
データ記述方法のこと

これは成魚のための文字が少なく
データが比較的軽量なので
多くのAPIで使われる

例のソースにすると
{
“dataA”:”data1″,
“dataB”:”data2″,
“dataC”:{
“dataC-1″:”dataC”,
“dataC-2″:”dataD”
}

}
というようにペアになっていて階層にすることも可能

次に。JSONオブジェクト

JSON形式のデータファイルを扱うにはJSONObuject を使う

ソースにすると
String text = “{“+
“‘nodeA’ : ‘nodeA-data’,”+
“‘nodeB’ : ‘nodeB-data'”+
“}”;
JSONObject json_data = new JSONObject(text);

これでJSONObuject にしている

そして
JSONオブジェクトから値を取り出すには
getXXX() という形のメソッドを使う
これは型により変わる
大抵の場合なら string 形式なので
getString()になる

この変換はAPI使うなら必須かも

ソースにすると
String text = “{“+
“‘nodeA’ : ‘nodeA-data’,”+
“‘nodeB’ : ‘nodeB-data'”+
“}”;
JSONObject json_data = new JSONObject(text);

で text という JSONオブジェクトを作成している

そしてこれから値を取得する

string result = json_data.getString(“nodeA”);
これで
値として
nodeA-data

result に格納される

これはJSONが
キー:値
というよく見る組み合わせで管理しているからだ

つまり、getXXX() でキーを取得すれば
値を格納することができるわけだ

さて、ここまではよくあるやり方
実際にAPIを使うときには、ほぼ確実に階層データになっている

階層構造のあるデータの操作が必要になる

改造構造のあるJSONデータを扱うには
取得した JSONObject のgetJSONObject() を使うことになる

ソースにすると

まず
String text = “{“+
“‘nodeA’ : ‘nodeA-data’,”+
“‘nodeB’ : ‘nodeB-data’,”+

“‘nodeC’: “+ “{” +
“‘nodeC-A’ :+’data1′,”+
“‘nodeC-B’:’data2′”+
“}”+
“}”;
これで階層構造のJSONを変数 text に格納

次に
JSONOBject json_data = new JSONOBject(text);
として
json_data に変換したデータを格納する

ここまではほとんど同じ

次に階構造のあるJSONを取得する

JSONbject inner = json_data.getJSONObuject(“nodeC”);
まずは複数格納している上のものを取得する

次に
String result = inner.getString(“nodeC-A”);
とすれば
nodeC-A の中身の data1 が取得できる

つまり
一度上のものを取得しておけば
あとは別の変数に
getXXX() でデータを引っ張ってくことができる

PHPで
$result->item
というように階層をたどるのと同じ要領になる

そして、もう一つよく使うのが配列が含まれるデータの操作について

基本的に検索結果とかだとほぼ配列を使うことになる
配列が含まれるJSONデータは
JSONObuject の getJSONArray() を使うことで取得する

ソースにすると

String text =”{“+
“‘nodeA’ : ‘nodeA-data’,”+
“‘nodeB’ : ‘nodeB-data’,”+
“‘nodeC’ : ‘[‘A’,’B’,’C’]”+
“}”;
として text にデータを格納

次にect
JSONObject json_data = new JSONObject(text);
でJSONデータにする

ここから配列として取り出したいので
JSONArray inner = json_data.getJSONArray(“nodeC”);
で配列 nodeC を inner に格納

そして代入するための文字列を
StringBuilder string = new StringBuilder();
で用意して

for(int i=0;i

URIフィールドについて

URIフィールドについて

このフィールドには、RFC 3987 に沿ったURIが入る

このRFCはIRIだけど
レガシーな理由からURIというキーワードで使われ続けている

このURIのエンコーディングは
URIスキームにより特別に指定されていない限り、UTF-8であること

URIは、7bitのUS-ASCII空間のみで定義されている

このため、それ以外の文字が含まれるなら
IRI[RFC 3987]
IDN[RFC 3492]
に従い、適切にエンコードする必要がある

uriレコードの利用

uriレコードの利用

URI Recordは
URLとURNの総称で
場所であるURL
名前であるURNを一意に識別するためのルールのこと

NFCでやりとりするために
通常のuriより軽量に作られている

また、URI RTDは
NDEF headerへ以下の情報がセットされる必要がある

TNF:0x01(NFC forum well known type)
タイプ:RTD URI Type(“U”[0x55])

payloadについては以下の要素で構成される

識別子コード(identifier code)

1byteで表すURI識別子コード

URIを短くするために、最初のバイトは
URIのプロトコルを表現するために使う

URIをエンコード、またはデコードする場合
以下の識別子コードを使う

0(0x00)
前置きは使わない
完全なURIを指定するときに使う

1(0x01)
http://www.

2(0x02)
https://www.

3(0x03)
http://

4(0x04)
https://

5(0x05)
tel:

6(0x06)
mailto:

7(0x07)
ftp://anonymous:anonymous@

8(0x08)
ftp://ftp.

9(0x09)
ftps://

10(0x0A)
sftp://

11(0x0B)
smb://

12(0x0C)
nfs://

13(0x0D)
ftp://

14(0x0E)
dav://

15(0x0F)
news:

16(0x10)
telnet://

17(0x11)
imap:

18(0x12)
risp://

19(0x13)
urn:

20(0x14)
pop:

21(0x15)
sip:

22(0x16)
sips:

23(0x17)
tftp:

24(0x18)
btspp:

25(0x19)
btl2cap:

26(0x1A)
blgoep://

27(0x1B)
tcpobex://

28(0x1C)
irdaobex://

29(0x1D)
file://

30(0x1E)
urn:epc:id:

31(0x1F)
urn:epc:tag:

32(0x20)
urn:epc:pat:

33(0x21)
urn:epc:raw:

34(0x22)
urn:epc:

35(0x23)
urn:nfc:

36(0x24…0xFF)
RFUこれは将来のための予約
このプロトコルを含むコードは生成してはいけない

Eclipse プロジェクトコピー

Eclipse プロジェクトコピー

Android Projectをeclipse上でコピーして別Projectとして開発する
http://kyokomi-android.doorblog.jp/archives/6835616.html
を参考に
既存のプロジェクトである
SQLDBを
コピーして新しく作る

まずはプロジェクト右クリックでコピー
そして貼り付け
名前は
AutoSQLDB
へ変更

次にプロジェクトを右クリック
Android Tools >
Rename Application Package
でパッケージ名を変更

あとはアプリの名前が同じだとわかりにくいので
res/strings.xml で

<string name="app_name">SQLDB</string>

となっているのを

<string name="app_name">AutoSQLDB</string>

というようにアプリ名を変更すればOK

あとは実機で実行すれば無事に起動しました

TextRTDについて

TextRTDについて

Text Recordは、自由な構文のテキストを含むことごできるレコード

言語コードを含むことができるため
軽量な多言語対応テキストが作成可能

テキストレコードは
NDEF Message の中に複数含めることができるがこれは、多言語対応のため

このため、複数のテキストレコードがふくまれる場合、
複数表示ではなく
ユーザーが求める言語のいずれかのみ表示する

テキストレコードは
NDEF headerに以下の情報がセットする必要がある

TNF
0x01(NFC forum well known type)

そして、タイプ
RTD Text Type(“T” [0x54])

次に、payloadについて
以下の3つのフィールドで構成される

ステータスバイト
ISO/IANA言語コード
実テキスト

まず、ステータスバイトについて
ステータスバイトは
Text RTD のheaderのような役割をするバイト
このバイトは、以下のように定義されている

ビット数
7
0の場合、このテキストのエンコードがUTF-8であることを示す
1なら、UTF-16になる

6
必ず0をセットする
将来のために予約されているビット

5-0
ISO/IANA言語コードの長さを示す
単位はバイト

次に、ISO/IANA言語コードについて
jpやen-USなど
RFC3066
に則った言語コードが入る

また、ステータスバイトには
この言語コードの長さを
ステータスバイトの下位5ビットに含める必要がある
例えば、
jp なら 0x02
en-USなら 0x05
となる
この言語コードは、RFC3066に従わなくてはならない

次に、実テキストについて
これは、UTF-8、または、UTF-16でエンコーディングされた文字列のこと
このエンコーディングは
ステータスバイトで指定したエンコーディングと同じであること

他にもいくつか仕様で決まっていることがあり

テキストの改行コードはCRLFでなければならない

BOM(Byte Order Mark)は許容すること
BOMによりエラーになってはいけない
BOMが省略された場合、
UTF-16 BE(Big Endian)とする

改行(0x0D,0x0A)と,タブ文字(0x08)
を除いて制御文字(UTF-8でいう0x00-0x1F)は
表示する前に削除するべき

マークアップは埋め込まれてはいけない
マークアップはHTMLのようなコードのこと
この場合、text/xhtmlなどのMIMEタイプレコードを利用する

テキストレコードは
MIME-Typeで表すところの
text/plain
format-fixed
と等しくなるよう配慮することが必要

RFC2119キーワードについて

RFC2119キーワードについて

MUST
しなければならない

SHALL
する事になる

SHOULD
する必要がある

MAY
してもよい
これらは、仕様で記述されている事柄に対するキーワード

実装しなくてよい
実装しないとだめ
の解釈を少なくするためキーワード化し
要請の程度を定義したのが
RFC2119になる

NFC forum仕様のように
様々な技術仕様は、このRFC2119で定義された語句を多く利用している

わかりにくいなら検索エンジンで探すと
日本語訳もでてくる

NFC Forumの仕様

NFC Forumの仕様

NFC Forumの仕様は
http://www.nfc-forum.org/specs/spec_list
からダウンロード可能

NDEF関連ドキュメントは5つ

NFC data exchanged format (NDEF) technical specification
NFC forum準拠のデバイスやタグのための一般的なデータフォーマットであるNDEFの仕様
これが公式な仕様になる

NFC Record type Definition(RTD) Technical Specification
レコード定義(RTD)の技術仕様
NDEFに基づいた標準的なレコード定義を組み立てるときのルールが書かれている

NFC Text Record Type Definition Technical Specification
複数言語に対応したテキストを作成するためのRTD技術仕様

NFC URI Record Type Definition Technical Specification
URI作成のためのRTD技術仕様

NFC Smart Poster RTD Technical Specification
スマートポスター作成のためのRTD技術仕様
スマートポスターは、payloadへ
NDEF Messageが入るようになっているため
複数のRTD技術仕様の例が含まれている

内容は英語で
バイナリーのレイアウトとして図が書かれていたり
例が書かれている