init: init proj
This commit is contained in:
52
Printer/build.gradle
Normal file
52
Printer/build.gradle
Normal file
@@ -0,0 +1,52 @@
|
||||
|
||||
plugins {
|
||||
id 'com.android.library'
|
||||
id 'kotlin-android'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 31
|
||||
buildToolsVersion '30.0.3'
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 22
|
||||
targetSdkVersion 30
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
dataBinding = true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
implementation 'androidx.core:core-ktx:1.3.2'
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||
implementation 'com.google.android.material:material:1.2.1'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.4'
|
||||
}
|
||||
0
Printer/consumer-rules.pro
Normal file
0
Printer/consumer-rules.pro
Normal file
21
Printer/proguard-rules.pro
vendored
Normal file
21
Printer/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.huitao.printer
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
fun useAppContext() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals("com.huitao.printer.test", appContext.packageName)
|
||||
}
|
||||
}
|
||||
14
Printer/src/main/AndroidManifest.xml
Normal file
14
Printer/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.huitao.printer">
|
||||
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
|
||||
<application>
|
||||
<provider
|
||||
android:name=".PrinterProvider"
|
||||
android:authorities="${applicationId}.printer-tool"
|
||||
android:exported="false" />
|
||||
</application>
|
||||
</manifest>
|
||||
82
Printer/src/main/java/com/huitao/printer/Printer.kt
Normal file
82
Printer/src/main/java/com/huitao/printer/Printer.kt
Normal file
@@ -0,0 +1,82 @@
|
||||
package com.huitao.printer
|
||||
|
||||
import android.content.Context
|
||||
import com.huitao.printer.printerface.DeviceFoundCallback
|
||||
import com.huitao.printer.printerface.ProcessData
|
||||
import com.huitao.printer.printerface.TaskCallback
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
/**
|
||||
*author : huitao
|
||||
*e-mail : pig.huitao@gmail.com
|
||||
*/
|
||||
class Printer private constructor() {
|
||||
private var context: WeakReference<Context>? = null
|
||||
private lateinit var printerModel: PrinterModel
|
||||
|
||||
companion object {
|
||||
private var singleInstance: Printer? = null
|
||||
get() {
|
||||
if (null == field) {
|
||||
field = Printer()
|
||||
}
|
||||
|
||||
return field
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun getInstance() = singleInstance!!
|
||||
|
||||
}
|
||||
|
||||
fun initPrinter(context: Context) {
|
||||
this.context = WeakReference(context)
|
||||
printerModel = PrinterModel(this)
|
||||
printerModel.startPrinterService()
|
||||
}
|
||||
|
||||
|
||||
fun getContext(): Context? {
|
||||
return this.context?.get()
|
||||
}
|
||||
|
||||
|
||||
fun getBondDevicesList(foundCallback: DeviceFoundCallback): MutableList<String>? {
|
||||
return printerModel.getBondDeviceList(foundCallback)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param[mac] the printer mac
|
||||
* @param[taskCallback] the connect state by the taskCallback call
|
||||
*/
|
||||
fun connectDeviceByMac(mac: String, taskCallback: TaskCallback) {
|
||||
printerModel.connectDeviceByMac(mac, taskCallback)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param[taskCallback] the disconnect state by taskCallback call
|
||||
*/
|
||||
fun disconnected(taskCallback: TaskCallback) {
|
||||
printerModel.disconnected(taskCallback)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param[taskCallback] write state by the taskCallback call
|
||||
* @param[processData] the send data
|
||||
*/
|
||||
fun writeData(taskCallback: TaskCallback, processData: ProcessData) {
|
||||
printerModel.writeData(taskCallback, processData)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param[byteArray] the send data
|
||||
* @param[taskCallback] write state by the taskCallback call
|
||||
*/
|
||||
fun writeData(byteArray: ByteArray, taskCallback: TaskCallback) {
|
||||
printerModel.writeData(byteArray, taskCallback)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.huitao.printer
|
||||
|
||||
/**
|
||||
*author : huitao
|
||||
*e-mail : pig.huitao@gmail.com
|
||||
*/
|
||||
data class PrinterConfig(val isAutoConnect:Boolean =false)
|
||||
94
Printer/src/main/java/com/huitao/printer/PrinterModel.kt
Normal file
94
Printer/src/main/java/com/huitao/printer/PrinterModel.kt
Normal file
@@ -0,0 +1,94 @@
|
||||
package com.huitao.printer
|
||||
|
||||
import android.app.Service
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.os.IBinder
|
||||
import com.huitao.printer.listener.BondListCallback
|
||||
import com.huitao.printer.printerface.DeviceFoundCallback
|
||||
import com.huitao.printer.printerface.IMyBinder
|
||||
import com.huitao.printer.printerface.ProcessData
|
||||
import com.huitao.printer.printerface.TaskCallback
|
||||
import com.huitao.printer.service.PrinterService
|
||||
import com.huitao.printer.utils.PrinterDev
|
||||
|
||||
|
||||
/**
|
||||
*author : huitao
|
||||
*e-mail : pig.huitao@gmail.com
|
||||
*/
|
||||
class PrinterModel constructor(private val printer: Printer) {
|
||||
|
||||
private var mIMyBinder: IMyBinder? = null
|
||||
private val mServiceConnect = object : ServiceConnection {
|
||||
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
||||
mIMyBinder = service as IMyBinder
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(name: ComponentName?) {
|
||||
startPrinterService()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return return the bond devices
|
||||
*/
|
||||
fun getBondDeviceList(deviceFoundCallback: DeviceFoundCallback): MutableList<String>? {
|
||||
mIMyBinder?.let {
|
||||
printer.getContext()?.let { ctx ->
|
||||
return it.onDiscovery(
|
||||
ctx,
|
||||
PrinterDev.PortType.Bluetooth,
|
||||
deviceFoundCallback
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun connectDeviceByMac(mac: String, taskCallback: TaskCallback) {
|
||||
mIMyBinder?.let {
|
||||
it.connectBtPort(mac, taskCallback)
|
||||
return
|
||||
}
|
||||
taskCallback.onFailed("mIMyBinder is not initialization,the lib was wrong")
|
||||
}
|
||||
|
||||
fun disconnected(taskCallback: TaskCallback) {
|
||||
mIMyBinder?.let {
|
||||
it.disconnectCurrentPort(taskCallback)
|
||||
return
|
||||
}
|
||||
taskCallback.onFailed("mIMyBinder is not initialization,the lib was wrong")
|
||||
}
|
||||
|
||||
fun writeData(taskCallback: TaskCallback, processData: ProcessData) {
|
||||
mIMyBinder?.let {
|
||||
it.writeSendData(taskCallback, processData)
|
||||
return
|
||||
}
|
||||
taskCallback.onFailed("mIMyBinder is not initialization,the lib was wrong")
|
||||
}
|
||||
|
||||
fun writeData(byteArray: ByteArray, taskCallback: TaskCallback) {
|
||||
mIMyBinder?.let {
|
||||
it.write(byteArray, taskCallback)
|
||||
return
|
||||
}
|
||||
taskCallback.onFailed("mIMyBinder is not initialization,the lib was wrong")
|
||||
}
|
||||
|
||||
|
||||
fun startPrinterService(): PrinterModel {
|
||||
printer.getContext()?.let {
|
||||
val service = Intent(it, PrinterService::class.java)
|
||||
it.bindService(service, mServiceConnect, Service.BIND_AUTO_CREATE)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
50
Printer/src/main/java/com/huitao/printer/PrinterProvider.kt
Normal file
50
Printer/src/main/java/com/huitao/printer/PrinterProvider.kt
Normal file
@@ -0,0 +1,50 @@
|
||||
package com.huitao.printer
|
||||
|
||||
import android.content.ContentProvider
|
||||
import android.content.ContentValues
|
||||
import android.database.Cursor
|
||||
import android.net.Uri
|
||||
|
||||
/**
|
||||
*author : huitao
|
||||
*e-mail : pig.huitao@gmail.com
|
||||
*/
|
||||
class PrinterProvider : ContentProvider() {
|
||||
override fun onCreate(): Boolean {
|
||||
context?.let {
|
||||
Printer.getInstance().initPrinter(it)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun query(
|
||||
uri: Uri,
|
||||
projection: Array<out String>?,
|
||||
selection: String?,
|
||||
selectionArgs: Array<out String>?,
|
||||
sortOrder: String?
|
||||
): Cursor? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getType(uri: Uri): String? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun insert(uri: Uri, values: ContentValues?): Uri? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
override fun update(
|
||||
uri: Uri,
|
||||
values: ContentValues?,
|
||||
selection: String?,
|
||||
selectionArgs: Array<out String>?
|
||||
): Int {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.huitao.printer.listener
|
||||
|
||||
/**
|
||||
*author : huitao
|
||||
*e-mail : pig.huitao@gmail.com
|
||||
*/
|
||||
interface BondListCallback {
|
||||
|
||||
fun onBondListCallback(bondList:MutableList<String>)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.huitao.printer.printerface
|
||||
|
||||
/**
|
||||
*author : huitao
|
||||
*e-mail : pig.huitao@gmail.com
|
||||
*date : 2021/4/28 14:55
|
||||
*desc :
|
||||
*version :
|
||||
*/
|
||||
interface DeviceFoundCallback {
|
||||
fun deviceFoundCallback(device:String)
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.huitao.printer.printerface
|
||||
|
||||
import android.content.Context
|
||||
import com.huitao.printer.utils.PrinterDev
|
||||
import com.huitao.printer.utils.RoundQueue
|
||||
|
||||
/**
|
||||
*author : huitao
|
||||
*e-mail : pig.huitao@gmail.com
|
||||
*date : 2021/4/13 10:42
|
||||
*desc :
|
||||
*version :
|
||||
*/
|
||||
interface IMyBinder {
|
||||
fun connectBtPort(var1: String, var2: TaskCallback)
|
||||
|
||||
fun disconnectCurrentPort(var1: TaskCallback)
|
||||
|
||||
fun clearBuffer()
|
||||
|
||||
fun checkLinkedState(var1: TaskCallback)
|
||||
|
||||
fun onDiscovery(
|
||||
var1: Context,
|
||||
portType: PrinterDev.PortType,
|
||||
callback: DeviceFoundCallback
|
||||
): MutableList<String>?
|
||||
|
||||
fun getBtAvailableDevice(): MutableList<String>
|
||||
|
||||
fun write(var1: ByteArray?, var2: TaskCallback)
|
||||
|
||||
fun writeSendData(var1: TaskCallback, var2: ProcessData)
|
||||
|
||||
fun acceptDataFromPrinter(var1: TaskCallback?, var2: Int)
|
||||
|
||||
fun readBuffer(): RoundQueue<ByteArray?>?
|
||||
|
||||
fun read(var1: TaskCallback)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.huitao.printer.printerface
|
||||
|
||||
/**
|
||||
*author : huitao
|
||||
*e-mail : pig.huitao@gmail.com
|
||||
*date : 2021/4/14 10:15
|
||||
*desc :
|
||||
*version :
|
||||
*/
|
||||
interface ProcessData {
|
||||
fun processDataBeforeSend(): MutableList<ByteArray>?
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.huitao.printer.printerface
|
||||
|
||||
/**
|
||||
*author : huitao
|
||||
*e-mail : pig.huitao@gmail.com
|
||||
*date : 2021/4/13 10:43
|
||||
*desc :
|
||||
*version :
|
||||
*/
|
||||
interface TaskCallback {
|
||||
fun onSucceed()
|
||||
|
||||
fun onFailed(error:String)
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
package com.huitao.printer.service
|
||||
|
||||
import android.app.Service
|
||||
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.Binder
|
||||
import android.os.IBinder
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import com.huitao.printer.printerface.DeviceFoundCallback
|
||||
import com.huitao.printer.printerface.IMyBinder
|
||||
import com.huitao.printer.printerface.ProcessData
|
||||
import com.huitao.printer.printerface.TaskCallback
|
||||
import com.huitao.printer.utils.PrinterDev
|
||||
import com.huitao.printer.utils.ReturnMessage
|
||||
import com.huitao.printer.utils.RoundQueue
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
*author : huitao
|
||||
*e-mail : pig.huitao@gmail.com
|
||||
*date : 2021/4/13 10:39
|
||||
*desc :
|
||||
*version :
|
||||
*/
|
||||
class PrinterService : Service() {
|
||||
private val mMyBinder = MyBinder()
|
||||
private lateinit var mPrinterDev: PrinterDev
|
||||
private lateinit var mReturnMsg: ReturnMessage
|
||||
private var mIsConnected = false
|
||||
private var mQueue: RoundQueue<ByteArray>? = null
|
||||
private var mDeviceFoundCallback: DeviceFoundCallback? = null
|
||||
private fun getInstanceRoundQueue(): RoundQueue<ByteArray> {
|
||||
if (this.mQueue == null) {
|
||||
mQueue = RoundQueue(500)
|
||||
}
|
||||
return this.mQueue!!
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
this.mQueue = this.getInstanceRoundQueue()
|
||||
}
|
||||
|
||||
|
||||
private val mViewModelScope = CoroutineScope(Dispatchers.IO)
|
||||
override fun onBind(p0: Intent?): IBinder {
|
||||
return this.mMyBinder
|
||||
}
|
||||
|
||||
|
||||
inner class MyBinder : Binder(), IMyBinder {
|
||||
private var mBluetoothAdapter: BluetoothAdapter? = null
|
||||
private var mFond: MutableList<String>? = null
|
||||
private var mBond: MutableList<String>? = null
|
||||
private var mPortType: PrinterDev.PortType? = null
|
||||
private val mReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(p0: Context?, p1: Intent?) {
|
||||
p1?.let {
|
||||
if (it.action == "android.bluetooth.device.action.FOUND") {
|
||||
val device =
|
||||
it.getParcelableExtra<BluetoothDevice>("android.bluetooth.device.extra.DEVICE")
|
||||
?: return
|
||||
if (!device.name.isNullOrEmpty()) {
|
||||
mFond?.forEach { found ->
|
||||
if (found.split("\n").last() == device.address) {
|
||||
return
|
||||
}
|
||||
}
|
||||
mFond?.add("${device.name}\n${device.address}")
|
||||
mDeviceFoundCallback?.deviceFoundCallback("${device.name} \n ${device.address}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun connectBtPort(var1: String, var2: TaskCallback) {
|
||||
mViewModelScope.launch {
|
||||
mPrinterDev = PrinterDev(PrinterDev.PortType.Bluetooth, var1)
|
||||
mReturnMsg = mPrinterDev.open()
|
||||
mPortType = PrinterDev.PortType.Bluetooth
|
||||
mViewModelScope.launch(Dispatchers.Main) {
|
||||
when (mReturnMsg.getErrorCode()) {
|
||||
PrinterDev.ErrorCode.OpenPortSucceed -> {
|
||||
mIsConnected = true
|
||||
var2.onSucceed()
|
||||
}
|
||||
else -> {
|
||||
var2.onFailed("Bluetooth connected Failed")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun disconnectCurrentPort(var1: TaskCallback) {
|
||||
mViewModelScope.launch {
|
||||
mReturnMsg = mPrinterDev.close()
|
||||
mViewModelScope.launch(Dispatchers.Main) {
|
||||
when (mReturnMsg.getErrorCode()) {
|
||||
PrinterDev.ErrorCode.ClosePortSucceed -> {
|
||||
mIsConnected = false
|
||||
if (mQueue != null) {
|
||||
mQueue?.clear()
|
||||
}
|
||||
var1.onSucceed()
|
||||
}
|
||||
else -> {
|
||||
var1.onFailed("Bluetooth disconnected failed")
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
override fun clearBuffer() {
|
||||
mQueue?.clear()
|
||||
}
|
||||
|
||||
override fun checkLinkedState(var1: TaskCallback) {
|
||||
mViewModelScope.launch {
|
||||
if (mPrinterDev.getPortInfo().isOpened) var1.onSucceed() else var1.onFailed("")
|
||||
}.start()
|
||||
}
|
||||
|
||||
override fun onDiscovery(
|
||||
var1: Context,
|
||||
portType: PrinterDev.PortType,
|
||||
callback: DeviceFoundCallback
|
||||
): MutableList<String>? {
|
||||
this.mFond = mutableListOf()
|
||||
this.mBond = mutableListOf()
|
||||
mDeviceFoundCallback = callback
|
||||
if (portType == PrinterDev.PortType.Bluetooth) {
|
||||
this.mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
|
||||
if (mBluetoothAdapter == null) {
|
||||
Toast.makeText(
|
||||
this@PrinterService,
|
||||
"Device didn't support bluetooth !\n",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
return null
|
||||
}
|
||||
if (mBluetoothAdapter!!.isEnabled) {
|
||||
if (mBluetoothAdapter!!.enable()) {
|
||||
if (!mBluetoothAdapter!!.isDiscovering) {
|
||||
mBluetoothAdapter!!.startDiscovery()
|
||||
}
|
||||
val filter = IntentFilter("android.bluetooth.device.action.FOUND")
|
||||
registerReceiver(mReceiver, filter)
|
||||
val pairedDevice = mBluetoothAdapter!!.bondedDevices
|
||||
if (!pairedDevice.isNullOrEmpty()) {
|
||||
val it = pairedDevice.iterator()
|
||||
while (it.hasNext()) {
|
||||
val device = it.next()
|
||||
mBond?.add("${device.name}\n${device.address}")
|
||||
}
|
||||
} else {
|
||||
Looper.prepare()
|
||||
Toast.makeText(
|
||||
this@PrinterService,
|
||||
"no paired device",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
Looper.loop()
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(
|
||||
this@PrinterService,
|
||||
"Bluetooth is not enable !\n",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
} else {
|
||||
Toast.makeText(
|
||||
this@PrinterService,
|
||||
"Bluetooth adapter is not enabled !\n",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
|
||||
}
|
||||
return this.mBond
|
||||
}
|
||||
|
||||
override fun getBtAvailableDevice(): MutableList<String> {
|
||||
this.mBluetoothAdapter?.cancelDiscovery()
|
||||
return this.mFond!!
|
||||
}
|
||||
|
||||
override fun write(var1: ByteArray?, var2: TaskCallback) {
|
||||
if (var1 != null) {
|
||||
mViewModelScope.launch {
|
||||
mReturnMsg = mPrinterDev.write(var1)
|
||||
mViewModelScope.launch(Dispatchers.Main) {
|
||||
when (mReturnMsg.getErrorCode()) {
|
||||
PrinterDev.ErrorCode.WriteDataSucceed -> {
|
||||
mIsConnected = true
|
||||
var2.onSucceed()
|
||||
}
|
||||
else -> {
|
||||
mIsConnected = false
|
||||
var2.onFailed("Write data failed ,please check the device connected")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun writeSendData(var1: TaskCallback, var2: ProcessData) {
|
||||
val list = var2.processDataBeforeSend()
|
||||
if (list == null) {
|
||||
var1.onFailed("Write data is null")
|
||||
} else {
|
||||
mViewModelScope.launch {
|
||||
list.forEach {
|
||||
mReturnMsg = mPrinterDev.write(it)
|
||||
}
|
||||
when (mReturnMsg.getErrorCode()) {
|
||||
PrinterDev.ErrorCode.WriteDataSucceed -> {
|
||||
mIsConnected = true
|
||||
var1.onSucceed()
|
||||
}
|
||||
else -> {
|
||||
mIsConnected = false
|
||||
var1.onFailed("Bluetooth is no connected,please connect first")
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
}
|
||||
|
||||
override fun acceptDataFromPrinter(var1: TaskCallback?, var2: Int) {
|
||||
val buffer = ByteArray(var2)
|
||||
mViewModelScope.launch {
|
||||
kotlin.runCatching {
|
||||
mQueue = getInstanceRoundQueue()
|
||||
mQueue?.clear()
|
||||
mQueue?.addLast(buffer)
|
||||
Log.i("frank", "acceptDataFromPrinter: " + Arrays.toString(mQueue!!.last))
|
||||
}.onSuccess {
|
||||
|
||||
}.onFailure {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun readBuffer(): RoundQueue<ByteArray?>? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun read(var1: TaskCallback) {
|
||||
mViewModelScope.launch {
|
||||
val msg = mPrinterDev.read()
|
||||
Log.d("frank", "read: $msg")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
25
Printer/src/main/java/com/huitao/printer/utils/ByteUtil.kt
Normal file
25
Printer/src/main/java/com/huitao/printer/utils/ByteUtil.kt
Normal file
@@ -0,0 +1,25 @@
|
||||
package com.huitao.printer.utils
|
||||
|
||||
/**
|
||||
*author : huitao
|
||||
*e-mail : pig.huitao@gmail.com
|
||||
*date : 2021/4/15 10:45
|
||||
*desc :
|
||||
*version :
|
||||
*/
|
||||
|
||||
|
||||
fun byteArrayOfInts(vararg ints: Int) =
|
||||
ByteArray(ints.size) { pos -> ints[pos].toByte() }
|
||||
|
||||
|
||||
fun byteMerge(b1: ByteArray, b2: ByteArray): ByteArray {
|
||||
val b3 = ByteArray(b1.size + b2.size)
|
||||
System.arraycopy(b1, 0, b3, 0, b1.size)
|
||||
System.arraycopy(b2, 0, b3, b1.size, b2.size)
|
||||
return b3
|
||||
}
|
||||
|
||||
fun getByteLength(str: String): Int {
|
||||
return str.toByteArray(charSetName()).size
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
package com.huitao.printer.utils
|
||||
|
||||
import java.lang.StringBuilder
|
||||
import java.nio.charset.Charset
|
||||
|
||||
/**
|
||||
*author : huitao
|
||||
*e-mail : pig.huitao@gmail.com
|
||||
*date : 2021/4/15 9:23
|
||||
*desc :
|
||||
*version :
|
||||
*/
|
||||
object DataForSendToPrinter {
|
||||
private const val horizontal_length = 32
|
||||
private const val left_length = 18
|
||||
private const val right_length = 14
|
||||
|
||||
///水平定位
|
||||
fun horizontalPositioning(): ByteArray {
|
||||
return byteArrayOfInts(0x09)
|
||||
}
|
||||
|
||||
///打印并换行
|
||||
fun printAndFeedLine(): ByteArray {
|
||||
return byteArrayOfInts(0x0A)
|
||||
}
|
||||
|
||||
///打印并换行
|
||||
fun printAddPaperWalking(n: Int = 0x01): ByteArray {
|
||||
return byteArrayOfInts(0x1B, 0x4A, n)
|
||||
}
|
||||
|
||||
///设置字符右间距
|
||||
fun setCharRightSpace(n: Int): ByteArray {
|
||||
return byteArrayOfInts(0x1B, 0x20, n)
|
||||
}
|
||||
|
||||
///选择打印模式
|
||||
fun selectPrintModel(n: Int): ByteArray {
|
||||
return byteArrayOfInts(0x1B, 0x21, n)
|
||||
}
|
||||
|
||||
///设置绝对打印位置
|
||||
fun setAbsolutePrintPosition(m: Int, n: Int): ByteArray {
|
||||
return byteArrayOfInts(0x1B, 0x24, m, n)
|
||||
}
|
||||
|
||||
///选择/取消用户自定义字符
|
||||
fun selectOrCancelCustomerChar(n: Int): ByteArray {
|
||||
return byteArrayOfInts(0x1B, 0x25, n)
|
||||
}
|
||||
|
||||
///定义用户自定义字符
|
||||
fun defineUserDefinedCharacters(c1: Int, c2: Int, b: ByteArray): ByteArray {
|
||||
return byteMerge(byteArrayOf(0x1B.toByte(), 0x26.toByte(), c1.toByte(), c2.toByte()), b)
|
||||
}
|
||||
|
||||
//选择位图模式
|
||||
fun selectBtmModel(m: Int, nL: Int, nH: Int, b: ByteArray): ByteArray {
|
||||
return byteMerge(byteArrayOfInts(0x1B, 0x2A, m, nL, nH), b)
|
||||
}
|
||||
|
||||
///选择取消下划线模式
|
||||
fun selectOrCancelUnderlineModel(n: Int): ByteArray {
|
||||
return byteArrayOfInts(0x1B, 0x2D, n)
|
||||
}
|
||||
|
||||
///设置默认行间距
|
||||
fun setDefaultLineSpace(): ByteArray {
|
||||
return byteArrayOfInts(0x1B, 0x32)
|
||||
}
|
||||
|
||||
///设置行间距
|
||||
fun setLineSpace(n: Int): ByteArray {
|
||||
return byteArrayOfInts(0x1B, 0x33, n)
|
||||
}
|
||||
|
||||
///取消用户自定义字符
|
||||
fun cancelUserDefineCharsets(n: Int): ByteArray {
|
||||
return byteArrayOfInts(0x1B, 0x3F, n)
|
||||
}
|
||||
|
||||
///初始化打印机
|
||||
fun initializePrinter(): ByteArray {
|
||||
return byteArrayOfInts(0x1B, 0x40)
|
||||
}
|
||||
|
||||
///设置横向跳格位置
|
||||
fun setHorizontalMovementPosition(b: ByteArray): ByteArray {
|
||||
var data = byteArrayOfInts(0x1B, 0x44)
|
||||
val nul = ByteArray(1)
|
||||
data = byteMerge(data, b)
|
||||
data = byteMerge(data, nul)
|
||||
return data
|
||||
}
|
||||
|
||||
///选择取消加粗模式
|
||||
fun selectOrCancelBoldModel(n: Int): ByteArray {
|
||||
return byteArrayOfInts(0x1B, 0x45, n)
|
||||
}
|
||||
|
||||
///选择/取消双重打印模式
|
||||
fun selectOrCancelDoublePrinterModel(n: Int): ByteArray {
|
||||
return byteArrayOfInts(0x1B, 0x47, n)
|
||||
}
|
||||
|
||||
|
||||
///打印并走纸
|
||||
fun printAndFeed(n: Int): ByteArray {
|
||||
return byteArrayOfInts(0x1B, 0x4A, n)
|
||||
}
|
||||
|
||||
///选择字体
|
||||
fun selectFont(n: Int): ByteArray {
|
||||
return byteArrayOfInts(0x1B, 0x4D, n)
|
||||
}
|
||||
|
||||
///选择国际字符集
|
||||
fun selectInternationalCharsetSets(n: Int): ByteArray {
|
||||
return byteArrayOfInts(0x1B, 0x52, n)
|
||||
}
|
||||
|
||||
///选择/取消顺时针旋转90
|
||||
fun selectOrCancelCW90(n: Int): ByteArray {
|
||||
return byteArrayOfInts(0x1B, 0x56, n)
|
||||
}
|
||||
|
||||
///设置相对横向打印位置
|
||||
fun setRelativeHorizontalPrintPosition(nL: Int, nH: Int): ByteArray {
|
||||
return byteArrayOfInts(0x1B, 0x5C, nL, nH)
|
||||
}
|
||||
|
||||
///选择对齐方式
|
||||
fun selectAliment(n: Int): ByteArray {
|
||||
return byteArrayOfInts(0x1B, 0x61, n)
|
||||
}
|
||||
|
||||
///允许/禁止按键
|
||||
fun allowOrForbidPressButton(n: Int): ByteArray {
|
||||
return byteArrayOfInts(0x1B, 0x63, 0x35, n)
|
||||
}
|
||||
|
||||
///打印并向前走纸n行
|
||||
fun printAndFeedForward(n: Int): ByteArray {
|
||||
return byteArrayOfInts(0x1B, 0x64, n)
|
||||
}
|
||||
|
||||
//设置字体大小
|
||||
fun selectFontSize(n: Int): ByteArray {
|
||||
return byteArrayOfInts(0x1D, 0x21, n)
|
||||
}
|
||||
|
||||
fun queryPrinterState(): ByteArray {
|
||||
return byteArrayOfInts(0x1B, 0x76)
|
||||
}
|
||||
|
||||
|
||||
fun printBothColumns(str1: String, str2: String): ByteArray {
|
||||
val byte1Length: Int = getByteLength(str1)
|
||||
val byte2Length = getByteLength(str2)
|
||||
val spaceLength = horizontal_length - byte1Length - byte2Length
|
||||
val sb = StringBuilder()
|
||||
sb.append(str1)
|
||||
for (i in 0 until spaceLength) {
|
||||
sb.append(" ")
|
||||
}
|
||||
sb.append(str2)
|
||||
return strToBytes(sb.toString())!!
|
||||
}
|
||||
|
||||
fun printThreeColumns(str1: String, str2: String, str3: String): ByteArray {
|
||||
val sb = StringBuilder()
|
||||
//由于在打印的时候商品名称大度为一行,因此不做左边长度处理
|
||||
sb.append(str1)
|
||||
val leftSpaceLength = left_length - getByteLength(str1) - getByteLength(str2) / 2
|
||||
for (i in 0 until leftSpaceLength) {
|
||||
sb.append(" ")
|
||||
}
|
||||
sb.append(str2)
|
||||
val rightSpaceLength = right_length - getByteLength(str3) - getByteLength(str2) / 2
|
||||
for (i in 0 until rightSpaceLength) {
|
||||
sb.append(" ")
|
||||
}
|
||||
sb.delete(sb.length - 1, sb.length)
|
||||
sb.append(str3)
|
||||
return strToBytes(sb.toString())!!
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
18
Printer/src/main/java/com/huitao/printer/utils/PortInfo.kt
Normal file
18
Printer/src/main/java/com/huitao/printer/utils/PortInfo.kt
Normal file
@@ -0,0 +1,18 @@
|
||||
package com.huitao.printer.utils
|
||||
|
||||
import android.content.Context
|
||||
|
||||
/**
|
||||
*author : huitao
|
||||
*e-mail : pig.huitao@gmail.com
|
||||
*date : 2021/4/13 11:22
|
||||
*desc :
|
||||
*version :
|
||||
*/
|
||||
data class PortInfo(
|
||||
var bluetoothId: String = "",
|
||||
var context: Context? = null,
|
||||
var parIsOk: Boolean = false,
|
||||
var isOpened: Boolean = false,
|
||||
var portType: PrinterDev.PortType? = null
|
||||
)
|
||||
278
Printer/src/main/java/com/huitao/printer/utils/PrinterDev.kt
Normal file
278
Printer/src/main/java/com/huitao/printer/utils/PrinterDev.kt
Normal file
@@ -0,0 +1,278 @@
|
||||
package com.huitao.printer.utils
|
||||
|
||||
import android.bluetooth.BluetoothAdapter
|
||||
import android.bluetooth.BluetoothDevice
|
||||
import android.bluetooth.BluetoothSocket
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import java.lang.Exception
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
*author : huitao
|
||||
*e-mail : pig.huitao@gmail.com
|
||||
*date : 2021/4/13 11:08
|
||||
*desc :
|
||||
*version :
|
||||
*/
|
||||
class PrinterDev(portType: PortType, bluetoothId: String) {
|
||||
|
||||
enum class ErrorCode private constructor() {
|
||||
OpenPortFailed,
|
||||
OpenPortSucceed,
|
||||
ClosePortFailed,
|
||||
ClosePortSucceed,
|
||||
WriteDataSucceed,
|
||||
WriteDataFailed,
|
||||
ReadDataSucceed,
|
||||
ReadDataFailed,
|
||||
UnKnownError;
|
||||
}
|
||||
|
||||
enum class PortType private constructor() {
|
||||
UnKnown,
|
||||
USB,
|
||||
Bluetooth,
|
||||
Ethernet;
|
||||
}
|
||||
|
||||
private var mPortInfo: PortInfo = PortInfo()
|
||||
private var mPrinterPort: PrinterPort? = null
|
||||
|
||||
|
||||
init {
|
||||
this.mPortInfo.portType = portType
|
||||
this.mPortInfo.bluetoothId = bluetoothId
|
||||
}
|
||||
|
||||
private fun resetPar() {
|
||||
mPortInfo = PortInfo()
|
||||
this.mPrinterPort?.closePort()
|
||||
this.mPrinterPort = null
|
||||
}
|
||||
|
||||
|
||||
fun open(): ReturnMessage {
|
||||
return when (mPortInfo.portType) {
|
||||
PortType.Bluetooth -> {
|
||||
this.open(this.mPortInfo.portType!!, this.mPortInfo.bluetoothId)
|
||||
}
|
||||
else -> {
|
||||
ReturnMessage(ErrorCode.OpenPortFailed, "Only support bluetooth !\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun open(portType: PortType, bluetoothId: String): ReturnMessage {
|
||||
this.resetPar()
|
||||
return when {
|
||||
portType != PortType.Bluetooth -> ReturnMessage(
|
||||
ErrorCode.OpenPortFailed,
|
||||
"Port type wrong !\n"
|
||||
)
|
||||
!BluetoothAdapter.checkBluetoothAddress(bluetoothId) -> ReturnMessage(
|
||||
ErrorCode.OpenPortFailed,
|
||||
"BluetoothId wrong !/n"
|
||||
)
|
||||
else -> {
|
||||
this.mPortInfo.bluetoothId = bluetoothId
|
||||
this.mPortInfo.portType = PortType.Bluetooth
|
||||
this.mPrinterPort = BluetoothPort(this.mPortInfo)
|
||||
this.mPrinterPort!!.openPort()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun close(): ReturnMessage {
|
||||
return if (this.mPrinterPort == null) ReturnMessage(
|
||||
ErrorCode.ClosePortFailed,
|
||||
"Not opened port !"
|
||||
) else this.mPrinterPort!!.closePort()
|
||||
}
|
||||
|
||||
fun write(data: ByteArray): ReturnMessage {
|
||||
return this.mPrinterPort!!.write(data)
|
||||
}
|
||||
|
||||
fun getPortInfo(): PortInfo {
|
||||
this.mPortInfo.isOpened = this.mPrinterPort!!.portIsOpen()
|
||||
return this.mPortInfo
|
||||
}
|
||||
|
||||
fun read(buffer: ByteArray): ReturnMessage {
|
||||
return this.read(buffer, 0, buffer.size)
|
||||
}
|
||||
|
||||
fun read(buffer: ByteArray, offset: Int, count: Int): ReturnMessage {
|
||||
val returnMessage: ReturnMessage? = mPrinterPort?.read(buffer, offset, count)
|
||||
return returnMessage!!
|
||||
}
|
||||
|
||||
fun read(): Int {
|
||||
val byte = ByteArray(1)
|
||||
return if (this.read(byte, 0, 1)
|
||||
.getErrorCode() == ErrorCode.ReadDataSucceed
|
||||
) byte[0].toInt() else -1
|
||||
}
|
||||
|
||||
private inner class BluetoothPort(portInfo: PortInfo) : PrinterPort(portInfo) {
|
||||
private val SPP_UUID: UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")
|
||||
private var mBluetoothAdapter: BluetoothAdapter? = null
|
||||
private var mBluetoothDevice: BluetoothDevice? = null
|
||||
private var mBluetoothSocket: BluetoothSocket? = null
|
||||
private var mOutputStream: OutputStream? = null
|
||||
private var mInputStream: InputStream? = null
|
||||
|
||||
init {
|
||||
when {
|
||||
portInfo.portType == PortType.Bluetooth && BluetoothAdapter.checkBluetoothAddress(
|
||||
portInfo.bluetoothId
|
||||
) -> {
|
||||
this.mPortInfo?.parIsOk = true
|
||||
this.mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
|
||||
}
|
||||
else -> this.mPortInfo?.parIsOk = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun openPort(): ReturnMessage {
|
||||
if (!this.mPortInfo!!.parIsOk) {
|
||||
return ReturnMessage(
|
||||
ErrorCode.OpenPortFailed,
|
||||
"PortInfo error !\n"
|
||||
)
|
||||
} else {
|
||||
try {
|
||||
if (this.mBluetoothAdapter == null) {
|
||||
return ReturnMessage(
|
||||
ErrorCode.OpenPortFailed,
|
||||
"Not Bluetooth adapter !\n"
|
||||
)
|
||||
}
|
||||
if (!this.mBluetoothAdapter!!.isEnabled) {
|
||||
return ReturnMessage(
|
||||
ErrorCode.OpenPortFailed,
|
||||
"Bluetooth adapter was closed !\n"
|
||||
)
|
||||
}
|
||||
this.mBluetoothAdapter?.cancelDiscovery()
|
||||
this.mBluetoothDevice =
|
||||
this.mBluetoothAdapter?.getRemoteDevice(this.mPortInfo?.bluetoothId)
|
||||
this.mBluetoothSocket =
|
||||
this.mBluetoothDevice?.createRfcommSocketToServiceRecord(this.SPP_UUID)
|
||||
this.mBluetoothSocket?.connect()
|
||||
this.mOutputStream = null
|
||||
this.mOutputStream = this.mBluetoothSocket?.outputStream
|
||||
this.mInputStream = this.mBluetoothSocket?.inputStream
|
||||
this.mIsOpen = true
|
||||
} catch (e: Exception) {
|
||||
return ReturnMessage(ErrorCode.OpenPortFailed, e.toString())
|
||||
}
|
||||
}
|
||||
|
||||
return ReturnMessage(ErrorCode.OpenPortSucceed, "Open bluetooth port success !\n")
|
||||
}
|
||||
|
||||
override fun closePort(): ReturnMessage {
|
||||
try {
|
||||
if (this.mOutputStream != null) {
|
||||
this.mOutputStream!!.flush()
|
||||
}
|
||||
if (this.mBluetoothSocket != null) {
|
||||
this.mBluetoothSocket?.close()
|
||||
}
|
||||
this.mIsOpen = false
|
||||
this.mOutputStream = null
|
||||
this.mInputStream = null
|
||||
} catch (e: Exception) {
|
||||
return ReturnMessage(ErrorCode.ClosePortFailed, e.toString())
|
||||
}
|
||||
return ReturnMessage(ErrorCode.ClosePortSucceed, "Close bluetooth port success !\n")
|
||||
}
|
||||
|
||||
override fun write(var1: Int): ReturnMessage {
|
||||
if (this.mIsOpen && this.mBluetoothSocket!!.isConnected && mOutputStream != null) {
|
||||
try {
|
||||
this.mOutputStream?.write(var1)
|
||||
this.mOutputStream?.flush()
|
||||
} catch (e: Exception) {
|
||||
this.closePort()
|
||||
return ReturnMessage(ErrorCode.WriteDataFailed, e.toString())
|
||||
}
|
||||
return ReturnMessage(ErrorCode.WriteDataSucceed, "Send 1 byte !\n", 1)
|
||||
} else {
|
||||
return ReturnMessage(ErrorCode.WriteDataFailed, "Bluetooth port was closed !\n")
|
||||
}
|
||||
}
|
||||
|
||||
override fun write(var1: ByteArray): ReturnMessage {
|
||||
if (this.mIsOpen && this.mBluetoothSocket!!.isConnected && mOutputStream != null) {
|
||||
try {
|
||||
this.mOutputStream?.write(var1)
|
||||
this.mOutputStream?.flush()
|
||||
} catch (e: Exception) {
|
||||
this.closePort()
|
||||
return ReturnMessage(ErrorCode.WriteDataFailed, e.toString())
|
||||
}
|
||||
return ReturnMessage(ErrorCode.WriteDataSucceed, "Send ${var1.size} bytes !\n")
|
||||
} else {
|
||||
return ReturnMessage(ErrorCode.WriteDataFailed, "Bluetooth port was closed !\n")
|
||||
}
|
||||
}
|
||||
|
||||
override fun write(var1: ByteArray, var2: Int, var3: Int): ReturnMessage {
|
||||
if (this.mIsOpen && this.mBluetoothSocket!!.isConnected && mOutputStream != null) {
|
||||
try {
|
||||
this.mOutputStream?.write(var1, var2, var3)
|
||||
this.mOutputStream?.flush()
|
||||
} catch (e: Exception) {
|
||||
this.closePort()
|
||||
return ReturnMessage(ErrorCode.WriteDataFailed, e.toString())
|
||||
}
|
||||
return ReturnMessage(ErrorCode.WriteDataSucceed, "Send $var3 bytes !\n ", var3)
|
||||
} else {
|
||||
return ReturnMessage(ErrorCode.WriteDataFailed, "Bluetooth port was closed")
|
||||
}
|
||||
}
|
||||
|
||||
override fun read(): Int {
|
||||
return if (this.mIsOpen && this.mBluetoothSocket!!.isConnected && this.mInputStream != null) {
|
||||
try {
|
||||
this.mInputStream!!.read()
|
||||
} catch (e: Exception) {
|
||||
-1
|
||||
}
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
}
|
||||
|
||||
override fun read(var1: ByteArray): ReturnMessage {
|
||||
return this.read(var1, 0, var1.size)
|
||||
}
|
||||
|
||||
override fun read(var1: ByteArray, var2: Int, var3: Int): ReturnMessage {
|
||||
if (this.mIsOpen && this.mBluetoothSocket!!.isConnected && this.mInputStream != null) {
|
||||
val readBytes: Int
|
||||
try {
|
||||
readBytes = this.mInputStream!!.read(var1, var2, var3)
|
||||
} catch (e: Exception) {
|
||||
return ReturnMessage(ErrorCode.ReadDataFailed, e.toString())
|
||||
}
|
||||
return ReturnMessage(ErrorCode.ReadDataSucceed, "Read $var3 bytes !\n", readBytes)
|
||||
} else {
|
||||
return ReturnMessage(ErrorCode.ReadDataFailed, "Bluetooth port was close !\n")
|
||||
}
|
||||
}
|
||||
|
||||
override fun portIsOpen(): Boolean {
|
||||
val b = ByteArray(4)
|
||||
val msg: ReturnMessage = this.read(b)
|
||||
this.mIsOpen = msg.getReadByteCount() != -1
|
||||
return this.mIsOpen
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.huitao.printer.utils
|
||||
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
*author : huitao
|
||||
*e-mail : pig.huitao@gmail.com
|
||||
*date : 2021/4/13 11:36
|
||||
*desc :
|
||||
*version :
|
||||
*/
|
||||
abstract class PrinterPort() {
|
||||
protected var mPortInfo: PortInfo? = null
|
||||
protected var mIsOpen = false
|
||||
protected var mRxdQueue: Queue<Byte>? = null
|
||||
|
||||
private var mTxdQueue: Queue<Byte>? = null
|
||||
|
||||
|
||||
abstract fun openPort(): ReturnMessage
|
||||
|
||||
abstract fun closePort(): ReturnMessage
|
||||
|
||||
abstract fun write(var1: Int): ReturnMessage
|
||||
|
||||
abstract fun write(var1: ByteArray): ReturnMessage
|
||||
|
||||
abstract fun write(var1: ByteArray, var2: Int, var3: Int): ReturnMessage
|
||||
|
||||
abstract fun read(): Int
|
||||
|
||||
abstract fun read(var1: ByteArray): ReturnMessage
|
||||
|
||||
abstract fun read(var1: ByteArray, var2: Int, var3: Int): ReturnMessage
|
||||
|
||||
abstract fun portIsOpen(): Boolean
|
||||
|
||||
constructor(portInfo: PortInfo) : this() {
|
||||
this.mPortInfo = portInfo
|
||||
}
|
||||
|
||||
fun getRxdCount(): Int {
|
||||
return if (mRxdQueue != null) mRxdQueue!!.size else 0
|
||||
}
|
||||
|
||||
fun getTxdCount(): Int {
|
||||
return if (mTxdQueue != null) mTxdQueue!!.size else 0
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.huitao.printer.utils
|
||||
|
||||
/**
|
||||
*author : huitao
|
||||
*e-mail : pig.huitao@gmail.com
|
||||
*date : 2021/4/13 11:39
|
||||
*desc :
|
||||
*version :
|
||||
*/
|
||||
class ReturnMessage() {
|
||||
private var mErrorCode: PrinterDev.ErrorCode? = null
|
||||
private var mErrorStrings: String? = null
|
||||
|
||||
private var mReadBytes: Int? = null
|
||||
|
||||
private var mWriteBytes: Int? = null
|
||||
|
||||
init {
|
||||
this.mErrorCode = PrinterDev.ErrorCode.UnKnownError
|
||||
this.mErrorStrings = "unknown error \n"
|
||||
this.mReadBytes = -1
|
||||
this.mWriteBytes = -1
|
||||
}
|
||||
|
||||
constructor(ec: PrinterDev.ErrorCode, es: String) : this() {
|
||||
this.mWriteBytes = -1
|
||||
this.mReadBytes = -1
|
||||
this.mErrorStrings = es
|
||||
this.mErrorCode = ec
|
||||
}
|
||||
|
||||
constructor(ec: PrinterDev.ErrorCode, es: String, count: Int) : this() {
|
||||
this.mErrorCode = ec
|
||||
this.mErrorStrings = es
|
||||
this.mReadBytes = -1
|
||||
this.mWriteBytes = -1
|
||||
when (count) {
|
||||
6 -> this.mReadBytes = count
|
||||
7 -> this.mReadBytes = count
|
||||
}
|
||||
}
|
||||
|
||||
fun getErrorCode(): PrinterDev.ErrorCode {
|
||||
return this.mErrorCode!!
|
||||
}
|
||||
|
||||
fun getErrorString(): String {
|
||||
return this.mErrorStrings!!
|
||||
}
|
||||
|
||||
fun getReadByteCount(): Int {
|
||||
return this.mReadBytes!!
|
||||
}
|
||||
|
||||
fun getWriteByCount(): Int {
|
||||
return this.mWriteBytes!!
|
||||
}
|
||||
|
||||
}
|
||||
102
Printer/src/main/java/com/huitao/printer/utils/RoundQueue.java
Normal file
102
Printer/src/main/java/com/huitao/printer/utils/RoundQueue.java
Normal file
@@ -0,0 +1,102 @@
|
||||
package com.huitao.printer.utils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* author : huitao
|
||||
* e-mail : pig.huitao@gmail.com
|
||||
* date : 2021/4/13 14:27
|
||||
* desc :
|
||||
* version :
|
||||
*/
|
||||
public class RoundQueue<T> implements Serializable {
|
||||
private static final long serialVersionUID = -873109114121357176L;
|
||||
private T[] queue;
|
||||
private int head = 0;
|
||||
private int tail = 0;
|
||||
private int realSize = 0;
|
||||
|
||||
public RoundQueue(int size) {
|
||||
this.queue = (T[]) new Object[size <= 0 ? 500 : size];
|
||||
}
|
||||
|
||||
public void addLast(T element) {
|
||||
if (this.isFull()) {
|
||||
this.removeFirst();
|
||||
}
|
||||
|
||||
this.tail = (this.head + this.realSize) % this.queue.length;
|
||||
this.queue[this.tail] = element;
|
||||
++this.realSize;
|
||||
}
|
||||
|
||||
public T removeFirst() {
|
||||
if (this.isEmpty()) {
|
||||
throw new NoSuchElementException();
|
||||
} else {
|
||||
T tempLog = this.queue[this.head];
|
||||
this.queue[this.head] = null;
|
||||
this.head = (this.head + 1) % this.queue.length;
|
||||
--this.realSize;
|
||||
return tempLog;
|
||||
}
|
||||
}
|
||||
|
||||
public int realSize() {
|
||||
return this.realSize;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.realSize() == 0;
|
||||
}
|
||||
|
||||
public boolean isFull() {
|
||||
return this.realSize() == this.queue.length;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
while (!this.isEmpty()) {
|
||||
this.removeFirst();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public T get(int index) {
|
||||
if (index >= 0 && index < this.realSize) {
|
||||
return this.queue[index];
|
||||
} else {
|
||||
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + this.realSize);
|
||||
}
|
||||
}
|
||||
|
||||
public int indexOf(T key) {
|
||||
if (key == null) {
|
||||
return -1;
|
||||
} else {
|
||||
for (int index = 0; index <= this.realSize() - 1; ++index) {
|
||||
if (key.equals(this.queue[index])) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int getHead() {
|
||||
return this.head;
|
||||
}
|
||||
|
||||
public int getTail() {
|
||||
return this.tail;
|
||||
}
|
||||
|
||||
public T getLast() {
|
||||
return this.queue[this.tail];
|
||||
}
|
||||
|
||||
public T getFirst() {
|
||||
return this.queue[this.head];
|
||||
}
|
||||
}
|
||||
43
Printer/src/main/java/com/huitao/printer/utils/StringUtil.kt
Normal file
43
Printer/src/main/java/com/huitao/printer/utils/StringUtil.kt
Normal file
@@ -0,0 +1,43 @@
|
||||
package com.huitao.printer.utils
|
||||
|
||||
import android.util.Log
|
||||
import java.lang.Exception
|
||||
import java.nio.charset.Charset
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.nio.charset.StandardCharsets.UTF_8
|
||||
|
||||
/**
|
||||
*author : huitao
|
||||
*e-mail : pig.huitao@gmail.com
|
||||
*date : 2021/4/15 13:51
|
||||
*desc :
|
||||
*version :
|
||||
*/
|
||||
|
||||
fun charSetName(): Charset = Charset.forName("gbk")
|
||||
|
||||
fun strToBytes(str: String): ByteArray? {
|
||||
|
||||
val data: ByteArray
|
||||
try {
|
||||
val b = str.toByteArray(charset = StandardCharsets.UTF_8)
|
||||
data = String(b).toByteArray(Charset.forName("gbk"))
|
||||
} catch (e: Exception) {
|
||||
return null
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
|
||||
fun strToBytes(str: String, charset: String): ByteArray? {
|
||||
val data: ByteArray?
|
||||
try {
|
||||
val b = str.toByteArray(charset = Charsets.UTF_8)
|
||||
data = String(b).toByteArray(Charset.forName("gbk"))
|
||||
} catch (e: Exception) {
|
||||
return null
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
17
Printer/src/test/java/com/huitao/printer/ExampleUnitTest.kt
Normal file
17
Printer/src/test/java/com/huitao/printer/ExampleUnitTest.kt
Normal file
@@ -0,0 +1,17 @@
|
||||
package com.huitao.printer
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
class ExampleUnitTest {
|
||||
@Test
|
||||
fun addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user