Flutter智能卡读写插件flutter_pcsc_linux的使用
Flutter智能卡读写插件flutter_pcsc_linux的使用
flutter_pcsc_linux
是 flutter_pcsc
插件在 Linux 平台上的实现。它允许开发者在 Flutter 应用中读取和写入智能卡。
使用方法
该插件被官方推荐使用(通过 endorsed federated plugin),这意味着你可以直接使用 flutter_pcsc
,而这个包会在你的应用中自动包含 flutter_pcsc_linux
。
示例代码
以下是一个完整的示例代码,展示了如何使用 flutter_pcsc_linux
插件来读取智能卡的序列号。
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_pcsc_linux/flutter_pcsc_linux.dart';
import 'dart:async';
import 'package:flutter_pcsc_platform_interface/flutter_pcsc_platform_interface.dart';
void main() {
MyApp? myApp;
runZonedGuarded(() async {
PcscLinux.registerWith(); // 注册插件
WidgetsFlutterBinding.ensureInitialized(); // 确保初始化
FlutterError.onError = (FlutterErrorDetails details) {
FlutterError.dumpErrorToConsole(details); // 错误处理
myApp?.addError(details.toString());
};
runApp(myApp = MyApp());
}, (Object error, StackTrace stack) {
print(error.toString()); // 打印错误信息
myApp?.addError(error.toString());
});
}
class MyApp extends StatelessWidget {
final GlobalKey<_MyAppBodyState> _myAppKey = GlobalKey();
MyApp({Key? key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('智能卡读写插件示例'),
),
body: MyAppBody(key: _myAppKey)),
);
}
void addError(String msg) {
_myAppKey.currentState?.addMessage(Message.error(msg));
}
}
class MyAppBody extends StatefulWidget {
const MyAppBody({required Key key}) : super(key: key);
[@override](/user/override)
_MyAppBodyState createState() {
return _MyAppBodyState();
}
}
// 消息类型
enum MessageType { info, error }
class Message {
final String content;
final MessageType type;
Message(this.type, this.content);
static info(String content) {
return Message(MessageType.info, content);
}
static error(String content) {
return Message(MessageType.error, content);
}
}
class _MyAppBodyState extends State<MyAppBody> {
static const List<int> getCardSerialNumberCommand = [0xFF, 0xCA, 0x00, 0x00, 0x00]; // 获取序列号命令
final ScrollController _scrollController = ScrollController();
final List<Message> _messages = [];
[@override](/user/override)
void initState() {
super.initState();
getCardSerialNumber();
}
void addMessage(Message m) {
setState(() {
_messages.add(m);
});
}
Future<void> getCardSerialNumber() async {
int ctx = await PcscPlatform.instance
.establishContext(PcscConstants.CARD_SCOPE_USER); // 建立上下文
Map<String, dynamic>? card;
try {
List<String> readers = await PcscPlatform.instance.listReaders(ctx); // 列出读卡器
if (readers.isEmpty) {
setState(() {
_messages.add(Message.error('未检测到任何读卡器'));
});
} else {
String reader = readers[0];
setState(() {
_messages.add(Message.info('使用读卡器: $reader'));
});
card = await PcscPlatform.instance.cardConnect(ctx, reader,
PcscConstants.SCARD_SHARE_SHARED, PcscConstants.SCARD_PROTOCOL_ANY); // 连接卡片
var response = await PcscPlatform.instance.transmit(card['h_card'],
card['active_protocol'], getCardSerialNumberCommand); // 发送获取序列号命令
var sw = response.sublist(response.length - 2);
var sn = response.sublist(0, response.length - 2);
if (sw[0] != 0x90 || sw[1] != 0x00) {
setState(() {
_messages.add(Message.error('卡片返回错误: ${hexDump(sw)}'));
});
} else {
setState(() {
_messages
.add(Message.info('卡片序列号是: ${hexDump(sn)}'));
_messages.add(Message.info('完成'));
});
}
}
} finally {
if (card != null) {
try {
await PcscPlatform.instance
.cardDisconnect(card['h_card'], PcscConstants.SCARD_RESET_CARD); // 断开卡片连接
} on Exception catch (e) {
setState(() {
_messages.add(Message.error(e.toString()));
});
}
}
try {
await PcscPlatform.instance.releaseContext(ctx); // 释放上下文
} on Exception catch (e) {
setState(() {
_messages.add(Message.error(e.toString()));
});
}
}
}
static String hexDump(List<int> csn) {
return csn
.map((i) => i.toRadixString(16).padLeft(2, '0').toUpperCase()) // 转换为十六进制字符串
.join(' ');
}
_scrollToBottom() {
_scrollController.jumpTo(_scrollController.position.maxScrollExtent); // 滚动到底部
}
[@override](/user/override)
Widget build(BuildContext context) {
TextStyle errorStyle = const TextStyle(color: Colors.red);
WidgetsBinding.instance?.addPostFrameCallback((_) => _scrollToBottom());
return Row(crossAxisAlignment: CrossAxisAlignment.start, children: [
Expanded(
child: Column(children: [
Expanded(
child: ListView(
controller: _scrollController,
children: _messages
.map((e) => Text(e.content,
style: e.type == MessageType.error ? errorStyle : null)) // 显示消息
.toList())),
Container(
margin: const EdgeInsets.all(10),
child: ElevatedButton(
onPressed: () async {
await tryAgain();
},
child: const Text("重新尝试")))
]))
]);
}
tryAgain() async {
setState(() {
_messages.clear();
});
await getCardSerialNumber(); // 重新尝试读取序列号
}
}
更多关于Flutter智能卡读写插件flutter_pcsc_linux的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter智能卡读写插件flutter_pcsc_linux的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
flutter_pcsc_linux
是一个用于在 Linux 平台上通过 PC/SC 接口读写智能卡(Smart Card)的 Flutter 插件。它允许你在 Flutter 应用程序中与智能卡进行交互,例如读取卡数据、写入数据、发送 APDU 命令等。
以下是如何使用 flutter_pcsc_linux
插件的基本步骤:
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 flutter_pcsc_linux
依赖:
dependencies:
flutter:
sdk: flutter
flutter_pcsc_linux: ^0.1.0 # 请检查最新版本
然后运行 flutter pub get
以获取依赖。
2. 导入插件
在你的 Dart 文件中导入插件:
import 'package:flutter_pcsc_linux/flutter_pcsc_linux.dart';
3. 初始化 PC/SC 上下文
在使用插件之前,你需要初始化 PC/SC 上下文:
final pcsc = FlutterPcscLinux();
await pcsc.initializeContext();
4. 列出可用的读卡器
你可以列出系统中可用的智能卡读卡器:
final readers = await pcsc.listReaders();
print('Available readers: $readers');
5. 连接到读卡器
选择一个读卡器并连接到它:
final reader = readers.first; // 选择第一个读卡器
await pcsc.connect(reader);
6. 发送 APDU 命令
你可以通过发送 APDU 命令与智能卡进行交互。例如,发送一个简单的 SELECT 命令:
final command = [0x00, 0xA4, 0x04, 0x00, 0x00]; // SELECT 命令
final response = await pcsc.transmit(command);
print('Response: $response');
7. 断开连接并释放资源
完成操作后,断开与读卡器的连接并释放资源:
await pcsc.disconnect();
await pcsc.releaseContext();
8. 处理错误
在实际使用中,可能会遇到各种错误,例如读卡器不可用、智能卡未插入等。你应该适当地处理这些错误:
try {
await pcsc.connect(reader);
} catch (e) {
print('Failed to connect to reader: $e');
}
9. 完整的示例代码
以下是一个完整的示例代码,展示了如何使用 flutter_pcsc_linux
插件与智能卡进行交互:
import 'package:flutter/material.dart';
import 'package:flutter_pcsc_linux/flutter_pcsc_linux.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final pcsc = FlutterPcscLinux();
try {
await pcsc.initializeContext();
final readers = await pcsc.listReaders();
print('Available readers: $readers');
if (readers.isNotEmpty) {
final reader = readers.first;
await pcsc.connect(reader);
final command = [0x00, 0xA4, 0x04, 0x00, 0x00]; // SELECT 命令
final response = await pcsc.transmit(command);
print('Response: $response');
await pcsc.disconnect();
} else {
print('No readers available');
}
} catch (e) {
print('Error: $e');
} finally {
await pcsc.releaseContext();
}
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter PC/SC Linux Example'),
),
body: Center(
child: Text('Check the console for output'),
),
),
);
}
}