安装flutter依赖

需要配合flutter_nfc_kit插件来实现读取卡号的功能

flutter_nfc_kit: ^3.5.2

实现Android端功能

安卓Android依赖

dependencies {
    implementation 'com.github.devnied.emvnfccard:library:3.0.1'
}

创建插件

MainActivity中添加代码

package yourpackage

import android.app.PendingIntent
import android.content.Intent
import android.nfc.NfcAdapter
import android.nfc.Tag
import im.nfc.flutter_nfc_kit.FlutterNfcKitPlugin
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel

class MainActivity: FlutterActivity() {
      // 新增
    companion object {
        private val CHANNEL = "plugin.channel"
        private lateinit var methodChannel: MethodChannel
        private var nfcTag: Tag? = null
    }

      // 新增
    override fun onResume() {
        super.onResume()
        val adapter: NfcAdapter? = NfcAdapter.getDefaultAdapter(this)
        val pendingIntent: PendingIntent = PendingIntent.getActivity(
            this, 0, Intent(this, javaClass).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), PendingIntent.FLAG_MUTABLE
        )
        adapter?.enableForegroundDispatch(this, pendingIntent, null, null)
    }

      // 新增
    override fun onPause() {
        super.onPause()
        val adapter: NfcAdapter? = NfcAdapter.getDefaultAdapter(this)
        adapter?.disableForegroundDispatch(this)
    }

      // 新增
    override fun onNewIntent(intent: Intent) {
        val tag: Tag? = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
        nfcTag = tag
        tag?.apply(FlutterNfcKitPlugin::handleTag)
    }

      // 新增
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        methodChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
        methodChannel.setMethodCallHandler { call, result ->
            run {
                when (call.method) {
                    "getCardNumber" -> getCardNumber(call, result)
                    else -> result.notImplemented()
                }
            }
        }
    }

    // 新增
    private fun getCardNumber(call: MethodCall, result: MethodChannel.Result) {
        if (nfcTag != null) {
            val data = CardUtils.getCardNumber(nfcTag!!)
            result.success(data)
        } else {
          result.success("")
        }
    }
}

实现获取银行卡卡号方法

在和MainActivity同级新建一个CardUtils.ktMyProvider.kt文件

CardUtils.kt文件写入

package yourpackage

import android.nfc.Tag
import android.nfc.tech.IsoDep
import com.github.devnied.emvnfccard.parser.EmvTemplate

class CardUtils {
    companion object {
        fun getCardNumber(tag: Tag): String {
            var cardNumber = ""

            val isoDep: IsoDep = IsoDep.get(tag)

            try {
                if (!isoDep.isConnected) {
                    isoDep.connect()
                }
        
                 val provider = MyProvider()
                provider.setmTagCom(isoDep)

                val config: EmvTemplate.Config = EmvTemplate.Config()
                            .setContactLess(true)
                            .setReadAllAids(true)
                            .setReadTransactions(true)
                            .setReadCplc(false)
                            .setRemoveDefaultParsers(false)
                            .setReadAt(true)

                val parser = EmvTemplate.Builder()
                            .setProvider(provider)
                            .setConfig(config)
                            .build()

                val card = parser.readEmvCard()
                cardNumber = card.cardNumber
                isoDep.close()
            } catch (_: Exception) {} finally {
                try {
                    isoDep.close()
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }

            return cardNumber.toString()
        }
    }
}

MyProvider.kt写入

package yourpackage

import android.nfc.tech.IsoDep
import com.github.devnied.emvnfccard.exception.CommunicationException
import com.github.devnied.emvnfccard.parser.IProvider
import java.io.IOException

class MyProvider : IProvider {
    private var mTagCom: IsoDep? = null

    @Throws(CommunicationException::class)
    override fun transceive(pCommand: ByteArray?): ByteArray {
        val response: ByteArray
        try {
            response = mTagCom!!.transceive(pCommand)
        } catch (e: IOException) {
            throw CommunicationException(e.message)
        }

        return response
    }

    override fun getAt(): ByteArray {
        return mTagCom!!.historicalBytes
    }


    fun setmTagCom(TagCom: IsoDep?) {
        this.mTagCom = TagCom
    }
}

实现Flutter端通道

实现通道功能

lib目录下新建文件,我这里叫my_app_plugin.dart,写入代码

import 'package:flutter/services.dart';

class MyAppPlugin {
  static const MethodChannel methodChannel = MethodChannel("plugin.channel");
  
  static Future<String> get cardNumber {
    return await methodChannel.invokeMethod<String>("getCardNumber")
  }
}

使用示例

import 'package:flutter/material.dart';
import 'package:flutter_nfc_kit/flutter_nfc_kit.dart';
import './my_app_plugin.dart';

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<StatefulWidget> createState() => _HomePageState();

}

class _HomePageState extends State<HomePage> {
    StreamSubscription<NFCTag>? tagSubscription;
  
  String? cardNumber;
  
  @override
  void initState() {
    super.initState();
  
    tagSubscription = FlutterNfcKit.tagStream.listen((NFCTag tag) async {
      String result = await MyAppPlugin.cardNumber;
  
         if (result.isNotEmpty()) {
        setState({
          cardNumber = result;
        });
      }
    });
  }
  
  @override
  void dispose() {
    tagSubscription?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
          child: Row(
            children: [
            Text("卡号:${cardNumber ?? ""}")
          ]
        )
      ),
    );
  }

}
最后修改:2025 年 04 月 01 日
如果觉得我的文章对你有用,请随意赞赏