dtb_link 0.1.19+42
dtb_link: ^0.1.19+42 copied to clipboard
DTB Link - utility app enabling applications to connect and integrate with NFC card readers over Bluetooth
example/lib/main.dart
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:dtb_link/dtb_link.dart';
enum EasyKey { sKey, echo, saleTran, voidTran }
typedef OnDevice = Function;
void main() {
runApp(const MaterialApp(home: MyApp()));
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown';
DtbLink dtbLink = DtbLink();
DataInitRet? initData;
List<BluetoothDevice> deviceList = [];
TextEditingController controller = TextEditingController();
ScrollController scrollController = ScrollController();
OnDevice? onDevice;
Map<String, dynamic>? lastTran;
@override
void initState() {
super.initState();
dtbLink.dtbLibInit(const bool.fromEnvironment("dart.vm.product") ? InitType.production : InitType.staging);
WidgetsBinding.instance.addPostFrameCallback((_) {
dtbLink.terminalInitData().then((data) {
debugPrint("initData: ${data?.toJson()}");
initData = data;
});
dtbLink.onEvent((onData) {
debugPrint("onData: $onData");
Map<String, dynamic> retData = json.decode(onData);
if (retData["command"] == "bluetooth.device_found") {
String? deviceId = retData["ret"]?["device_id"];
String? deviceName = retData["ret"]?["device_name"];
if (deviceId != null && deviceName != null) {
final device = BluetoothDevice(deviceId: deviceId, deviceName: deviceName);
if (!deviceList.contains(device)) {
setState(() {
deviceList.add(device);
addMessage("${device.toJson()}");
});
onDevice?.call();
}
}
} else if (retData["command"] == "bluetooth.download_file.pregress") {
int? current = retData["ret"]?["current"];
int? total = retData["ret"]?["total"];
debugPrint("current: $current, total: $total");
}
});
initPlatformState();
});
}
Future<void> initPlatformState() async {
String platformVersion;
try {
debugPrint("platformVersion before");
platformVersion = await dtbLink.getPlatformVersion() ?? 'Unknown platform version';
debugPrint("platformVersion: $platformVersion");
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("DTB Link Flutter Demo $_platformVersion")),
body: Padding(
padding: const EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Wrap(
children: [
const Text("Bluetooth"),
DtbButton(
onPressed: () {
deviceList.clear();
addMessage("=>Search device");
showSearchDialog(context);
dtbLink.bluetoothStartSearch();
},
title: "Search device",
),
DtbButton(
onPressed: () {
addMessage("=>Is connected");
dtbLink.bluetoothIsConnected().then((result) {
addMessage("<=$result");
});
},
title: "Is connected",
),
DtbButton(
onPressed: () {
addMessage("=>Contactless upload");
dtbLink.bluetoothContactlessFileUpload().then((result) {
addMessage("<=$result");
});
},
title: "Contactless upload",
),
DtbButton(
onPressed: () {
addMessage("=>EMV upload");
dtbLink.bluetoothEmvFileUpload().then((result) {
addMessage("<=$result");
});
},
title: "EMV upload",
),
DtbButton(
onPressed: () {
addMessage("=>Device data");
dtbLink.bluetoothDeviceData().then((device) {
addMessage("<=${device.toJson()}");
});
},
title: "Device Data",
),
DtbButton(
onPressed: () {
addMessage("=>Reconnect Device");
dtbLink.bluetoothReconnectDevice().then((ret) {
addMessage("<=$ret}");
});
},
title: "Reconnect Device",
),
DtbButton(
onPressed: () {
addMessage("=>Card read");
dtbLink.traceNo.then((traceNo) {
dtbLink.bluetoothCardRead(amount: "100", tranType: 1, traceNo: traceNo).then((ret) {
addMessage("<=$ret");
});
});
},
title: "Card read",
),
],
),
),
),
),
Expanded(
child: Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Wrap(
children: [
const Text("Terminal"),
DtbButton(
onPressed: () {
addMessage("=>Echo test");
dtbLink.terminalEchoTest().then((ret) {
addMessage("<=$ret");
});
},
title: "Echo Test",
),
DtbButton(
onPressed: () {
addMessage("=>Init Data");
dtbLink.terminalInitData().then((ret) {
addMessage("<=${ret?.toJson()}");
});
},
title: "Init Data",
),
DtbButton(
onPressed: () {
addMessage("=>Init terminal");
dtbLink.terminalDoInit(terminalId: "Prepared Terminal ID", trc: "TRC code").then((ret) {
// dtbLink.terminalDoInit(terminalId: "KP000142", trc: "021655").then((ret) {
addMessage("<=${ret.toJson()}");
});
},
title: "Init Terminal",
),
DtbButton(
onPressed: () {
addMessage("=>Sync Key");
dtbLink.syncKey().then((ret) {
addMessage("<=${ret.toJson()}");
});
},
title: "Sync Key",
),
DtbButton(
onPressed: () {
addMessage("=>Do Sale");
dtbLink.doSale(context: context, amount: 100).then((ret) {
addMessage("<=$ret");
debugPrint("ret: $ret");
if (ret["code"] == 0) {
Map<String, dynamic> tranRet = ret["ret"];
if (tranRet["resp_code"] == "000") {
debugPrint("tranRet: $tranRet");
setState(() {
lastTran = tranRet;
});
}
} else {
setState(() {
lastTran = ret;
});
}
});
},
title: "Do Sale",
),
DtbButton(
onPressed: lastTran != null ? doVoid : null,
title: "Do Void",
),
DtbButton(
onPressed: () {
addMessage("=>Do User Cancel");
dtbLink.doCancelCardRead();
},
title: "Do UserCancel",
),
],
),
),
),
),
],
),
),
Expanded(
child: SingleChildScrollView(
controller: scrollController,
child: TextField(
maxLines: null,
enabled: false,
controller: controller,
style: const TextStyle(fontSize: 11),
),
),
),
],
),
),
);
}
doVoid() {
addMessage("=>Do Void");
debugPrint("lastTran: $lastTran");
String? amountStr = lastTran?["amount"];
String? encTrack2 = lastTran?["enc_track"];
String? rrn = lastTran?["rrn"];
String? authCode = lastTran?["auth_code"];
String? traceNo = lastTran?["trace_no"];
if (amountStr != null && encTrack2 != null && rrn != null && authCode != null && traceNo != null) {
dtbLink.doVoid(amountStr: amountStr, encTrack2: encTrack2, rrn: rrn, authCode: authCode, traceNo: traceNo).then(
(ret) {
addMessage("<=$ret");
},
);
}
}
addMessage(String msg) {
controller.text = "${controller.text}\n$msg";
Future.delayed(const Duration(milliseconds: 200), () {
scrollController.animateTo(scrollController.position.maxScrollExtent,
duration: const Duration(milliseconds: 200), curve: Curves.easeInOut);
});
}
showSearchDialog(BuildContext context) {
showDialog(
context: context,
builder: (context) {
return StatefulBuilder(
builder: (BuildContext context, void Function(void Function()) setState) {
onDevice = () {
setState(() {});
};
Widget buildDevice(BluetoothDevice device) {
return DtbButton(
title: '${device.deviceName}\n${device.deviceId}',
onPressed: () {
Navigator.of(context).pop();
onDevice = null;
dtbLink.connectDevice(device);
},
);
}
List<Widget> buildList() {
List<Widget> list = [];
for (BluetoothDevice device in deviceList) {
list.add(buildDevice(device));
}
return list;
}
return AlertDialog(
title: const Text('Dialog Title'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: buildList(),
),
);
},
);
},
);
}
}
class DtbButton extends ElevatedButton {
DtbButton({
super.key,
super.onPressed,
required String title,
}) : super(
child: Text(title, style: const TextStyle(fontSize: 11)),
style: ElevatedButton.styleFrom(
elevation: 0.5,
minimumSize: const Size.fromHeight(38),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4), // <-- Radius
),
),
);
}