質問編集履歴
2
文字修正
test
CHANGED
File without changes
|
test
CHANGED
@@ -12,15 +12,15 @@
|
|
12
12
|
|
13
13
|
```java
|
14
14
|
|
15
|
-
2020-03-09 00:42:55.726 10628-10628/com.example.t
|
15
|
+
2020-03-09 00:42:55.726 10628-10628/com.example.t D/Hoge: date Discovered!
|
16
|
-
|
16
|
+
|
17
|
-
2020-03-09 00:42:55.727 10628-10628/com.example.t
|
17
|
+
2020-03-09 00:42:55.727 10628-10628/com.example.t E/com.example.ta: No package ID 31 found for ID 0x31303336.
|
18
|
-
|
18
|
+
|
19
|
-
2020-03-09 00:42:55.727 10628-10628/com.example.t
|
19
|
+
2020-03-09 00:42:55.727 10628-10628/com.example.t D/AndroidRuntime: Shutting down VM
|
20
|
-
|
20
|
+
|
21
|
-
2020-03-09 00:42:55.732 10628-10628/com.example.t
|
21
|
+
2020-03-09 00:42:55.732 10628-10628/com.example.t E/AndroidRuntime: FATAL EXCEPTION: main
|
22
|
-
|
22
|
+
|
23
|
-
Process: com.example.t
|
23
|
+
Process: com.example.t, PID: 10628
|
24
24
|
|
25
25
|
android.content.res.Resources$NotFoundException: String resource ID #0x31303336
|
26
26
|
|
@@ -28,7 +28,7 @@
|
|
28
28
|
|
29
29
|
at android.widget.Toast.makeText(Toast.java:307)
|
30
30
|
|
31
|
-
at com.example.t
|
31
|
+
at com.example.t.MainActivity.onNewIntent(MainActivity.java:92)
|
32
32
|
|
33
33
|
at android.app.Activity.performNewIntent(Activity.java:7149)
|
34
34
|
|
@@ -62,7 +62,7 @@
|
|
62
62
|
|
63
63
|
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
|
64
64
|
|
65
|
-
2020-03-09 00:42:55.740 10628-10628/com.example.ta
|
65
|
+
2020-03-09 00:42:55.740 10628-10628/com.example.ta I/Process: Sending signal. PID: 10628 SIG: 9
|
66
66
|
|
67
67
|
```
|
68
68
|
|
@@ -76,7 +76,7 @@
|
|
76
76
|
|
77
77
|
```JAVa
|
78
78
|
|
79
|
-
package com.example.t
|
79
|
+
package com.example.t;
|
80
80
|
|
81
81
|
|
82
82
|
|
@@ -118,9 +118,9 @@
|
|
118
118
|
|
119
119
|
// 定数
|
120
120
|
|
121
|
-
private final byte[] TARGET_SYSTEM_CODE = new byte[]{(byte) 0x80, (byte) 0x2
|
121
|
+
private final byte[] TARGET_SYSTEM_CODE = new byte[]{(byte) 0x80, (byte) 0x22};
|
122
|
-
|
122
|
+
|
123
|
-
private final byte[] TARGET_SERVICE_CODE = new byte[]{(byte) 0x9B, (byte) 0x
|
123
|
+
private final byte[] TARGET_SERVICE_CODE = new byte[]{(byte) 0x9B, (byte) 0x1B};
|
124
124
|
|
125
125
|
private final int TARGET_SIZE = 4;
|
126
126
|
|
@@ -272,7 +272,7 @@
|
|
272
272
|
|
273
273
|
```Java
|
274
274
|
|
275
|
-
package com.example.t
|
275
|
+
package com.example.t;
|
276
276
|
|
277
277
|
import android.nfc.Tag;
|
278
278
|
|
1
Nfcreaderのプログラムを追加しました。
test
CHANGED
File without changes
|
test
CHANGED
@@ -268,7 +268,265 @@
|
|
268
268
|
|
269
269
|
```
|
270
270
|
|
271
|
-
|
271
|
+
以下がNfcReader.javaです。
|
272
|
+
|
273
|
+
```Java
|
274
|
+
|
275
|
+
package com.example.ta7;
|
276
|
+
|
277
|
+
import android.nfc.Tag;
|
278
|
+
|
279
|
+
import android.nfc.tech.NfcF;
|
280
|
+
|
281
|
+
import android.util.Log;
|
282
|
+
|
283
|
+
|
284
|
+
|
285
|
+
import java.io.ByteArrayOutputStream;
|
286
|
+
|
287
|
+
import java.io.IOException;
|
288
|
+
|
289
|
+
import java.util.Arrays;
|
290
|
+
|
291
|
+
|
292
|
+
|
293
|
+
|
294
|
+
|
295
|
+
public class NfcReader {
|
296
|
+
|
297
|
+
|
298
|
+
|
299
|
+
public byte[][] readTag(Tag tag, byte[] targetSystemCode , byte[] targetServiceCode, int size ) {
|
300
|
+
|
301
|
+
NfcF nfc = NfcF.get(tag);
|
302
|
+
|
303
|
+
if (nfc == null) {
|
304
|
+
|
305
|
+
return null;
|
306
|
+
|
307
|
+
}
|
308
|
+
|
309
|
+
|
310
|
+
|
311
|
+
try {
|
312
|
+
|
313
|
+
nfc.connect();
|
314
|
+
|
315
|
+
|
316
|
+
|
317
|
+
|
318
|
+
|
319
|
+
// polling コマンドを作成
|
320
|
+
|
321
|
+
byte[] polling = polling(targetSystemCode );
|
322
|
+
|
323
|
+
|
324
|
+
|
325
|
+
// コマンドを送信して結果を取得
|
326
|
+
|
327
|
+
byte[] pollingRes = nfc.transceive(polling);
|
328
|
+
|
329
|
+
|
330
|
+
|
331
|
+
// System 0 のIDmを取得(1バイト目はデータサイズ、2バイト目はレスポンスコード、IDmのサイズは8バイト)
|
332
|
+
|
333
|
+
byte[] targetIDm = Arrays.copyOfRange(pollingRes, 2, 10);
|
334
|
+
|
335
|
+
|
336
|
+
|
337
|
+
Log.d("Hoge","IDM Discovered!");
|
338
|
+
|
339
|
+
|
340
|
+
|
341
|
+
// Read Without Encryption コマンドを作成
|
342
|
+
|
343
|
+
byte[] req = readWithoutEncryption(targetIDm, size, targetServiceCode);
|
344
|
+
|
345
|
+
|
346
|
+
|
347
|
+
// コマンドを送信して結果を取得
|
348
|
+
|
349
|
+
byte[] res = nfc.transceive(req);
|
350
|
+
|
351
|
+
Log.d("Hoge","Tag covered!");
|
352
|
+
|
353
|
+
nfc.close();
|
354
|
+
|
355
|
+
|
356
|
+
|
357
|
+
// 結果をパースしてデータだけ取得
|
358
|
+
|
359
|
+
return parse(res);
|
360
|
+
|
361
|
+
} catch (Exception e) {
|
362
|
+
|
363
|
+
Log.e(String.valueOf(tag), e.getMessage() , e);
|
364
|
+
|
365
|
+
}
|
366
|
+
|
367
|
+
return null;
|
368
|
+
|
369
|
+
}
|
370
|
+
|
371
|
+
/*
|
372
|
+
|
373
|
+
* Pollingコマンドの取得。
|
374
|
+
|
375
|
+
* @param systemCode byte[] 指定するシステムコード
|
376
|
+
|
377
|
+
* @return Pollingコマンド
|
378
|
+
|
379
|
+
* @throws IOException
|
380
|
+
|
381
|
+
*/
|
382
|
+
|
383
|
+
|
384
|
+
|
385
|
+
private byte[] polling(byte[] targetSystemCode ) {
|
386
|
+
|
387
|
+
ByteArrayOutputStream bout = new ByteArrayOutputStream(6);
|
388
|
+
|
389
|
+
|
390
|
+
|
391
|
+
bout.write(0x00); // データ長バイトのダミー
|
392
|
+
|
393
|
+
bout.write(0x00); // コマンドコード:0X00
|
394
|
+
|
395
|
+
bout.write(targetSystemCode [0]); // systemCode
|
396
|
+
|
397
|
+
bout.write(targetSystemCode [1]); // systemCode
|
398
|
+
|
399
|
+
bout.write(0x01); // リクエストコード:01h(システムコード要求)
|
400
|
+
|
401
|
+
bout.write(0x00); // タイムスロット
|
402
|
+
|
403
|
+
|
404
|
+
|
405
|
+
byte[] msg = bout.toByteArray();
|
406
|
+
|
407
|
+
msg[0] = (byte) msg.length; // 先頭1バイトはデータ長
|
408
|
+
|
409
|
+
return msg;
|
410
|
+
|
411
|
+
}
|
412
|
+
|
413
|
+
/*
|
414
|
+
|
415
|
+
* Read Without Encryptionコマンドの取得。
|
416
|
+
|
417
|
+
* @param idm 指定するシステムのID
|
418
|
+
|
419
|
+
* @param size 取得するデータの数
|
420
|
+
|
421
|
+
* @return Read Without Encryptionコマンド
|
422
|
+
|
423
|
+
* @throws IOException
|
424
|
+
|
425
|
+
*/
|
426
|
+
|
427
|
+
private byte[] readWithoutEncryption(byte[] targetIDm, int size, byte[] targetServiceCode) throws IOException {
|
428
|
+
|
429
|
+
ByteArrayOutputStream bout = new ByteArrayOutputStream(100);
|
430
|
+
|
431
|
+
|
432
|
+
|
433
|
+
bout.write(0x00); // データ長バイトのダミー
|
434
|
+
|
435
|
+
bout.write(0x06); // コマンドコード
|
436
|
+
|
437
|
+
bout.write(targetIDm); // IDm 8byte
|
438
|
+
|
439
|
+
bout.write(1); // サービス数の長さ(以下2バイトがこの数分繰り返す)
|
440
|
+
|
441
|
+
|
442
|
+
|
443
|
+
// サービスコードの指定はリトルエンディアンなので、下位バイトから指定します。
|
444
|
+
|
445
|
+
bout.write( targetServiceCode[1]); // サービスコード下位バイト
|
446
|
+
|
447
|
+
bout.write( targetServiceCode[0]); // サービスコード上位バイト
|
448
|
+
|
449
|
+
bout.write(size); // ブロック数
|
450
|
+
|
451
|
+
|
452
|
+
|
453
|
+
// ブロック番号の指定
|
454
|
+
|
455
|
+
for (int i = 0; i < size; i++) {
|
456
|
+
|
457
|
+
bout.write(0x80); // ブロックエレメント上位バイト 「Felicaユーザマニュアル抜粋」の4.3項参照
|
458
|
+
|
459
|
+
bout.write(i); // ブロック番号
|
460
|
+
|
461
|
+
}
|
462
|
+
|
463
|
+
|
464
|
+
|
465
|
+
byte[] msg = bout.toByteArray();
|
466
|
+
|
467
|
+
msg[0] = (byte) msg.length; // 先頭1バイトはデータ長
|
468
|
+
|
469
|
+
return msg;
|
470
|
+
|
471
|
+
}
|
472
|
+
|
473
|
+
|
474
|
+
|
475
|
+
/*
|
476
|
+
|
477
|
+
* Read Without Encryption応答の解析。
|
478
|
+
|
479
|
+
* @param res byte[]
|
480
|
+
|
481
|
+
* @return 文字列表現
|
482
|
+
|
483
|
+
*/
|
484
|
+
|
485
|
+
private byte[][] parse(byte[] res) {
|
486
|
+
|
487
|
+
// res[10] エラーコード。0x00の場合が正常
|
488
|
+
|
489
|
+
if (res[10] != 0x00)
|
490
|
+
|
491
|
+
throw new RuntimeException("Read Without Encryption Command Error");
|
492
|
+
|
493
|
+
|
494
|
+
|
495
|
+
// res[12] 応答ブロック数
|
496
|
+
|
497
|
+
// res[13 + n * 16] 実データ 16(byte/ブロック)の繰り返し
|
498
|
+
|
499
|
+
int size = res[12];
|
500
|
+
|
501
|
+
byte[][] data = new byte[size][16];
|
502
|
+
|
503
|
+
for (int i = 0; i < size; i++) {
|
504
|
+
|
505
|
+
byte[] tmp = new byte[16];
|
506
|
+
|
507
|
+
int offset = 13 + i * 16;
|
508
|
+
|
509
|
+
for (int j = 0; j < 16; j++) {
|
510
|
+
|
511
|
+
tmp[j] = res[offset + j];
|
512
|
+
|
513
|
+
}
|
514
|
+
|
515
|
+
|
516
|
+
|
517
|
+
data[i] = tmp;
|
518
|
+
|
519
|
+
}
|
520
|
+
|
521
|
+
return data;
|
522
|
+
|
523
|
+
}
|
524
|
+
|
525
|
+
|
526
|
+
|
527
|
+
}
|
528
|
+
|
529
|
+
```
|
272
530
|
|
273
531
|
### 試したこと
|
274
532
|
|