Android端末を使って、NFC Tagに書き込むプログラムをkotlinで書いてみた

## 経緯
ふと、AndroidでNFCタグを書き込むことをやりたくなった。
数年前にJavaで書いて以来すっかり忘れてしまったので、kotlinでNFCタグに、NDEFで書き込むアプリを書いてみました。

## 環境
Android Stusio 3.1.3
Qua Phone (Android 7.0)
NFCタグ

## コード
パーミッションとして、android.permission.NFCを要求
ハードウェアとして、nfcを搭載していることを明記したぐらいです。
注意：NFCのサンプルコードでは、ここにintentでタグを読んだ際に、アプリが起動するようにintentフィルターを書いたりするが、今回のコードは、書き込みなので、アプリ起動していない時に、書き込みしないようにするため、ここには、intentフィルターは書きません。

```xml:AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="jp.eguchi.android.nfc_writer">

    <uses-permission android:name="android.permission.NFC" />
    <uses-feature android:name="android.hardware.nfc" android:required="true" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
```

```kotlin:MainActivity.kt
package jp.eguchi.android.nfc_writer

// Androidで、NFCタグに書き込んでみる Kotlin
// Progmramed by Kazuyuki Eguchi

import android.app.PendingIntent
import android.content.Intent
import android.content.IntentFilter
import android.nfc.*
import android.nfc.tech.Ndef
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.Log

class MainActivity : AppCompatActivity() {

    private val TAG: String = "Debug"

    private var intentFiltersArray: Array<IntentFilter>? = null
    private var techListsArray: Array<Array<String>>? = null
    private var mAdapter: NfcAdapter? = null
    private var pendingIntent: PendingIntent ? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        Log.d(TAG,"onCreate")

        val intent = Intent(this, javaClass).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
        pendingIntent = PendingIntent.getActivity(this,123,intent,0)


        val ndef = IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED).apply {
            this.addDataType("*/*")
        }

        intentFiltersArray = arrayOf(ndef)

        techListsArray = arrayOf(
                arrayOf(android.nfc.tech.Ndef::class.java.name),
                arrayOf(android.nfc.tech.NdefFormatable::class.java.name))

        mAdapter = NfcAdapter.getDefaultAdapter(applicationContext)
    }

    override fun onResume() {
        super.onResume()
        Log.d(TAG,"onRusume()")
        mAdapter?.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray)
    }

    override fun onPause() {
        super.onPause()
        Log.d(TAG,"onPause()")
        mAdapter?.disableForegroundDispatch(this)

    }

    override fun onNewIntent(intent: Intent) {
        Log.d(TAG,"onNewIntent")

        if (intent == null) {
            return
        }

        Log.d(TAG,"Action" + intent.action)

        if(NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.action) || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.action)) {

            val tag = intent.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG)

            if (tag == null) {
                return
            }

            val ndef = Ndef.get(tag);

            if(ndef == null) {
                return;
            }

            if(ndef.isWritable) {
                Log.d(TAG,"is Writable")

                try {
                    val record = NdefRecord.createTextRecord("en","Hello")
                    val msg = NdefMessage(record);

                    ndef.connect()
                    ndef.writeNdefMessage(msg)
                    ndef.close()
                } catch (e:FormatException) {
                    Log.d(TAG,e.toString())
                }
            }
        }
    }
}

```

## 参考：読み込みコード(onNewIntent部分のみ）
```kotlin:MainActivity.kt
    override fun onNewIntent(intent: Intent) {
        Log.d(TAG,"onNewIntent")

        if (intent == null) {
            return
        }

        Log.d(TAG,"Action" + intent.action)

        if(NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.action) || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.action)) {

            val tag = intent.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG)

            if (tag == null) {
                return
            }

            val ndef = Ndef.get(tag);

            if(ndef == null) {
                return;
            }

            val raws = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);

            if(raws == null){
                return;
            }

            var msgs = arrayOfNulls<NdefMessage>(raws.size)

            for(i in 0..raws.size-1) {
                msgs[i] = raws.get(i) as NdefMessage?
                for(records in msgs) {
                    for(record in records?.records!!){
                        Log.d(TAG,"TNF=" + record.tnf)
                        Log.d(TAG,"mime=" + record.toMimeType())
                        Log.d(TAG,"payload=" + String(record.payload));
                    }
                }
            }
        }
    }
```