Compare commits

..

8 Commits

@ -1,17 +1,25 @@
<component name="libraryTable"> <component name="libraryTable">
<library name="Dart SDK"> <library name="Dart SDK">
<CLASSES> <CLASSES>
<root url="file:///Users/zhangmeng/flutter/bin/cache/dart-sdk/lib/async" /> <root url="file://$PROJECT_DIR$/../fvm/versions/3.0.0/bin/cache/dart-sdk/lib/async" />
<root url="file:///Users/zhangmeng/flutter/bin/cache/dart-sdk/lib/collection" /> <root url="file://$PROJECT_DIR$/../fvm/versions/3.0.0/bin/cache/dart-sdk/lib/cli" />
<root url="file:///Users/zhangmeng/flutter/bin/cache/dart-sdk/lib/convert" /> <root url="file://$PROJECT_DIR$/../fvm/versions/3.0.0/bin/cache/dart-sdk/lib/collection" />
<root url="file:///Users/zhangmeng/flutter/bin/cache/dart-sdk/lib/core" /> <root url="file://$PROJECT_DIR$/../fvm/versions/3.0.0/bin/cache/dart-sdk/lib/convert" />
<root url="file:///Users/zhangmeng/flutter/bin/cache/dart-sdk/lib/developer" /> <root url="file://$PROJECT_DIR$/../fvm/versions/3.0.0/bin/cache/dart-sdk/lib/core" />
<root url="file:///Users/zhangmeng/flutter/bin/cache/dart-sdk/lib/html" /> <root url="file://$PROJECT_DIR$/../fvm/versions/3.0.0/bin/cache/dart-sdk/lib/developer" />
<root url="file:///Users/zhangmeng/flutter/bin/cache/dart-sdk/lib/io" /> <root url="file://$PROJECT_DIR$/../fvm/versions/3.0.0/bin/cache/dart-sdk/lib/ffi" />
<root url="file:///Users/zhangmeng/flutter/bin/cache/dart-sdk/lib/isolate" /> <root url="file://$PROJECT_DIR$/../fvm/versions/3.0.0/bin/cache/dart-sdk/lib/html" />
<root url="file:///Users/zhangmeng/flutter/bin/cache/dart-sdk/lib/math" /> <root url="file://$PROJECT_DIR$/../fvm/versions/3.0.0/bin/cache/dart-sdk/lib/indexed_db" />
<root url="file:///Users/zhangmeng/flutter/bin/cache/dart-sdk/lib/mirrors" /> <root url="file://$PROJECT_DIR$/../fvm/versions/3.0.0/bin/cache/dart-sdk/lib/io" />
<root url="file:///Users/zhangmeng/flutter/bin/cache/dart-sdk/lib/typed_data" /> <root url="file://$PROJECT_DIR$/../fvm/versions/3.0.0/bin/cache/dart-sdk/lib/isolate" />
<root url="file://$PROJECT_DIR$/../fvm/versions/3.0.0/bin/cache/dart-sdk/lib/js" />
<root url="file://$PROJECT_DIR$/../fvm/versions/3.0.0/bin/cache/dart-sdk/lib/js_util" />
<root url="file://$PROJECT_DIR$/../fvm/versions/3.0.0/bin/cache/dart-sdk/lib/math" />
<root url="file://$PROJECT_DIR$/../fvm/versions/3.0.0/bin/cache/dart-sdk/lib/mirrors" />
<root url="file://$PROJECT_DIR$/../fvm/versions/3.0.0/bin/cache/dart-sdk/lib/svg" />
<root url="file://$PROJECT_DIR$/../fvm/versions/3.0.0/bin/cache/dart-sdk/lib/typed_data" />
<root url="file://$PROJECT_DIR$/../fvm/versions/3.0.0/bin/cache/dart-sdk/lib/web_audio" />
<root url="file://$PROJECT_DIR$/../fvm/versions/3.0.0/bin/cache/dart-sdk/lib/web_gl" />
</CLASSES> </CLASSES>
<JAVADOC /> <JAVADOC />
<SOURCES /> <SOURCES />

@ -2,7 +2,6 @@
<library name="Flutter Plugins" type="FlutterPluginsLibraryType"> <library name="Flutter Plugins" type="FlutterPluginsLibraryType">
<CLASSES> <CLASSES>
<root url="file://$PROJECT_DIR$" /> <root url="file://$PROJECT_DIR$" />
<root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.flutter-io.cn/flutter_blue-0.8.0" />
</CLASSES> </CLASSES>
<JAVADOC /> <JAVADOC />
<SOURCES /> <SOURCES />

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
</set>
</option>
</component>
</project>

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

@ -0,0 +1 @@
hy_printer

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="11" />
</component>
</project>

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="PLATFORM" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="MavenRepo" />
<option name="name" value="MavenRepo" />
<option name="url" value="https://repo.maven.apache.org/maven2/" />
</remote-repository>
<remote-repository>
<option name="id" value="Google" />
<option name="name" value="Google" />
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
</remote-repository>
</component>
</project>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/modules/hy_printer.iml" filepath="$PROJECT_DIR$/.idea/modules/hy_printer.iml" />
</modules>
</component>
</project>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
</set>
</option>
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

