1、功能实现
ios和安卓双端都实现蓝牙自定义打印
2、成品展示
周征喻分享的视频
安卓打印
设备清单:设备TSC台式打印机(碳带式),手机,数据线,电脑
技术清单:flutter, tscsdk,
步骤拆分详解:
1、引入官方sdk
2、flutter建立与原生通讯 (dart)
var appIsexitBlue = MethodChannel('app_isexit_blue');
Future<void> iSappIsexitBlue() async {
//初始蓝牙
try {
final Map<String, dynamic> arguments = {'key1': "111", 'key2': "222"};
final result = await appIsexitBlue.invokeMethod('getResult2', arguments);
}
}
3、原生底层接收搜索蓝牙设备(java)
这一步目的的场景是:用户初始进来页面时候,点击连接设备按钮,然后调用底层蓝牙搜索,并且返回搜索到的蓝牙设备
new MethodChannel(Objects.requireNonNull(getFlutterEngine()).getDartExecutor().getBinaryMessenger(), "app_isexit_blue")
.setMethodCallHandler((call, result) -> {
if (call.method.equals("getResult2")) {
Set<BluetoothDevice> bondedDevices = getBondedDevices();
List<Map<String, String>> deviceList = new ArrayList<>(); //总连接设备
for (BluetoothDevice device : bondedDevices) {
Map<String, String> deviceInfo = new HashMap<>();
deviceInfo.put("DeviceName", device.getName());
deviceInfo.put("DeviceAddress", device.getAddress());
System.out.println("Device Name: 蓝牙" + device.getName() + ", Device Address: 蓝牙" + device.getAddress());
deviceList.add(deviceInfo);
}
Map<String, String> allInfo = new HashMap<>();
System.out.println("全部蓝牙设备" + deviceList);
result.success(deviceList);
}else{
result.success(null);
}
});
4、缓存已经连接过的设备
下次进来页面默认为上一次选择的蓝牙
showModalBottomSheet(
context: context,
backgroundColor: Colors.transparent,
builder: (BuildContext context) {
return BrnCommonActionSheet(
title: "请选择蓝牙设备",
actions: actions,
clickCallBack: (
int index,
BrnCommonActionSheetItem actionEle,
) {
setState(() {
print("选择结果");
print(bluedevices[index]['DeviceAddress']);
print(bluedevices[index]['DeviceName']);
psbluedevices = bluedevices[index]['DeviceAddress'];
psbluedevicesName = bluedevices[index]['DeviceName'];
SharedPreferencesUtils.savePreference(
"storeBlueIp", psbluedevices);
SharedPreferencesUtils.savePreference(
"storeBlueName", psbluedevicesName);
});
FocusManager.instance.primaryFocus?.unfocus();
},
);
});
5、指定蓝牙发送打印指令(建立通信和上一面一样的)
printPage是指发送打印的命令方法
new MethodChannel(Objects.requireNonNull(getFlutterEngine()).getDartExecutor().getBinaryMessenger(), "app_test_channel")
.setMethodCallHandler((call, result) -> {
if (call.method.equals("getResult1")) {
if (!call.hasArgument("key3")) {
result.error("ERROR_CODE", "失败调用:未找到设备或设备信息为空", null);
return;
}
if (call.hasArgument("key3")&&call.hasArgument("key1")&&call.hasArgument("key2")) {
String str = call.argument("key1");
String stycode = call.argument("key2");
String newipadress = call.argument("key3");
TSCActivity PrintDll = new TSCActivity();
try {
//------------
System.setProperty("jna.encoding", "GBK");// 支持中文
String connectResult = PrintDll.openport(newipadress); //BT
//如果connectResult不等于1
if (!"1".equals(connectResult)) {
PrintDll.closeport();
result.error("ERROR_CODE", "打印机未连接,请重新连接", null);
return;
}
//==============
JSONArray array = JSONUtil.parseArray(str);
// 改为同步执行,逐个打印
for (Object obj : array) {
JSONObject jsonObject = (JSONObject) obj;
printPage(jsonObject, PrintDll, newipadress);
}
System.out.println("全部执行结束");
result.success("good");
PrintDll.closeport();
//-----------------
} catch (Exception e) {
result.error("ERROR_CODE", "打印失败:"+e, null);
} finally {
// PrintDll.closeport();
}
} else {
System.out.println("错误1");
// 如果没有提供所需的参数,可以返回一个错误给Flutter
result.error("MISSING_ARGUMENTS", "getResult方法需要key1和key2参数", null);
}
} else {
result.notImplemented();
}
});
public void printPage(JSONObject jsonObject, TSCActivity PrintDll, String newipadress) {
try {
PrintDll.clearbuffer();
String SC = "数量"; //数量
byte[] btSC = new byte[1024];
try {
btSC = SC.getBytes("GB2312");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//切割
String title1 = jsonObject.getStr("goodsName");
String[] parts = splitStringByLength(title1, 11);
String bianmaOne = jsonObject.getStr("printUserName");
byte[] bianmaOnebtSC = new byte[1024];
try {
bianmaOnebtSC = bianmaOne.getBytes("GB2312");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String bianmaTwo = jsonObject.getStr("bin");
byte[] bianmaTwobtSC = new byte[1024];
try {
bianmaTwobtSC = bianmaTwo.getBytes("GB2312");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String time = jsonObject.getStr("printTime");
byte[] timebtSC = new byte[1024];
try {
timebtSC = time.getBytes("GB2312");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String Cang = "圆通4楼";
byte[] CangbtSC = new byte[1024];
try {
CangbtSC = Cang.getBytes("GB2312");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// start
PrintDll.sendcommand("SIZE 100mm,53mm\n");
//
PrintDll.sendcommand("CLS\n");
List<String> list = new ArrayList<>();
for (int index = 0; index < parts.length; index++) {
String part = parts[index];
byte[] sc = new byte[1024];
try {
sc = part.getBytes("GB2312");
PrintDll.sendcommand("TEXT 200," + (40 + index * 30) + ",\"FONT001\",0,2,2,\""); //中文
PrintDll.sendcommand(sc);
PrintDll.sendcommand("\"\n");
System.out.println(part);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
//调试
PrintDll.sendcommand("BAR 40,160,580,4\n");//横向
PrintDll.sendcommand("BAR 40,290,580,4\n");//横向
PrintDll.sendcommand("BAR 180,30,4,130\n");//竖向 zheng
PrintDll.sendcommand("BAR 630,30,4,370\n");//竖向
PrintDll.sendcommand("TEXT 60,40,\"FONT001\",0,2,2,\""); //中文
PrintDll.sendcommand(btSC);
PrintDll.sendcommand("\"\n");
PrintDll.printerfont(60, 90, "3", 0, 1, 1, jsonObject.getStr("packNum"));
PrintDll.sendcommand("TEXT 50,180,\"FONT001\",0,2,2,\""); //中文
PrintDll.sendcommand(bianmaOnebtSC);
PrintDll.sendcommand("\"\n");
PrintDll.sendcommand("TEXT 380,180,\"FONT001\",0,2,2,\""); //中文
PrintDll.sendcommand(bianmaTwobtSC);
PrintDll.sendcommand("\"\n");
PrintDll.sendcommand("TEXT 250,250,\"FONT001\",0,2,2,\""); //中文
PrintDll.sendcommand(timebtSC);
PrintDll.sendcommand("\"\n");
PrintDll.barcode(80, 300, "128", 70, 1, 0, 3, 3, jsonObject.getStr("goodsCode"));
PrintDll.barcode(660, 390, "128", 70, 2, 270, 2, 3, jsonObject.getStr("packNo"));
PrintDll.sendcommand("PRINT 1\n");
} catch (Exception e) {
System.out.println("打印过程中发生异常: " + e.getMessage());
e.printStackTrace();
} finally {
}
// PrintDll.closeport();
}
这里会有一些坑,我需要提醒下,
1、打印的字体很长需要换行,改怎么做?
2、为什么打印不出中文字体?
机器需要设置中文字体包
3、为什么批量打印出现应用无响应现象?
new的实例太多了,端口打印时候可以先不捉急关闭
这些问题是我遇见过的
待更新...