NFC通信での読み取り_Suicaの残高の読み取り
■スマホでSuica残高を読み取るコード。
前回タグの読み取りができたけど、実際のデータが返ってこなかった。ウェブで調べたコードを基に、Suica残高を表示させてみた。
データ自体は前回試した connect、transceive のメソッドで十分だった。パラメータの値として、Suicaのサービスコードとブロックコードを含めることでデータ取得ができた。
タグを読み取った後のコードは下の通り。Suicaのサービスコード0x090f、ブロック番号0x80はウェブで調べたもの(ここで0xは16進数を示す。0x090f は、090fの16進数のため、10進数で2319となる)。
NfcF nf = NfcF.get(tag);
int length = 64;
ByteBuffer buff = ByteBuffer.allocate(length);
byte byteLength = (byte) length;
byte[] idm = nf.getTag().getId();
byte[] read_wo_encryption_command = new byte[]{(byte) 0x06};
// Suicaのサービスコード: 0x090f
byte[] data = new byte[]{
(byte) 0x01,
(byte) 0x0f,
(byte) 0x09,
(byte) 0x01,
(byte) 0x80,
(byte) 0x00,
};
buff.put(byteLength).put(read_wo_encryption_command).put(idm).put(data);
byte[] tranCmd = buff.array();
byte[] result = new byte[255];
TextView tv = findViewById(R.id.tv1);
try {
nf.connect();
result = nf.transceive(tranCmd);
(以下省略)
transceive の引数のフォーマット(長さ 1バイト、コマンドコード 1バイト、ID 8バイト、パラメータ 10バイト:1バイトは8ビット(0~255))と比べても、上の例は合致する。
パラメータ部分(上の例でのdata部分)は、おそらくサービス数(0x01)、サービスコード(0x090fを2つに分けたもの)、ブロック数(0x01)、ブロック位置(ブロック位置を2つに分けたもの)。1ブロックは16バイトとのことなので、0x80 (128、1ブロック)、0x100 (256、2ブロック)、0x180 (384、3ブロック) などから指定できるよう。0x180 とする場合、(byte) 0x80, (byte) 0x01 と指定する。
Suicaの場合、1ブロックの中に残高を含めた取引履歴が入っているそうで、2ブロック分のデータを取得した場合は、最新のものと1つ前のものが含まれていた。
実行してSuicaを読み取った結果が下のもの。読み取った結果もバイト表記となるので、それらを変換して表示させたもの。
今回、ウェブのコードを基にしたけど、Suicaの仕様など分からなかったらサービスコードとか何を使えばいいか分からなかっただろうなー。