安装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.kt
、MyProvider.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 ?? ""}")
]
)
),
);
}
}