Slide 1

Slide 1 text

2࣍ݩͱ஥ྑ͘͠Α͏ ͱࢥ͍·ͨ͠ NFCLab 8݄ఆྫձ Լ઒ ܟ߂ 12೥8݄25೔౔༵೔

Slide 2

Slide 2 text

ࣗݾ঺հ גࣜձࣾιχοΫϜʔϒʢਆָࡔʣ ϑϩϯτΤϯυ ΤϯδχΞ NFCLab, JAG, JAGἚ৓ࢧ෦ @androhi 12೥8݄25೔౔༵೔

Slide 3

Slide 3 text

ΞϓϦ࡞ͬͯΈͯ·͢ 12೥8݄25೔౔༵೔

Slide 4

Slide 4 text

NDEFϝοηʔδɹ㱺ɹQRίʔυ Library : ZXing 2.0 ֓ཁ 12೥8݄25೔౔༵೔

Slide 5

Slide 5 text

૝ఆ͢Δར༻γʔϯ Aʮ͜ͷϙελʔʹλον͢ΔͱɺεϚʔτϑΥϯͰԿ͔ݟΒΕΔΒ͍ͧ͠ɻʯ BʮͲΕͲΕ…ɻʁɻԿ΋ى͖ͳ͍͚Ͳɻʯ Cʮ͋ͬʂ͓αΠϑέʔλΠʹ͸ɺॱ࣍ରԠ༧ఆͰͬͯ͢ॻ͍ͯ͋Δʂʯ Dʮࢲͷ΋ɺ͓αΠϑέʔλΠ͔ͩΒμϝͩΘɻʯ ͋ͳͨʮ·͔ͤΖͬʂ(ʯɾωɾ)ʯ͏ʔʂ(ʗɾωɾ)ʗʹΌʔʂʯ ABCDʮΩϟʔʂεςΩʔʂʯ 12೥8݄25೔౔༵೔

Slide 6

Slide 6 text

ษڧʹͳͬͨίʔυ 12೥8݄25೔౔༵೔

Slide 7

Slide 7 text

