【Kotlin/Android Studio】NFCの実装方法!検出方法とデータの取得

この記事からわかること

  • Android Studio/KotlinNFC実装方法
  • NfcManager/NfcAdapter/Tag/ReaderCallbackクラス役割使い方
  • 検出方法とデータ取得
  • 運転免許証読み取る

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

Androidアプリで他の機器と通信してデータを送受信する手段の1つであるNFC機能を実装する方法をまとめていきます。NFC自体についてや種類などの詳細は以下の記事を参考にしてください。

AndroidアプリでNFCを実装のために必要なクラス

KotlinでNFC機能を実装するために必要になるクラスをまずは整理しておきます。

NfcManager

公式リファレンス:NfcManager

・NfcAdapterインスタンスを取得するためのマネージャー

NfcAdapter

公式リファレンス:NfcAdapter

・NFCデバイス(デバイス内にあるNFC通信が可能なハードウェア)の制御
・NFCタグ(通信対象)の検出
・データの書き込み/読み取り
・NFCビームのサポート
・ハードウェアの制御のインターフェースとなるので、インスタンスを取得するためにContextを要求
・目的は Tag オブジェクトを取得すること

Tag

・検出した NFCデバイスを表すモデル

ReaderCallback

・検出された後の処理を実装するコールバック

実装の流れ

まずはAndroid端末のアプリからNFCデバイス(タグ)を検出する流れをまとめていきます。検出するまでの手順は少なく以下のとおりです。

  1. パーミッションの追加
  2. 管理クラスとコールバックの定義
  3. 検出の開始

パーミッションの追加

まずはNFCを利用できるようにパーミッションを宣言します。


<uses-permission android:name="android.permission.NFC" />

管理クラスとコールバックの定義

続いてNFC絡みの機能を統括する管理クラスを作成します。引数からContextActivityを受け取れるようにしておきます。そしてその中に検出時のコールバック処理を実装していきます。ReaderCallback型のクラスを作成しonTagDiscoveredメソッド内に検出後に実装したい処理を記述します


class NfcService(private val context: Context, private val activity : Activity) {

    private class CustomReaderCallback : ReaderCallback {
        // NFCタグが検出されると呼ばれる
        override fun onTagDiscovered(tag: Tag) {
            Log.i("NFC Log", "タグを検出したよ")
            Log.i("NFC Log", tag.id.toString())
        }
    }
}

ReaderCallbackonTagDiscoveredメソッドはNFCタグが検出されると呼ばれるメソッドです。

検出の開始

検出を開始するためにはNfcAdapterenableReaderModeメソッドを呼び出す必要があります。NfcAdapterを取得するためにはNfcManagerが必要であり、NfcManagerを取得するためにgetSystemService(Context.NFC_SERVICE)を呼び出します。


private var nfcmanager: NfcManager? = null
private var nfcadapter: NfcAdapter? = null
private var callback: CustomReaderCallback? = null
  
fun scanStart() {
    callback = CustomReaderCallback()
    nfcmanager = context.getSystemService(Context.NFC_SERVICE) as? NfcManager
    nfcadapter = nfcmanager!!.defaultAdapter
    nfcadapter!!.enableReaderMode(activity, callback,
            NfcAdapter.FLAG_READER_NFC_F or 
                    NfcAdapter.FLAG_READER_NFC_A or 
                    NfcAdapter.FLAG_READER_NFC_B or 
                    NfcAdapter.FLAG_READER_NFC_V or 
                    NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS or 
                    NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK,null)
}

enableReaderModeメソッドの3番目の引数には検出したいNFCの種類を渡します。複数の種類を渡したい場合はor繋いで渡すことが可能です。

検出を終了するためにはdisableReaderModeメソッドを呼び出します。


fun scanStop() {
    nfcadapter!!.disableReaderMode(activity)
    callback = null
}

運転免許証を読み取る実装

これでAndroidアプリからNFCデバイスを検出できるようになったので実際に動作確認をしてみます。先ほどまでの実装の流れを流用して運転免許証を読み取るアプリを作成していきます。

注意点とポイント

実装コード全体

運転免許証はType-Bなので指定するのはFLAG_READER_NFC_BだけでOKです。今回はアプリ起動と同時にスキャンを開始させるためonResumeの中にスキャン開始を組み込んでいます。

class MainActivity : AppCompatActivity() {

    private var nfcService = NfcService(this,this)

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

    override fun onResume() {
        super.onResume()
        nfcService.scanStart()
    }

    override fun onPause() {
        super.onPause()
        nfcService.scanStop()
    }
}

class NfcService(private val context: Context, private val activity : Activity) {

    private var nfcmanager: NfcManager? = null
    private var nfcadapter: NfcAdapter? = null
    private var callback: CustomReaderCallback? = null

    fun scanStart() {
        callback = CustomReaderCallback()
        nfcmanager = context.getSystemService(Context.NFC_SERVICE) as? NfcManager
        nfcadapter = nfcmanager!!.defaultAdapter
        nfcadapter!!.enableReaderMode(activity, callback, NfcAdapter.FLAG_READER_NFC_B ,null)
    }

    fun scanStop() {
        nfcadapter!!.disableReaderMode(activity)
        callback = null
    }

    private class CustomReaderCallback : ReaderCallback {
        // NFCタグが検出されると呼ばれる
        override fun onTagDiscovered(tag: Tag) {
            Log.i("NFC Log", "タグを検出したよ")
            Log.i("NFC Log", "タグのID:" + tag.id.toString())
        }
    }
}

これを実際に実機へビルドして運転免許証をかざしてみると、読み取りが成功するとバイブレーションが作動し、ログには以下のように検出したタグのIDが表示されます。このIDはタグに振られているIDではなくAndroid側で対象タグを識別するために振られるIDなので読み取る度に変化していきます。

タグを検出したよ"タグのID:" [B@ffa0a95

運転免許証の中に格納されているデータも読み取ることができるようです。

参考記事:Androidで運転免許証のICを読み取る

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index