6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-06-17

経緯

ふと、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フィルターは書きません。

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>
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部分のみ)

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));
                    }
                }
            }
        }
    }
6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?