2013年2月4日月曜日

Google Playに誘導するNFCタグを作る




Google Playに誘導するNFCタグを作りました。
イベントなどで自作アプリを紹介する際、実際にダウンロードしてもらう良い手段だと思います。


Google PlayへのURL

Google PlayへのURLはこちらを参照。
Linking to Product Detail Page:
http://developer.android.com/distribute/googleplay/promote/linking.html


以下は詳細画面へのURLの例です。
From a web site:
http://play.google.com/store/apps/details?id=<package_name>
From an Android app:
market://details?id=<package_name>


Google Playアプリは「http:」でも反応します。Android端末以外のユーザーにも見てもらうために、「market:」ではなく「http:」を使用することをお薦めします。


NFCタグへの書き込み

Google Playアプリ詳細画面へのURLをNFCタグに書き込みます。
NDEF規格への書き込み例です。
手順
  1. NdefRecord#createUriでNDEFレコードを生成
  2. NDEFメッセージを生成
  3. Writeする

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
NdefRecord rtdUriRecords[] = {
        // Google Playの詳細ページURL
};
NdefMessage ndefMsg = new NdefMessage(rtdUriRecords);
Ndef ndef = Ndef.get(tag);
 
if (ndef.isWritable()) {
    try {
        ndef.connect();
        ndef.writeNdefMessage(ndefMsg);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (FormatException e) {
        e.printStackTrace();
    } finally {
        try {
            ndef.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2013年2月3日日曜日

NFCタグを読み込む NdefMessage編

NDEF規格のNFCタグを読み込む方法をまとめます。

参考:NFCタグにURLを書き込む
http://baroqueworksdevjp.blogspot.jp/2013/02/nfcurl.html


Intent-filterの記載

NDEF規格のNFCタグをハンドリングするために、android.nfc.action.NDEF_DISCOVEREDを追加
1
2
3
4
5
<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="http" />
</intent-filter>



IntentからNDEF情報を取得する

IntentのExtra情報:NfcAdapter.EXTRA_NDEF_MESSAGESから、NdefRecordを取得する。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if (getIntent().getAction().equals(NfcAdapter.ACTION_NDEF_DISCOVERED)) {
    Parcelable[] rawMsgs = getIntent().getParcelableArrayExtra(
            NfcAdapter.EXTRA_NDEF_MESSAGES);
    if (rawMsgs != null) {
        for (Parcelable pa : rawMsgs) {
            NdefMessage ndefMsg = (NdefMessage) pa;
            NdefRecord[] records = ndefMsg.getRecords();
            for (NdefRecord rec : records) {
                android.util.Log.e("", "NDEF toString = " + rec.toString());
                // Added in API level 16
                android.util.Log.e("", "NDEF toMimeType = " + rec.toMimeType());
                // Added in API level 16
                android.util.Log.e("", "NDEF toUri = " + rec.toUri());
            }
        }
    }
}

NdefRecord#toMimeType()とNdefRecord#toUri()はAPI Level 16から使用可能。
それ以前のAndroid versionの場合、自分で生成しないといけません。
以下のソースが参考になるかも。
\frameworks\base\core\java\android\nfc\NdefRecord.java


注意点

こんなバグがあるから気を付けよう。
Issue 36968: Scanning an NFC tag without a ndef record results in null pointer exception
http://code.google.com/p/android/issues/detail?id=36968

2013年2月2日土曜日

NFCタグにURLを書き込む

NFCタグシールを購入しました。
価格は一枚あたり約300円でした




このNFCタグへURLの書き込みを行いました。

NdefFormatableのハンドリング

NdefFormatableのTag配信をハンドリングするための準備
AndroidManifest.xmlの記載
NFCを使うためのPermision
1
2
3
4
5
<uses-permission android:name="android.permission.NFC" />
 
<uses-feature
    android:name="android.hardware.nfc"
    android:required="true" />


Intent-filterの追加
1
2
3
4
5
6
7
8
9
<intent-filter>
    <action android:name="android.nfc.action.TECH_DISCOVERED" />
 
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>
 
<meta-data
    android:name="android.nfc.action.TECH_DISCOVERED"
    android:resource="@xml/nfc_tech_list" />


Tech-ListのXmlを作成
1
2
3
4
5
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.NdefFormatable</tech>
    </tech-list>
</resources>


Activity側でTagを受信
IntentからTag情報を取得
1
2
3
if (getIntent().getAction().equals(NfcAdapter.ACTION_TECH_DISCOVERED)) {
    Tag tag = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
}


NFCタグへURLを書き込む
NdefFormatable.get(tag)でNdefFormatableクラスを取得し、write処理を行う。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public void write(Tag tag, String uri) {
    NdefRecord rtdUriRecords[] = {
            NdefRecord.createUri(uri)
    };
    NdefFormatable ndef = NdefFormatable.get(tag);
    NdefMessage message = new NdefMessage(rtdUriRecords);
    try {
        ndef.connect();
        ndef.format(message);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (FormatException e) {
        e.printStackTrace();
    } finally {
        try {
            ndef.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}