NDEFϝοηʔδಡΈࠐΈ private String getUrl(NdefMessage msg) { // NDEFϨίʔυ͔ΒTNFΛऔΓग़͢ NdefRecord[] records = msg.getRecords(); short tnf = records[0].getTnf(); if (tnf == NdefRecord.TNF_WELL_KNOWN) { return parseWellKnown(records[0]); } else if (tnf == NdefRecord.TNF_ABSOLUTE_URI) { return parseAbsolute(records[0]); } throw new IllegalArgumentException("Unknown TNF " + tnf); } 12೥8݄25೔౔༵೔

Slide 8

Slide 8 text

TNF = Type Name Format TNF_ABSOLUTE_URI URIΛϕʔεͱͨ͠λΠϓϑΟʔϧυ TNF_WELL_KNOWN ઃఆͨ͠RTDʹԠͯ͡ɺৼΔ෣͍͕มΘΔ 12೥8݄25೔౔༵೔

Slide 9

Slide 9 text

NDEFϨίʔυಡΈࠐΈ private String parseAbsolute(NdefRecord record) { byte[] payload = record.getPayload(); return new String(payload, Charset.forName("UTF-8")); } private String parseWellKnown(NdefRecord record) { // RTD Uri͔νΣοΫ if (Arrays.equals(record.getType(), NdefRecord.RTD_URI)) { byte[] payload = record.getPayload(); String prefix = prefixMap.get(payload[0]); byte[] uriData = Arrays.copyOfRange(payload, 1, payload.length); String uri = new String(uriData, Charset.forName("UTF-8")); return prefix.concat(uri); } throw new IllegalArgumentException("Not Support RTD"); } 12೥8݄25೔౔༵೔

Slide 10

Slide 10 text

RTD = Record Type Definition RTD_URI URIΛϕʔεͱͨ͠Payload 12೥8݄25೔౔༵೔

Slide 11

Slide 11 text

RecordsϚοϐϯά Name Offset Size Value Description Identifier code 0 1 byte URI identifier code The URI identifier code, as specified in Table 3. URI field 1 N UTF-8 string The rest of the URI, or the entire URI (if identifier code is 0x00). Ҿ༻ɿNFC URI RTD Technical Specification http://www.nfc-forum.org/specs/spec_list/#rtds 12೥8݄25೔౔༵೔

Slide 12

Slide 12 text

Decimal Hex Protocol 0 0x00 N/A 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: Decimal Hex Protocol 18 0x12 rtsp:// 19 0x13 urn: 20 0x14 pop: 21 0x15 sip: 22 0x16 sips: 23 0x17 tftp: 24 0x18 btspp:// 25 0x19 btl2cap:// 26 0x1A btgoep:// 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...255 0x24...0xFF RFU URI identifier code 12೥8݄25೔౔༵೔

Slide 13

Slide 13 text

private String getUrl(NdefMessage msg) { // NDEFϨίʔυ͔ΒTNFΛऔΓग़͢ NdefRecord[] records = msg.getRecords(); short tnf = records[0].getTnf(); if (tnf == NdefRecord.TNF_WELL_KNOWN) { // URLΛऔΓग़͢ return parseWellKnown(records[0]); } else if (tnf == NdefRecord.TNF_ABSOLUTE_URI) { // URLΛऔΓग़͢ return parseAbsolute(records[0]); } throw new IllegalArgumentException("Unknown TNF " + tnf); } 12೥8݄25೔౔༵೔

Slide 14

Slide 14 text

QRίʔυੜ੒͸ɺҎԼΛࢀߟʹ͠·ͨ͠ɻ ϒϩάɿ໌೔ͷ伴 ZXingΛ࢖ͬͯQRίʔυΛදࣔ͢Δ http://d.hatena.ne.jp/tomorrowkey/ 20091114/1258206013 12೥8݄25೔౔༵೔

Slide 15

Slide 15 text

public Bitmap createQRCodeByZxing(String contents, int size) throws WriterException { QRCodeWriter qrWriter = new QRCodeWriter(); // ҟͳΔܕͷ஋ΛೖΕΔͨΊgeneric͸࢖͑ͳ͍ @SuppressWarnings("rawtypes") Hashtable encodeHint = new Hashtable(); encodeHint.put(EncodeHintType.CHARACTER_SET, "shiftjis"); // Τϥʔम෮ϨϕϧΛࢦఆ encodeHint.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); BitMatrix qrCodeData = qrWriter.encode(contents, BarcodeFormat.QR_CODE, size, size, encodeHint); // QRίʔυͷbitmapը૾Λੜ੒ Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); bitmap.eraseColor(Color.argb(255, 255, 255, 255)); for(int x = 0; x < qrCodeData.getWidth(); x++) { for(int y = 0; y < qrCodeData.getHeight(); y++) { if(qrCodeData.get(x, y)) { // true͸Black bitmap.setPixel(x, y, Color.BLACK); } else { // false͸White bitmap.setPixel(x, y, Color.WHITE); } } } return bitmap; } 12೥8݄25೔౔༵೔

Slide 16

Slide 16 text

QRίʔυੜ੒ͷΠϝʔδ T F T T F T T F F F F F T T T F T F T T F T F T T F T T F T T F T F F F F F T F F F T T T F T T F F F T T F F F T T F T F F F T T F F T T F T F F T T T F F T F T 12೥8݄25೔౔༵೔

Slide 17

Slide 17 text

·ͱΊ̍ NDEFϝοηʔδ ࢓༷Λཧղ͢Δ TNF = Type Name Format RTD = Record Type Definition 12೥8݄25೔౔༵೔

Slide 18

Slide 18 text

·ͱΊ̎ QRίʔυ ZXing௒ศརʢ஗ͬʣ 12೥8݄25೔౔༵೔

Slide 19

Slide 19 text

͝ਗ਼ௌ ͋Γ͕ͱ͏͍͟͝·ͨ͠ 12೥8݄25೔౔༵೔