@ -31,7 +31,7 @@ android {
} }
defaultConfig { defaultConfig {
minSdkVersion 19 minSdkVersion 16
} }
sourceSets { sourceSets {
main { main {
@ -42,8 +42,8 @@ android {
dependencies{ dependencies{
implementation fileTree(dir: "libs", include: ["*.jar"]) implementation fileTree(dir: "libs", include: ["*.jar"])
implementation files('libs/CPCL_SDK_V1.11.jar') implementation files('libs/CPCL_SDK_V1.12.jar')
implementation 'androidx.annotation:annotation:1.3.0'
} }

@ -1,7 +1,15 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
package="com.hy.print.hy_printer"> package="com.hy.print.hy_printer">
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.BLUETOOTH" tools:remove="android:maxSdkVersion" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
</manifest> </manifest>

@ -0,0 +1,372 @@
package com.hy.print.hy_printer;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import java.io.IOException;
import cpcl.PrinterHelper;
import io.flutter.plugin.common.EventChannel;
//import com.sewoo.port.android.BluetoothPort;
//import com.sewoo.request.android.RequestHandler;
public class Bluetooth {
private BluetoothAdapter mBluetoothAdapter;
//private BluetoothPort bluetoothPort;
private BroadcastReceiver connectDevice;
private BroadcastReceiver discoveryResult;
private BroadcastReceiver searchFinish;
private BroadcastReceiver searchStart;
private Thread btThread;
private boolean searchflags;
private boolean disconnectflags;
public void init() {
// bluetoothPort = BluetoothPort.getInstance();
// bluetoothPort.SetMacFilter(false);
bluetoothSetup();
searchflags = false;
disconnectflags = false;
System.out.println("打印机蓝牙初始化完成");
}
//初始化连接监听
public void createConnectBroadcast(Context context, EventChannel.EventSink eventSink) {
connectDevice = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
eventSink.success("connected");
} else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
try {
PrinterHelper.portClose();
// if (bluetoothPort.isConnected()) {
// System.out.println("1111s");
// bluetoothPort.disconnect();
// }
if ((btThread != null) && (btThread.isAlive())) {
cancelThread();
}
System.out.println("disconnected");
eventSink.success("disconnected");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
context.registerReceiver(connectDevice, new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED));
context.registerReceiver(connectDevice, new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED));
System.out.println("注册连接广播");
}
public boolean isValidAddress(String address) {
String[] btDevAddr = new String[]{"00:12:6f", "00:13:7b", "00:07:80", "88:6b:0f", "40:19:20", "00:01:90", "ec:1b:bd", "58:8e:81", "14:b4:57", "90:fd:9f", "00:0b:57", "68:0a:e2", "84:2e:14", "08:6b:d7", "60:a4:23", "cc:cc:cc", "bc:33:ac", "74:f0:7d", "84:fd:27", "84:71:27", "80:4b:50", "5c:02:72", "cc:86:ec", "2c:11:65", "b4:e3:f9", "0c:43:14", "50:32:5f", "04:cd:15", "8c:f6:81", "90:35:ea"};
if (!BluetoothAdapter.checkBluetoothAddress(address)) {
return false;
} else {
for(int i = 0; i < btDevAddr.length; ++i) {
if (btDevAddr[i].equalsIgnoreCase(address.substring(0, 8))) {
return true;
}
}
return false;
}
}
//初始化搜索设备监听
public void createDiscoveryBroadcast(Context context, EventChannel.EventSink eventSink) {
discoveryResult = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String key = "";
BluetoothDevice remoteDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String name = remoteDevice.getName();
System.out.println(name);
System.out.println(remoteDevice.getAddress());
System.out.println(remoteDevice.getBluetoothClass().getMajorDeviceClass());
if (remoteDevice != null && name != null&&remoteDevice.getBluetoothClass().getMajorDeviceClass()==1536) {
if (remoteDevice.getBondState() != BluetoothDevice.BOND_BONDED) {
key = "{" + "\"name\":" + "\"" + name + "\"" + ","
+ "\"address\":" + "\"" + remoteDevice.getAddress() + "\"" + ","
+ "\"isPaired\":" + false
+ "}";
} else {
key = "{" + "\"name\":" + "\"" + name + "\"" + ","
+ "\"address\":" + "\"" + remoteDevice.getAddress() + "\"" + ","
+ "\"isPaired\":" + true
+ "}";
}
System.out.println(key);
eventSink.success(key);
System.out.println(key);
// if (isValidAddress(remoteDevice.getAddress())) {
// eventSink.success(key);
// System.out.println(key);
// }
}
}
};
context.registerReceiver(discoveryResult, new IntentFilter(BluetoothDevice.ACTION_FOUND));
searchStart = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
eventSink.success("start");
System.out.println("start");
}
};
context.registerReceiver(searchStart, new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED));
searchFinish = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
eventSink.success("finish");
searchflags = true;
System.out.println("finish");
}
};
context.registerReceiver(searchFinish, new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED));
System.out.println("注册搜索广播");
}
//蓝牙设置
private void bluetoothSetup() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
System.out.println("不支持蓝牙");
}
}
//搜索设备
public void SearchingBTDevice() {
new CheckTypesTask().execute();
System.out.println("开始搜索");
}
public void btConn(final String address, Context context) throws Exception {
System.out.println("btConn");
btThread = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
System.out.println(address);
final int result = PrinterHelper.portOpenBT(context,address);
PrinterHelper.logcat("portOpen result:"+ result);
System.out.println(result);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
btThread.start();
//final int result = PrinterHelper.portOpenBT(context,address);
//new connBT().execute(address);
}
//断开连接
public void DisconnectDevice(Context context) {
try {
// bluetoothPort.disconnect();
PrinterHelper.portClose();
// if ((btThread != null) && (btThread.isAlive()))
// btThread.interrupt();
if ((btThread != null) && (btThread.isAlive())) {
Thread dummy = btThread;
btThread = null;
dummy.interrupt();
}else{
return;
}
disconnectflags = true;
context.unregisterReceiver(connectDevice);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//取消搜索
public void cancelDiscoveryResult(Context context) {
System.out.println("取消搜索");
mBluetoothAdapter.cancelDiscovery();
context.unregisterReceiver(discoveryResult);
context.unregisterReceiver(searchStart);
context.unregisterReceiver(searchFinish);
}
public void cancelThread() {
btThread.interrupt();
btThread = null;
}
private class CheckTypesTask extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
mBluetoothAdapter.startDiscovery();
super.onPreExecute();
}
;
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
try {
while (true) {
if (searchflags)
break;
Thread.sleep(100);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
searchflags = false;
super.onPostExecute(result);
}
;
}
// class connBT extends AsyncTask<String, Void, Integer> {
//
//
// @Override
// protected Integer doInBackground(String... strings) {
// Integer retVal = null;
//
// //bluetoothPort.connect(strings[0]);
//
// retVal = Integer.valueOf(0);
//
// return retVal;
// }
//
// @Override
// protected void onPreExecute() {
//
// super.onPreExecute();
// }
//
// @Override
// protected void onPostExecute(Integer result) {
// if (result.intValue() == 0) // Connection success.
// {
//// RequestHandler rh = new RequestHandler();
//// btThread = new Thread(rh);
//// btThread.start();
// } else // Connection failed.
// {
//
// }
// super.onPostExecute(result);
// }
// }
public void ExcuteDisconnect(Context context) {
// new ExcuteDisconnectBT().execute(context);
try {
DisconnectDevice(context);
while (true) {
if (disconnectflags)
break;
Thread.sleep(100);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// private class ExcuteDisconnectBT extends AsyncTask<Context, Void, Void> {
//
//
// @Override
// protected Void doInBackground(Context... contexts) {
// try {
// DisconnectDevice(contexts[0]);
//
// while (true) {
// if (disconnectflags)
// break;
//
// Thread.sleep(100);
// }
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// return null;
// }
//
// @Override
// protected void onPreExecute() {
// super.onPreExecute();
// }
//
// ;
//
//
// @Override
// protected void onPostExecute(Void result) {
// disconnectflags = false;
// super.onPostExecute(result);
// }
//
// ;
// }
}

@ -4,8 +4,8 @@ import android.content.Context;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import cpcl.PrinterHelper;
import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
@ -15,62 +15,100 @@ import io.flutter.plugin.common.MethodChannel.Result;
* HyPrinterPlugin * HyPrinterPlugin
*/ */
public class HyPrinterPlugin implements FlutterPlugin, MethodCallHandler { public class HyPrinterPlugin implements FlutterPlugin, MethodCallHandler {
/// The MethodChannel that will the communication between Flutter and native Android
/// // private MethodChannel channel;
/// This local reference serves to register the plugin with the Flutter Engine and unregister it // private Context context;
/// when the Flutter Engine is detached from the Activity
private MethodChannel channel; private MethodChannel channel;
private EventChannel discoveryChannel;
private EventChannel connectChannel;
private Context context; private Context context;
private static final String DISCOVERYDEVICE = "com.discovery.devices";
private static final String CONNECT = "com.connect";
PrintAsOrder printAsOrder;
Bluetooth bluetooth = new Bluetooth();
@Override @Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "hy_printer"); channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "hy_printer");
channel.setMethodCallHandler(this); channel.setMethodCallHandler(this);
context = flutterPluginBinding.getApplicationContext(); context = flutterPluginBinding.getApplicationContext();
discoveryChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), DISCOVERYDEVICE);
connectChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), CONNECT);
discoveryChannel.setStreamHandler(new EventChannel.StreamHandler() {
@Override
public void onListen(Object arguments, EventChannel.EventSink events) {
bluetooth.createDiscoveryBroadcast(context, events);
} }
@Override @Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) { public void onCancel(Object arguments) {
if (call.method.equals("connect")) { bluetooth.cancelDiscoveryResult(context);
int code = -4;
try {
code = PrinterHelper.portOpenBT(context, (String) call.argument("address"));
} catch (Exception e) {
e.printStackTrace();
} }
result.success(code); });
} else if (call.method.equals("disConnect")) { connectChannel.setStreamHandler(new EventChannel.StreamHandler() {
boolean status = false; @Override
try { public void onListen(Object arguments, EventChannel.EventSink events) {
status = PrinterHelper.portClose(); bluetooth.createConnectBroadcast(context, events);
} catch (Exception e) {
e.printStackTrace();
} }
result.success(status);
} else if (call.method.equals("getStatus")) { @Override
int status = -1; public void onCancel(Object arguments) {
bluetooth.ExcuteDisconnect(context);
}
});
}
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
if (call.method.equals("startSearch")) {
bluetooth.SearchingBTDevice();
} else if (call.method.equals("connect")) {
String arg = call.argument("address");
try { try {
status = PrinterHelper.getstatus(); System.out.println("开始打印");
bluetooth.btConn(arg,context);
result.success(true);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
result.success(status); } else if (call.method.equals("init")) {
} else if (call.method.equals("printAsOrder")) { System.out.println("打印机初始化");
int re = PrintAsOrder.print(call.argument("code"), call.argument("fbaCode"), call.argument("country"), call.argument("channel"), call.argument("count"), call.argument("hasPlan")); bluetooth.init();
result.success(re); printAsOrder = new PrintAsOrder();
} else if (call.method.equals("printBarCode")) {
int re = -1; result.success(true);
} else if (call.method.equals("newPrint")) {
System.out.println("newPrint");
String code = call.argument("code");
String barCode = call.argument("barCode");
String channel = call.argument("channel");
String country = call.argument("country");
String num = call.argument("num");
String sum = call.argument("sum");
int offset = call.argument("offset");
boolean hasPlan = call.argument("hasPlan");
printAsOrder.printAsCodeNew(code, barCode, channel, country, num, sum, offset, hasPlan);
result.success(true);
} else if (call.method.equals("getStatus")) {
int sta = 0;
try { try {
PrinterHelper.printAreaSize("0", "200", "200", "500", "1"); sta = printAsOrder.getStatus();
re = PrinterHelper.Barcode(PrinterHelper.BARCODE, PrinterHelper.code128, call.argument("width"), call.argument("ratio"), call.argument("height"), call.argument("x"), call.argument("y"), call.argument("undertext"), "7", call.argument("size"), call.argument("offset"), call.argument("data"));
PrinterHelper.Form();
PrinterHelper.Print();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
result.success(re); result.success(sta);
} else { } else if (call.method.equals("disposeDiscovery")) {
result.notImplemented();
bluetooth.cancelDiscoveryResult(context);
result.success(true);
} else if (call.method.equals("disposeConnect")) {
bluetooth.ExcuteDisconnect(context);
result.success(true);
} }
} }

@ -3,6 +3,7 @@ package com.hy.print.hy_printer;
import cpcl.PrinterHelper; import cpcl.PrinterHelper;
public class PrintAsOrder { public class PrintAsOrder {
private static void setBold() { private static void setBold() {
try { try {
PrinterHelper.SetBold("2"); PrinterHelper.SetBold("2");
@ -19,18 +20,7 @@ public class PrintAsOrder {
} }
} }
private static void printBarCode(String code) {
String width = "2";
if (code.length() > 18) {
width = "1";
}
try {
PrinterHelper.Barcode(PrinterHelper.BARCODE, PrinterHelper.code128, width, "1", "130", "10", "26", false, "", "", "", code);
} catch (Exception e) {
e.printStackTrace();
}
}
public static int print(String code, String fbaCode, String country, String channel, String count, Boolean hasPlan) { public static int print(String code, String fbaCode, String country, String channel, String count, Boolean hasPlan) {
int re = 0; int re = 0;
@ -49,7 +39,7 @@ public class PrintAsOrder {
try { try {
PrinterHelper.printAreaSize("0", "200", "200", "400", "1"); PrinterHelper.printAreaSize("0", "200", "200", "400", "1");
PrinterHelper.Align(PrinterHelper.CENTER); PrinterHelper.Align(PrinterHelper.CENTER);
printBarCode(code); // printBarCode(code);
PrinterHelper.Align(PrinterHelper.LEFT); PrinterHelper.Align(PrinterHelper.LEFT);
PrinterHelper.SetBold("3"); PrinterHelper.SetBold("3");
PrinterHelper.AutCenter(PrinterHelper.TEXT, "45", "170", 500, 4, code); PrinterHelper.AutCenter(PrinterHelper.TEXT, "45", "170", 500, 4, code);
@ -83,7 +73,7 @@ public class PrintAsOrder {
try { try {
PrinterHelper.printAreaSize("0", "200", "200", "400", "1"); PrinterHelper.printAreaSize("0", "200", "200", "400", "1");
PrinterHelper.Align(PrinterHelper.CENTER); PrinterHelper.Align(PrinterHelper.CENTER);
printBarCode(code); // printBarCode(code);
PrinterHelper.Align(PrinterHelper.LEFT); PrinterHelper.Align(PrinterHelper.LEFT);
PrinterHelper.SetBold("3"); PrinterHelper.SetBold("3");
PrinterHelper.AutCenter(PrinterHelper.TEXT, "45", "170", 500, 4, code); PrinterHelper.AutCenter(PrinterHelper.TEXT, "45", "170", 500, 4, code);
@ -116,4 +106,234 @@ public class PrintAsOrder {
System.out.println("print finish"); System.out.println("print finish");
return reusult; return reusult;
} }
public void printAsCodeNew(String code, String barCode, String channel, String country, String num, String sum,
int offset, boolean hasPlan) {
if (hasPlan) {
PrintPlanNew(code, barCode, channel, country, num, sum, offset);
} else {
PrintNoPlanNew(code, barCode, num, sum, offset);
}
}
private void PrintPlanNew(String code, String barCode, String channel, String country, String num, String sum,
int offset) {
System.out.println("print start");
int cx = 0,cy = 0;
int cx1 = 0,cy1 = 0;
String country1 = "";
String cMultiple = "3";
String cSize = "55";
String channel1 = "";
if(country.length()>5){
cMultiple = "3";
cx = 65;cy = 220;
country1 = country.substring(4);
cx1 = (165-country1.length()*25);
cy1 = 280;
country = country.substring(0,4);
}else if(country.length()==5){
cMultiple = "3";cx = 45;cy = 250;
cSize = "55";
}else if(country.length()==4){
cMultiple = "4";cx = 40;cy = 245;
cSize = "55";
}
else {
cMultiple = "3";cy = 245;cx = 175-country.length()*40;
cSize = "60";
}
int channelY = 460;
int channel1Y = 460;
if(channel.length()>11){
channelY = 440;
channel1Y = 490;
channel1 = channel.substring(11);
channel = channel.substring(0,11);
}else{
channelY = 460;
}
System.out.println("cx1");
System.out.println(cx1);
System.out.println("country1");
System.out.println(country1);
try {
PrinterHelper.printAreaSize("0", "200", "200", "800", "1");
//PrinterHelper.Encoding("gb2312");
PrinterHelper.Box("0","10","575","790","3");
PrinterHelper.Line("0", "160", "575", "160", "3");
PrinterHelper.Line("0", "400", "575", "400", "3");
PrinterHelper.Line("0", "560", "575", "560", "3");
PrinterHelper.Line("380", "360", "540", "200", "3");
PrinterHelper.Line("333", "160", "333", "400", "3");
PrinterHelper.Align(PrinterHelper.CENTER);
PrinterHelper.SetBold("4");
PrinterHelper.SetMag("5","5");
PrinterHelper.Text(PrinterHelper.TEXT, "55", "0", "0", "55", code);
closeBold();
PrinterHelper.SetMag("1","1");
PrinterHelper.Align(PrinterHelper.LEFT);
PrinterHelper.SetBold("3");
PrinterHelper.SetMag(cMultiple,cMultiple);
PrinterHelper.Text(PrinterHelper.TEXT,cSize , "0",String.valueOf(cx), String.valueOf(cy), country);
if(!country1.isEmpty()){
PrinterHelper.Text(PrinterHelper.TEXT,cSize , "0",String.valueOf(cx1), String.valueOf(cy1), country1);
}
closeBold();
PrinterHelper.SetMag("1","1");
PrinterHelper.Align(PrinterHelper.LEFT);
PrinterHelper.SetBold("2");
PrinterHelper.SetMag("3","3");
PrinterHelper.Text(PrinterHelper.TEXT, "55", "0", "390", "210", num);
PrinterHelper.Text(PrinterHelper.TEXT, "55", "0", String.valueOf(500-sum.length()*10), String.valueOf(315), sum);
closeBold();
PrinterHelper.SetMag("1","1");
PrinterHelper.Align(PrinterHelper.CENTER);
printBarCode(barCode,"0","590");
PrinterHelper.Align(PrinterHelper.CENTER);
PrinterHelper.SetMag("2","2");
PrinterHelper.Text(PrinterHelper.TEXT,"55" , "0","0", "730", barCode);
PrinterHelper.SetMag("1","1");
PrinterHelper.Align(PrinterHelper.CENTER);
PrinterHelper.SetMag("2","2");
PrinterHelper.Text(PrinterHelper.TEXT,"3" , "0","0", String.valueOf(channelY), channel);
if(!channel1.isEmpty()){
PrinterHelper.Text(PrinterHelper.TEXT,"3" , "0","0", String.valueOf(channel1Y), channel1);
}
closeBold();
PrinterHelper.SetMag("1","1");
PrinterHelper.Form();
PrinterHelper.Print();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("print finish");
}
private static void printBarCode(String code,String x,String y) {
String width = "1.5";
if (code.length() > 18) {
width = "1";
}
try {
PrinterHelper.Barcode(PrinterHelper.BARCODE, PrinterHelper.code128, width, "0", "130", x, y, false, "15", "15", "15", code);
} catch (Exception e) {
e.printStackTrace();
}
}
private void PrintNoPlanNew(String code, String barCode, String num, String sum,
int offset) {
System.out.println("print start");
try {
PrinterHelper.printAreaSize("0", "200", "200", "800", "1");
PrinterHelper.Box("0","10","575","790","3");
PrinterHelper.Line("0", "160", "575", "160", "3");
PrinterHelper.Line("0", "400", "575", "400", "3");
PrinterHelper.Line("380", "360", "540", "200", "3");
PrinterHelper.Line("333", "160", "333", "400", "3");
PrinterHelper.Align(PrinterHelper.CENTER);
PrinterHelper.SetBold("4");
PrinterHelper.SetMag("5","5");
PrinterHelper.Text(PrinterHelper.TEXT, "55", "0", "0", "55", code);
closeBold();
PrinterHelper.SetMag("1","1");
PrinterHelper.Align(PrinterHelper.LEFT);
PrinterHelper.SetBold("3");
PrinterHelper.SetMag("4","4");
PrinterHelper.Text(PrinterHelper.TEXT,"55" , "0","40","245", "未建计划");
closeBold();
PrinterHelper.SetMag("1","1");
PrinterHelper.Align(PrinterHelper.LEFT);
PrinterHelper.SetBold("2");
PrinterHelper.SetMag("3","3");
PrinterHelper.Text(PrinterHelper.TEXT, "55", "0", "390", "210", num);
PrinterHelper.Text(PrinterHelper.TEXT, "55", "0", String.valueOf(500-sum.length()*10), String.valueOf(315), sum);
closeBold();
PrinterHelper.SetMag("1","1");
PrinterHelper.Align(PrinterHelper.CENTER);
printBarCode(barCode,"0","520");
PrinterHelper.Align(PrinterHelper.CENTER);
PrinterHelper.SetMag("2","2");
PrinterHelper.Text(PrinterHelper.TEXT,"55" , "0","0", "660", barCode);
PrinterHelper.SetMag("1","1");
PrinterHelper.Form();
PrinterHelper.Print();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("print finish");
}
public int getStatus() throws Exception {
return PrinterHelper.getstatus();
}
} }

@ -25,7 +25,7 @@ apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android { android {
compileSdkVersion 30 compileSdkVersion 33
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
@ -54,3 +54,8 @@ android {
flutter { flutter {
source '../..' source '../..'
} }
dependencies{
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation files('libs/CPCL_SDK_V1.12.jar')
}

@ -4,4 +4,10 @@
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.
--> -->
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation" />
</manifest> </manifest>

@ -1,4 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
package="com.hy.print.hy_printer_example"> package="com.hy.print.hy_printer_example">
<application <application
android:label="hy_printer_example" android:label="hy_printer_example"
@ -9,6 +9,7 @@
android:theme="@style/LaunchTheme" android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:requestLegacyExternalStorage="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as <!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user the Android process has started. This theme is visible to the user
@ -38,4 +39,16 @@
android:name="flutterEmbedding" android:name="flutterEmbedding"
android:value="2" /> android:value="2" />
</application> </application>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.BLUETOOTH" tools:remove="android:maxSdkVersion" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
</manifest> </manifest>

@ -4,4 +4,10 @@
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.
--> -->
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation" />
</manifest> </manifest>

@ -1,8 +1,12 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert';
import 'package:bot_toast/bot_toast.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hy_printer/device.dart';
import 'package:hy_printer/dj_printer.dart';
import 'package:hy_printer/hy_printer.dart'; import 'package:hy_printer/hy_printer.dart';
import 'package:hy_printer_example/scan_page.dart'; import 'package:hy_printer_example/scan_page.dart';
// import 'package:permission_handler/permission_handler.dart';
void main() { void main() {
runApp(const MyApp()); runApp(const MyApp());
@ -16,6 +20,8 @@ class MyApp extends StatefulWidget {
} }
class _MyAppState extends State<MyApp> { class _MyAppState extends State<MyApp> {
List<Device> devices = [];
var cancel;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -23,88 +29,167 @@ class _MyAppState extends State<MyApp> {
} }
Future<void> initPlatformState() async { Future<void> initPlatformState() async {
if (!mounted) return;
setState(() {});
}
@override DjPrinter().init();
Widget build(BuildContext context) { DjPrinter().addDiscoveryListen(onReceive: (data) {
return const MaterialApp( var js = json.decode(data.toString());
home: Home(), if ((js['name'] as String).startsWith('HM')) {
); devices.add(Device(
name: js['name'],
address: js['address'],
isPaired: js['isPaired']));
}
setState(() {});
}, onStart: () {
print("————————————————————————");
}, onFinish: () {
print('——————————————————————————————');
DjPrinter().cancelDiscovery();
cancel();
});
DjPrinter().addConnectListen(onConnect: () {
print("connected");
}, onDisconnect: () {
print('disconnected');
});
print('jieshu');
} }
}
class Home extends StatefulWidget {
const Home({Key? key}) : super(key: key);
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
int status = -1;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {return MaterialApp(
return Scaffold( title: '安速货运',
builder: (context, widget) {
// ScreenUtil.setContext(context);
return MediaQuery(
data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
child: BotToastInit().call(context, widget));
},
navigatorObservers: [BotToastNavigatorObserver()],
home: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar( appBar: AppBar(
title: const Text('Plugin example app'), title: const Text('设备列表',style: TextStyle(color: Colors.white),),
), ),
body: Center( body: Center(
child: Column( child: Column(
children: [ children: [
TextButton( TextButton(
onPressed: () { onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) { devices.clear();
return const ScanPage(); setState(() {});
})); cancel =
BotToast.showLoading(wrapToastAnimation: (controller, func, child) {
return discoveryLoadingWidget();
});
DjPrinter().startSearch;
}, },
child: const Text('扫描设备')), child: const Text('扫描设备')),
TextButton( // TextButton(onPressed: () {}, child: const Text('打印')),
onPressed: () async { const SizedBox(
await HyPrinter.disConnect(); height: 20,
}, ),
child: const Text('断开连接')), ...devices
TextButton( .map((e) => TextButton(
onPressed: () async { onPressed: ()async {
status = await HyPrinter.getStatus(); BotToast.showLoading(wrapToastAnimation: (controller, func, child) {
setState(() {}); return discoveryLoadingWidget();
});
await DjPrinter().connect(e.address).then((value) {
print("main value result");
print(value);
if(value!=null&&value){
BotToast.closeAllLoading();
}
});
// Future.delayed(Duration(seconds: 3), () async {
// if(value==0){
// BotToast.closeAllLoading();
// }
// });
}, },
child: Text('$status')), child: Column(
children: [
Text(e.name),
Text(e.address),
],
)))
.toList(),
const SizedBox(
height: 20,
),
TextButton( TextButton(
onPressed: () async { onPressed: () {
await HyPrinter.printAsOrder( DjPrinter().printNewAScode(
code: 'ASASNB2021121200011', code: 'ASSZ000000002',
fbaCode: '', barCode: 'ASSZ0000000020001',
channel: "", channel: '加拿大温哥华海派快线-卡派 / UPS派送',
country: '', country: '美国啊啊',
count: "2/10", num: '2',
hasPlan: false); sum:'99',
setState(() {}); offset: 0,
hasPlan: true, );
}, },
child: const Text('打印面单')), child: const Text('nocode打印')),
TextButton( TextButton(
onPressed: () async { onPressed: () {
await HyPrinter.printAsOrder(
code: 'ASASNB2021121200010002', DjPrinter().printNewAScode(
fbaCode: 'FBA15RY33MN8U00001', code: 'ASSZ000000002',
channel: "欧洲特快", barCode: 'ASSZ0000000020001',
country: '法国', channel: '加拿大温哥华海派快线-卡派 / UPS派送',
count: "2/10", country: '美国',
hasPlan: true); num: '2',
setState(() {}); sum:'999',
offset: 0,
hasPlan: false, );
}, },
child: const Text('打印FBA面单')), child: const Text('noplan打印')),
const SizedBox(
height: 20,
),
TextButton( TextButton(
onPressed: () async { onPressed: () {
await HyPrinter.printBarCode(0, 0, "2", "1", "130", "45", "26", DjPrinter().disposeConnect();
true, "8", "14", "12345678");
setState(() {});
}, },
child: const Text('打印条码')), child: const Text('取消链接')),
], ],
)), ),
),
)
);
}
Container discoveryLoadingWidget() {
return Container(
padding: const EdgeInsets.all(15),
decoration: const BoxDecoration(
color: Colors.black54,
borderRadius: BorderRadius.all(Radius.circular(8))),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
CircularProgressIndicator(
backgroundColor: Colors.white,
),
Text(
'扫描中……请稍作等待',
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold,
),
)
],
),
); );
} }
} }

@ -1,5 +1,9 @@
import 'dart:convert';
import 'package:bot_toast/bot_toast.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hy_printer/device.dart'; import 'package:hy_printer/device.dart';
import 'package:hy_printer/dj_printer.dart';
import 'package:hy_printer/hy_printer.dart'; import 'package:hy_printer/hy_printer.dart';
class ScanPage extends StatefulWidget { class ScanPage extends StatefulWidget {
@ -10,34 +14,99 @@ class ScanPage extends StatefulWidget {
} }
class _ScanPageState extends State<ScanPage> { class _ScanPageState extends State<ScanPage> {
List<Device> _devices = []; List<Device> devices = [];
var cancel;
@override @override
void initState() { void initState() {
init();
super.initState(); super.initState();
initPlatformState();
}
// Future<void> initPlatformState() async {
// if (!mounted) return;
// setState(() {});
// }
Future<void> initPlatformState() async {
// var per = await Permission.bluetooth.isGranted;
// if (!per) {
// Permission.bluetooth.request();
// }
// var pers = await Permission.locationWhenInUse.isGranted;
// if (!pers) {
// Permission.locationWhenInUse.request();
// }
// var per1 = await Permission.bluetoothScan.isGranted;
// if (!per1) {
// Permission.bluetoothScan.request();
// }
// var per2 = await Permission.bluetoothConnect.isGranted;
// if (!per2) {
// Permission.bluetoothConnect.request();
// }
DjPrinter().init();
DjPrinter().addDiscoveryListen(onReceive: (data) {
var js = json.decode(data.toString());
if ((js['name'] as String).startsWith('HM')) {
devices.add(Device(
name: js['name'],
address: js['address'],
isPaired: js['isPaired']));
} }
Future init() async {
_devices = await HyPrinter.getDeiveces();
setState(() {}); setState(() {});
}, onStart: () {
print("————————————————————————");
}, onFinish: () {
print('——————————————————————————————');
DjPrinter().cancelDiscovery();
cancel();
});
DjPrinter().addConnectListen(onConnect: () {
print("connected");
}, onDisconnect: () {
print('disconnected');
});
print('jieshu');
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar( appBar: AppBar(
title: const Text('设备列表'), title: const Text('设备列表',style: TextStyle(color: Colors.white),),
), ),
body: ListView( body: Center(
padding: const EdgeInsets.all(10), child: Column(
children: _devices children: [
TextButton(
onPressed: () {
devices.clear();
setState(() {});
cancel =
BotToast.showLoading(wrapToastAnimation: (controller, func, child) {
return discoveryLoadingWidget();
});
DjPrinter().startSearch;
},
child: const Text('扫描设备')),
// TextButton(onPressed: () {}, child: const Text('打印')),
const SizedBox(
height: 20,
),
...devices
.map((e) => TextButton( .map((e) => TextButton(
onPressed: () async { onPressed: ()async {
var result = await HyPrinter.connect(e.address);
if (result == 0) { await DjPrinter().connect(e.address);
Navigator.pop(context);
}
}, },
child: Column( child: Column(
children: [ children: [
@ -45,7 +114,76 @@ class _ScanPageState extends State<ScanPage> {
Text(e.address), Text(e.address),
], ],
))) )))
.toList()), .toList(),
const SizedBox(
height: 20,
),
TextButton(
onPressed: () {
DjPrinter().printNewAScode(
code: 'ASSZ000000002',
barCode: 'ASSZ0000000020001',
channel: '加拿大温哥华海派快线-卡派 / UPS派送',
country: '美国啊啊',
num: '2',
sum:'99',
offset: 0,
hasPlan: true, );
},
child: const Text('nocode打印')),
TextButton(
onPressed: () {
DjPrinter().printNewAScode(
code: 'ASSZ000000002',
barCode: 'ASSZ0000000020001',
channel: '加拿大温哥华海派快线-卡派 / UPS派送',
country: '美国',
num: '2',
sum:'999',
offset: 0,
hasPlan: false, );
},
child: const Text('noplan打印')),
const SizedBox(
height: 20,
),
TextButton(
onPressed: () {
DjPrinter().disposeConnect();
},
child: const Text('取消链接')),
],
),
),
);
}
Container discoveryLoadingWidget() {
return Container(
padding: const EdgeInsets.all(15),
decoration: const BoxDecoration(
color: Colors.black54,
borderRadius: BorderRadius.all(Radius.circular(8))),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
CircularProgressIndicator(
backgroundColor: Colors.white,
),
Text(
'扫描中……请稍作等待',
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold,
),
)
],
),
); );
} }
} }

@ -7,7 +7,7 @@ packages:
name: async name: async
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.7.0" version: "2.8.2"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
@ -15,13 +15,20 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.1.0" version: "2.1.0"
bot_toast:
dependency: "direct main"
description:
name: bot_toast
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.0.3"
characters: characters:
dependency: transitive dependency: transitive
description: description:
name: characters name: characters
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.1.0" version: "1.2.0"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
@ -42,47 +49,26 @@ packages:
name: collection name: collection
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.15.0" version: "1.16.0"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.1"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
name: cupertino_icons name: cupertino_icons
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.0.3" version: "1.0.5"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
name: fake_async name: fake_async
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.2.0" version: "1.3.0"
fixnum:
dependency: transitive
description:
name: fixnum
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.0"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_blue:
dependency: transitive
description:
name: flutter_blue
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.8.0"
flutter_lints: flutter_lints:
dependency: "direct dev" dependency: "direct dev"
description: description:
@ -115,35 +101,28 @@ packages:
name: matcher name: matcher
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.12.10" version: "0.12.11"
meta: material_color_utilities:
dependency: transitive
description:
name: meta
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.4.0"
path:
dependency: transitive dependency: transitive
description: description:
name: path name: material_color_utilities
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.8.0" version: "0.1.4"
protobuf: meta:
dependency: transitive dependency: transitive
description: description:
name: protobuf name: meta
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.0.0" version: "1.7.0"
rxdart: path:
dependency: transitive dependency: transitive
description: description:
name: rxdart name: path
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.26.0" version: "1.8.1"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -155,7 +134,7 @@ packages:
name: source_span name: source_span
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.8.1" version: "1.8.2"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
@ -190,21 +169,14 @@ packages:
name: test_api name: test_api
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.4.1" version: "0.4.9"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.0"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
name: vector_math name: vector_math
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.1.0" version: "2.1.2"
sdks: sdks:
dart: ">=2.12.0 <3.0.0" dart: ">=2.17.0-0 <3.0.0"
flutter: ">=1.20.0" flutter: ">=1.20.0"

@ -17,7 +17,7 @@ environment:
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
# permission_handler: 10.0.0
hy_printer: hy_printer:
# When depending on this package from a real application you should use: # When depending on this package from a real application you should use:
# hy_printer: ^x.y.z # hy_printer: ^x.y.z
@ -29,7 +29,7 @@ dependencies:
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2 cupertino_icons: ^1.0.2
bot_toast: ^4.0.1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter

@ -12,6 +12,7 @@
<excludeFolder url="file://$MODULE_DIR$/example/.pub" /> <excludeFolder url="file://$MODULE_DIR$/example/.pub" />
<excludeFolder url="file://$MODULE_DIR$/example/.dart_tool" /> <excludeFolder url="file://$MODULE_DIR$/example/.dart_tool" />
</content> </content>
<orderEntry type="jdk" jdkName="Android API 32 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" /> <orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Flutter Plugins" level="project" /> <orderEntry type="library" name="Flutter Plugins" level="project" />

@ -1,9 +1,11 @@
class Device { class Device {
final String name; String name;
final String address; String address;
bool isPaired;
const Device({ Device({
required this.name, required this.name,
required this.address, required this.address,
required this.isPaired,
}); });
} }

@ -0,0 +1,195 @@
import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hy_printer/status_enum.dart';
class DjPrinter {
static late final DjPrinter _instance = DjPrinter._();
DjPrinter._();
factory DjPrinter() => _instance;
static const MethodChannel _channel = MethodChannel('hy_printer');
static const EventChannel _deviceChannel =
EventChannel("com.discovery.devices");
StreamSubscription? _discoveryStream;
StreamSubscription addDiscoveryListen(
{required void Function(dynamic data) onReceive,
void Function()? onStart,
void Function()? onFinish}) {
if (_discoveryStream == null) {
return _deviceChannel.receiveBroadcastStream().listen((data) {
if (data == "start" && onStart != null) {
onStart();
} else if (data == "finish" && onFinish != null) {
onFinish();
} else {
onReceive(data);
}
});
} else {
return _discoveryStream!;
}
}
void cancelDiscovery() {
_discoveryStream?.cancel();
_discoveryStream = null;
print('结束搜索');
disposeDiscovery();
}
static const EventChannel _connectChannel = EventChannel("com.connect");
StreamSubscription? _connectStream;
StreamSubscription addConnectListen({required void Function() onConnect,
required void Function() onDisconnect}) {
if (_connectStream == null) {
return _connectChannel.receiveBroadcastStream().listen((data) {
if (data == 'connected') {
onConnect();
} else if (data == 'disconnected') {
onDisconnect();
}
});
} else {
return _connectStream!;
}
}
void cancelConnect() {
if (_connectStream != null) {
_connectStream!.cancel();
_connectStream = null;
}
}
void get startSearch {
final res = _channel.invokeMethod('startSearch');
}
bool _hasInit = false;
bool get hasInit => _hasInit;
Future<bool?> connect(String address) async {
final res = await _channel.invokeMethod('connect', {'address': address});
return res;
}
void disposeDiscovery() {
print('disposeDiscovery');
final res = _channel.invokeMethod('disposeDiscovery');
}
Future<bool?> disposeConnect() async {
final res = await _channel.invokeMethod('disposeConnect');
return res;
}
Future<bool?> init() async {
final res = await _channel.invokeMethod('init');
_hasInit = true;
return res;
}
//0 normal
//1 busy
//2 paper empty
//4 cover open
//8 battery low
// Future<PRINT_STATUS?> getStatus() async {
// final res = await _channel.invokeMethod('getStatus');
// switch (res) {
// case 0:
// return PRINT_STATUS.normal;
// case 1:
// return PRINT_STATUS.busy;
// case 2:
// return PRINT_STATUS.paperEmpty;
// case 4:
// return PRINT_STATUS.coverOpen;
// case 8:
// return PRINT_STATUS.batteryLow;
// default:
// return null;
// }
// }
//0 normal
//-1
//2 paper empty
//6 cover open
Future<PRINT_STATUS?> getStatus() async {
final res = await _channel.invokeMethod('getStatus');
switch (res) {
case 0:
return PRINT_STATUS.normal;
case -1:
return PRINT_STATUS.fail;
case 2:
return PRINT_STATUS.paperEmpty;
case 6:
return PRINT_STATUS.coverOpen;
default:
return null;
}
}
Future<bool?> printNewAScode({required String code,
required String barCode,
required String channel,
required String country,
required String num,
required String sum,
required int offset,
required bool hasPlan}) async {
final res = await _channel.invokeMethod('newPrint', {
'code': code,
'barCode':barCode,
'channel': channel,
'country': country,
'num': num,
'sum': sum,
'offset': offset,
'hasPlan': hasPlan,
});
return res;
}
Future<bool?> printAScode({required String code,
required String channel,
required String country,
required String countStr,
required int offset,
required bool hasPlan}) async {
final res = await _channel.invokeMethod('print', {
'code': code,
'channel': channel,
'country': country,
'countStr': countStr,
'offset': offset,
'hasPlan': hasPlan,
});
return res;
}
}

@ -1,141 +1,155 @@
import 'dart:async'; // import 'dart:async';
//
import 'package:flutter/services.dart'; // import 'package:flutter/services.dart';
import 'package:flutter_blue/flutter_blue.dart'; // // import 'package:flutter_blue/flutter_blue.dart';
import 'package:hy_printer/device.dart'; // import 'package:flutter_blue_plus/flutter_blue_plus.dart';
// import 'package:hy_printer/device.dart';
class HyPrinter { // import 'package:permission_handler/permission_handler.dart';
static const MethodChannel _channel = MethodChannel('hy_printer'); //
static FlutterBlue flutterBlue = FlutterBlue.instance; // class HyPrinter {
// static const MethodChannel _channel = MethodChannel('hy_printer');
static void init() {} // static FlutterBluePlus flutterBlue = FlutterBluePlus.instance;
// static void init() async {
static Future<List<Device>> getDeiveces() async { // var per = await Permission.bluetooth.isGranted;
var devices = <Device>[]; // if (!per) {
await flutterBlue.startScan(timeout: const Duration(seconds: 4)); // Permission.bluetooth.request();
flutterBlue.scanResults.listen((results) { // }
for (ScanResult r in results) { // var pers = await Permission.locationWhenInUse.isGranted;
// // if (!pers) {
if (r.device.name.isNotEmpty) { // Permission.locationWhenInUse.request();
devices.add(Device(name: r.device.name, address: r.device.id.id)); // }
} // }
} //
}); // static Future<List<Device>> getDeiveces() async {
await flutterBlue.stopScan(); // var devices = <Device>[];
return devices; // await flutterBlue.startScan(timeout: const Duration(seconds: 4));
} // flutterBlue.scanResults.listen((results) {
// for (ScanResult r in results) {
static Future<bool> blutIsOn() async { // //
var result = await flutterBlue.isOn; // if(r.device.name.contains('HM')){
return result; // devices.add(Device(name: r.device.name, address: r.device.id.id));
} // }
//
///0 // // if (r.device.name.isNotEmpty) {
///-1 // // devices.add(Device(name: r.device.name, address: r.device.id.id));
///-2 // // }
///-3sdk // }
///-4 // });
static Future<int> connect(String address) async { // await flutterBlue.stopScan();
int result = -4; // return devices;
await Future.delayed(const Duration(milliseconds: 2000), () async { // }
result = await _channel.invokeMethod('connect', {'address': address}); //
}); // static Future<bool> blutIsOn() async {
// int result = await _channel.invokeMethod('connect', {'address': address}); // var result = await flutterBlue.isOn;
return result; // return result;
} // }
//
static Future<bool> disConnect() async { // ///0
bool result = await _channel.invokeMethod('disConnect'); // ///-1
return result; // ///-2
} // ///-3sdk
// ///-4
///0: // static Future<int> connect(String address) async {
///-1 // int result = -4;
///2 // await Future.delayed(const Duration(milliseconds: 2000), () async {
///3 // result = await _channel.invokeMethod('connect', {'address': address});
static Future<int> getStatus() async { // });
int result = await _channel.invokeMethod( // // int result = await _channel.invokeMethod('connect', {'address': address});
'getStatus', // return result;
); // }
return result; //
} // static Future<bool> disConnect() async {
// bool result = await _channel.invokeMethod('disConnect');
static Future<int> printBarCode( // return result;
int direction, // }
int type, //
String width, // ///0:
String ratio, // ///-1
String height, // ///2
String x, // ///3
String y, // static Future<int> getStatus() async {
bool undertext, // int result = await _channel.invokeMethod(
String size, // 'getStatus',
String offset, // );
String data, // return result;
) async { // }
int result = await _channel.invokeMethod('printBarCode', { //
'direction': direction, // static Future<int> printBarCode(
'type': type, // int direction,
'width': width, // int type,
'ratio': ratio, // String width,
'height': height, // String ratio,
'x': x, // String height,
'y': y, // String x,
'undertext': undertext, // String y,
'size': size, // bool undertext,
'offset': offset, // String size,
'data': data, // String offset,
}); // String data,
return result; // ) async {
} // int result = await _channel.invokeMethod('printBarCode', {
// 'direction': direction,
static Future<int> printLine( // 'type': type,
String x0, // 'width': width,
String y0, // 'ratio': ratio,
String x1, // 'height': height,
String y1, // 'x': x,
) async { // 'y': y,
int result = await _channel // 'undertext': undertext,
.invokeMethod('printLine', {'x0': x0, 'x1': x1, 'y0': y0, 'y1': y1}); // 'size': size,
return result; // 'offset': offset,
} // 'data': data,
// });
static Future<int> align(String align) async { // return result;
int result = await _channel.invokeMethod('align', {'align': align}); // }
return result; //
} // static Future<int> printLine(
// String x0,
static Future<int> setBold(String bold) async { // String y0,
int result = await _channel.invokeMethod('setBold', {'bold': bold}); // String x1,
return result; // String y1,
} // ) async {
// int result = await _channel
static Future<int> prefeed(String prefeed) async { // .invokeMethod('printLine', {'x0': x0, 'x1': x1, 'y0': y0, 'y1': y1});
int result = await _channel.invokeMethod('setBold', {'prefeed': prefeed}); // return result;
return result; // }
} //
// static Future<int> align(String align) async {
/// 'code': code, // int result = await _channel.invokeMethod('align', {'align': align});
// 'fbaCode': fbaCode, fba/fba // return result;
// 'channel': channel, // }
// 'country': country, //
// 'count': count, // static Future<int> setBold(String bold) async {
// 'hasPlan':hasPlan // int result = await _channel.invokeMethod('setBold', {'bold': bold});
static Future<int> printAsOrder( // return result;
{required String code, // }
required String fbaCode, //
required String channel, // static Future<int> prefeed(String prefeed) async {
required String country, // int result = await _channel.invokeMethod('setBold', {'prefeed': prefeed});
required String count, // return result;
required bool hasPlan}) async { // }
int result = await _channel.invokeMethod('printAsOrder', { //
'code': code, // /// 'code': code,
'fbaCode': fbaCode, // // 'fbaCode': fbaCode, fba/fba
'channel': channel, // // 'channel': channel,
'country': country, // // 'country': country,
'count': count, // // 'count': count,
'hasPlan': hasPlan // // 'hasPlan':hasPlan
}); // static Future<int> printAsOrder(
return result; // {required String code,
} // required String fbaCode,
} // required String channel,
// required String country,
// required String count,
// required bool hasPlan}) async {
// int result = await _channel.invokeMethod('printAsOrder', {
// 'code': code,
// 'fbaCode': fbaCode,
// 'channel': channel,
// 'country': country,
// 'count': count,
// 'hasPlan': hasPlan
// });
// return result;
// }
// }

@ -0,0 +1,13 @@
// enum PRINT_STATUS {
// normal,
// busy,
// paperEmpty,
// coverOpen,
// batteryLow,
// }
enum PRINT_STATUS {
normal,
fail,
paperEmpty,
coverOpen,
}

@ -7,7 +7,7 @@ packages:
name: async name: async
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.7.0" version: "2.8.2"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
@ -21,7 +21,7 @@ packages:
name: characters name: characters
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.1.0" version: "1.2.0"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
@ -42,40 +42,19 @@ packages:
name: collection name: collection
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.15.0" version: "1.16.0"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.1"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
name: fake_async name: fake_async
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.2.0" version: "1.3.0"
fixnum:
dependency: transitive
description:
name: fixnum
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.0"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_blue:
dependency: "direct main"
description:
name: flutter_blue
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.8.0"
flutter_lints: flutter_lints:
dependency: "direct dev" dependency: "direct dev"
description: description:
@ -101,35 +80,28 @@ packages:
name: matcher name: matcher
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.12.10" version: "0.12.11"
meta: material_color_utilities:
dependency: transitive
description:
name: meta
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.4.0"
path:
dependency: transitive dependency: transitive
description: description:
name: path name: material_color_utilities
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.8.0" version: "0.1.4"
protobuf: meta:
dependency: transitive dependency: transitive
description: description:
name: protobuf name: meta
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.0.0" version: "1.7.0"
rxdart: path:
dependency: transitive dependency: transitive
description: description:
name: rxdart name: path
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.26.0" version: "1.8.1"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -141,7 +113,7 @@ packages:
name: source_span name: source_span
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.8.1" version: "1.8.2"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
@ -176,21 +148,14 @@ packages:
name: test_api name: test_api
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.4.1" version: "0.4.9"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.0"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
name: vector_math name: vector_math
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.1.0" version: "2.1.2"
sdks: sdks:
dart: ">=2.12.0 <3.0.0" dart: ">=2.17.0-0 <3.0.0"
flutter: ">=1.20.0" flutter: ">=1.20.0"

@ -10,8 +10,8 @@ environment:
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
flutter_blue: ^0.8.0 # flutter_blue_plus: ^1.3.1
# permission_handler: 10.0.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter

Loading…
Cancel
Save