技術解説
目次
インテントの内部構造
インテントの送信、では、パラメータとして Base64Encode されたバイナリデータがついています。
この中身を解析しないことには表示を行えないのですが、中身は本当にバイナリデータなので、構造が良くわかりません。
以下に構造を「たぶん」で解説しますが、本当にあっている保障はありません。
また、以下の考え方に「パディング」と説明している部分があります。これは、無意味なデータが入っている、と言う意味ですが、本当は意味があるのに気づいていないだけ、と言う可能性は高いです。
基礎概念
Android のプログラムは、基本的には Java です。JavaVM の亜種(Jakarta)の上で動きます。
なので、バイナリデータの中も、Java で扱いやすい形式です。
数値はすべて 32bit です。格納されるときは 32bit アライメントされています。
文字列は UTF-16 です。終端文字は U+0000 です。数値格納を 32bit アライメントするため、奇数文字列のデータの場合、最後に 16bit のパディング U+0000 が付加されます。
複数のデータをバイナリに格納するため、文字列の先頭には数値で文字列長が付与されています。この文字列長には終端文字は含みません。つまり、LASCIIZ 文字列になっています。
Intent のデータとしては、パッケージ、クラス、行動、カテゴリ、データ、データタイプがあります。
このうち、データとデータタイプはどちらか片方しか意味を持たない、排他構造になっています。
また、クラスはパッケージの下位の概念になります。
バイナリ内部は、これらを考慮した構造になっているようです。
文字列長が 0 のときは、文字列の先頭が終端文字 U+0000 のデータになります。この場合、32bit アライメントのため、もう一度 U+0000 が繰り返されます。
文字列長が -1 (0xffffffff) のときは、文字列データ自体が存在しません。すぐに次のデータとなります。
データ構造
それでは、データの内部構造にうつります。
基本的には、文字列の繰り返しですが、直前や直後に数値が入る場合があります。
なので、以下出てくる文字列を順に「n番目データ」とし、n=0 からはじめます。
以下の説明では 6番目まで説明していますが、最後のデータは「文字列長 -1」となっているようです。つまり、6番目まで存在している場合、データは7番目まで存在します。
逆に。後ろのほうのデータが無い場合、5番目や4番目でデータが終了することもあります。データは6番目まで、と決め打ちせず、バイナリデータの最後まで読み取ったら終了するようにしてください。
先頭、0番目として、android.content.Intent という固定文字列が入ります。これは、Intent のデータであることを明示するものです。
つづいて1番目。行動が文字列で入ります。
2番目の前には、数値で「フラグ」が入ります。このフラグの数値により、2番目が「データ」か「データタイプ」かが決定されます。
フラグが 0 のときはデータタイプです。1のときは、データになります。
データの場合のみ、文字列直後にパディング数値が来ます。
3番目の前にもパディング数値が入ります。
3~5番目は、関係が少し複雑です。ここには、パッケージと、その下位概念であるクラスが格納されます。
パッケージのみが指定された場合、3番目として格納されます。
クラス指定がある場合、4番目がパッケージ、5番目がクラスとなります。
文字列長が -1 の場合、「存在しない」ことを意味します。3番目データが存在しなければ、パッケージは4番目に格納されています。
4番目が存在しなければ、クラスのデータは完全に存在しません。5番目を飛ばして、4番目の次が6番目となります。
クラスデータのみ存在する場合、3番目の文字列長は -1 、4番目の文字列長は 0 となり、5番目にクラスが格納されます。
6番目の前には、パディングとフラグの 2つの数値が入ります。
フラグが1のときのみ、6番目にカテゴリーが格納されています。
7番目は、Extras データです。これは非常に長い文字列として、先頭に長さが入る形で扱われますが、実際はバイナリです。詳細は後述します。
以上ですべてのデータがそろいます。
…データの後ろのみ存在する数値とか、やたらパディングが多かったりとか、まだ「何かありそう」な予感がぷんぷんしますが、とりあえずは以上のデータを読み出せば表示は出来るはずです。
Extras データ
Extras のデータは、Intent のデータ構造内では「文字列」のように格納されています。しかし、実際にはバイナリです。
中身は、やはり UTF-16 の LASCIIZ 文字列と、32bit 数値の組み合わせになっています。
以下に構造を示します。
先頭には、 32bit 数値が入っています。4byte のデータとして ASCII 文字にすると BNDL です。これが Extras のバンドルデータであることを示しているようです。
つづいて、32bit 数値。このバイナリ内のデータの個数を示します。
さらに、32bit 数値。パディングです。もしくは、 0 によってヘッダの終了を示しているのかもしれません。
以下、個々のデータが連続して入ります。
key 文字列、型を示す数値、Value 、最後に数値として 0 がパディングで入ります。
この4つが1セットで、冒頭に示されたデータの個数続きます。
もっとも、Extras データは文字列と同じ扱いで格納されているため、バイナリの外側に終端文字の 0 が入ります。
データのサイズは型によって異なります。
型は 0:string 1:int 5:short 6:long 7:float 8:double 9:boolean 0x14:byte となっているようです。
string では、LASCIIZ 文字列で value を格納します。
int、 short および byte は、32bit 数値として格納されています。
long は、32bit 数値を2つ連続させることで 64bit を格納します。
float は 32bit 数値、double は 64bit 数値ですが、内部は IEEE754 浮動小数のビット表現です。
boolean は 32bit 数値で、0 なら false 、1 なら true です。