【Kotlin/Android Studio】NFCの実装方法!検出方法とデータの取得
この記事からわかること
- Android Studio/KotlinでNFCを実装方法
- NfcManager/NfcAdapter/Tag/ReaderCallbackクラスの役割と使い方
- 検出方法とデータ取得
- 運転免許証を読み取る
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
環境
- Android Studio:Flamingo
- Android:13
- Kotlin:1.8.20
Androidアプリで他の機器と通信してデータを送受信する手段の1つであるNFC機能を実装する方法をまとめていきます。NFC自体についてや種類などの詳細は以下の記事を参考にしてください。
おすすめ記事:NFCとは?規格の種類や違い、NDEFの中身について
AndroidアプリでNFCを実装のために必要なクラス
KotlinでNFC機能を実装するために必要になるクラスをまずは整理しておきます。
NfcManager
・NfcAdapterインスタンスを取得するためのマネージャー
NfcAdapter
・NFCデバイス(デバイス内にあるNFC通信が可能なハードウェア)の制御
・NFCタグ(通信対象)の検出
・データの書き込み/読み取り
・NFCビームのサポート
・ハードウェアの制御のインターフェースとなるので、インスタンスを取得するためにContextを要求
・目的は Tag オブジェクトを取得すること
Tag
・検出した NFCデバイスを表すモデル
ReaderCallback
・検出された後の処理を実装するコールバック
実装の流れ
まずはAndroid端末のアプリからNFCデバイス(タグ)を検出する流れをまとめていきます。検出するまでの手順は少なく以下のとおりです。
- パーミッションの追加
- 管理クラスとコールバックの定義
- 検出の開始
パーミッションの追加
まずはNFCを利用できるようにパーミッションを宣言します。
<uses-permission android:name="android.permission.NFC" />
管理クラスとコールバックの定義
続いてNFC絡みの機能を統括する管理クラスを作成します。引数からContext
とActivity
を受け取れるようにしておきます。そしてその中に検出時のコールバック処理を実装していきます。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())
}
}
}
ReaderCallback
のonTagDiscovered
メソッドはNFCタグが検出されると呼ばれるメソッドです。
検出の開始
検出を開始するためにはNfcAdapter
のenableReaderMode
メソッドを呼び出す必要があります。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デバイスを検出できるようになったので実際に動作確認をしてみます。先ほどまでの実装の流れを流用して運転免許証を読み取るアプリを作成していきます。
注意点とポイント
- エミュレーターではNFCの動作確認はできない
- アプリは実機にビルドする
- 運転免許証さえあればNFCデバイスの準備はOK
実装コード全体
運転免許証は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
運転免許証の中に格納されているデータも読み取ることができるようです。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。