diff --git a/.idea/libraries/Flutter_Plugins.xml b/.idea/libraries/Flutter_Plugins.xml index 53449da..b0f6971 100644 --- a/.idea/libraries/Flutter_Plugins.xml +++ b/.idea/libraries/Flutter_Plugins.xml @@ -1,8 +1,6 @@ - - - + diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 3c9d085..ffed3a2 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip diff --git a/android/src/main/kotlin/app/mylekha/client/flutter_usb_printer/FlutterUsbPrinterPlugin.kt b/android/src/main/kotlin/app/mylekha/client/flutter_usb_printer/FlutterUsbPrinterPlugin.kt index 095d965..f451f93 100644 --- a/android/src/main/kotlin/app/mylekha/client/flutter_usb_printer/FlutterUsbPrinterPlugin.kt +++ b/android/src/main/kotlin/app/mylekha/client/flutter_usb_printer/FlutterUsbPrinterPlugin.kt @@ -13,8 +13,6 @@ import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel.MethodCallHandler import io.flutter.plugin.common.MethodChannel.Result - - /** FlutterUsbPrinterPlugin */ class FlutterUsbPrinterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware { private var adapter: USBPrinterAdapter? = null @@ -30,7 +28,7 @@ class FlutterUsbPrinterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware { channel = MethodChannel(flutterPluginBinding.binaryMessenger, "flutter_usb_printer") channel.setMethodCallHandler(this) context = flutterPluginBinding.getApplicationContext() - adapter = USBPrinterAdapter().getInstance() + adapter = USBPrinterAdapter.getInstance() } override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) { @@ -65,7 +63,6 @@ class FlutterUsbPrinterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware { } private fun getUSBDeviceList(result: Result) { - val usbDevices = adapter!!.getDeviceList() val list = ArrayList>() for (usbDevice in usbDevices) { @@ -81,11 +78,11 @@ class FlutterUsbPrinterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware { }else{ deviceMap["productName"] = "unknown"; } - deviceMap["deviceId"] = Integer.toString(usbDevice.deviceId) - deviceMap["vendorId"] = Integer.toString(usbDevice.vendorId) - deviceMap["productId"] = Integer.toString(usbDevice.productId) + deviceMap["deviceId"] = usbDevice.deviceId.toString() + deviceMap["vendorId"] = usbDevice.vendorId.toString() + deviceMap["productId"] = usbDevice.productId.toString() list.add(deviceMap) - print("usbDevice ${usbDevice}"); + print("usbDevice $usbDevice"); } result.success(list) } @@ -120,6 +117,7 @@ class FlutterUsbPrinterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware { override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) { channel.setMethodCallHandler(null) + USBPrinterAdapter.dispose() } override fun onAttachedToActivity(binding: ActivityPluginBinding) { diff --git a/android/src/main/kotlin/app/mylekha/client/flutter_usb_printer/adapter/USBPrinterAdapter.kt b/android/src/main/kotlin/app/mylekha/client/flutter_usb_printer/adapter/USBPrinterAdapter.kt index 61dabdf..68f9f92 100644 --- a/android/src/main/kotlin/app/mylekha/client/flutter_usb_printer/adapter/USBPrinterAdapter.kt +++ b/android/src/main/kotlin/app/mylekha/client/flutter_usb_printer/adapter/USBPrinterAdapter.kt @@ -1,5 +1,6 @@ package app.mylekha.client.flutter_usb_printer.adapter +import android.annotation.SuppressLint import android.app.PendingIntent import android.content.BroadcastReceiver import android.content.Context @@ -14,49 +15,68 @@ import java.nio.charset.Charset import java.util.* -class USBPrinterAdapter { +class USBPrinterAdapter private constructor(){ + companion object { + private const val TAG = "Flutter USB Printer" - private var mInstance: USBPrinterAdapter? = null + private const val ACTION_USB_PERMISSION = + "app.mylekha.client.flutter_usb_printer.USB_PERMISSION" - private val LOG_TAG = "Flutter USB Printer" + @SuppressLint("StaticFieldLeak") + private var mInstance: USBPrinterAdapter? = null + + fun getInstance(): USBPrinterAdapter { + if (mInstance == null) { + mInstance = USBPrinterAdapter() + } + return mInstance!! + } + + fun dispose() { + mInstance = null + } + } + private var mContext: Context? = null private var mUSBManager: UsbManager? = null - private var mPermissionIntent: PendingIntent? = null private var mUsbDevice: UsbDevice? = null private var mUsbDeviceConnection: UsbDeviceConnection? = null private var mUsbInterface: UsbInterface? = null private var mEndPoint: UsbEndpoint? = null - private val ACTION_USB_PERMISSION = "app.mylekha.client.flutter_usb_printer.USB_PERMISSION" + private val mUsbDeviceReceiver: BroadcastReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + val action = intent.action + if (ACTION_USB_PERMISSION == action) { + synchronized(this) { + var usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE) + if (usbDevice == null) { + Log.d(TAG, "onReceive: Received null USB") + val vendorId = intent.getIntExtra("vendorId", -1) + val productId = intent.getIntExtra("productId", -1) - fun getInstance(): USBPrinterAdapter? { - if (mInstance == null) { - mInstance = this; - } - return mInstance - } + if (vendorId == -1 || productId == -1) { + Log.d(TAG, "onReceive: No vendor id or product id") + return + } + + usbDevice = getDeviceByVendorAndProductId(vendorId, productId) ?: return + } - private val mUsbDeviceReceiver: BroadcastReceiver = object : BroadcastReceiver() { - override fun onReceive(context: Context, intent: Intent) { - var action = intent.getAction(); - if (ACTION_USB_PERMISSION.equals(action)) { - synchronized(this) { - val usbDevice = - intent.getParcelableExtra(UsbManager.EXTRA_DEVICE) if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { Log.i( - LOG_TAG, - "Success to grant permission for device " + usbDevice!!.deviceId + ", vendor_id: " + usbDevice.vendorId + " product_id: " + usbDevice.productId + TAG, + "Success to grant permission for device " + usbDevice.deviceId + ", vendor_id: " + usbDevice.vendorId + " product_id: " + usbDevice.productId ) mUsbDevice = usbDevice } else { Toast.makeText( context, - "User refused to give USB device permissions" + usbDevice!!.deviceName, + "User refused to give USB device permissions" + usbDevice.deviceName, Toast.LENGTH_LONG ).show() } @@ -74,17 +94,10 @@ class USBPrinterAdapter { fun init(reactContext: Context?) { mContext = reactContext mUSBManager = mContext!!.getSystemService(Context.USB_SERVICE) as UsbManager - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - mPermissionIntent = - PendingIntent.getBroadcast(mContext, 0, Intent(ACTION_USB_PERMISSION), PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE) - } else { - mPermissionIntent = - PendingIntent.getBroadcast(mContext, 0, Intent(ACTION_USB_PERMISSION), PendingIntent.FLAG_UPDATE_CURRENT) - } val filter = IntentFilter(ACTION_USB_PERMISSION) filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED) mContext!!.registerReceiver(mUsbDeviceReceiver, filter) - Log.v(LOG_TAG, "USB Printer initialized") + Log.v(TAG, "USB Printer initialized") } @@ -95,7 +108,7 @@ class USBPrinterAdapter { mUsbInterface = null mEndPoint = null mUsbDeviceConnection = null - mUsbDevice=null + mUsbDevice = null } } @@ -111,37 +124,52 @@ class USBPrinterAdapter { return ArrayList(mUSBManager!!.deviceList.values) } + private fun getDeviceByVendorAndProductId(vendorId: Int, productId: Int): UsbDevice? { + val usbDevices = getDeviceList() + for (usbDevice in usbDevices) { + if (usbDevice.vendorId == vendorId && usbDevice.productId == productId) + return usbDevice + } + return null + } + fun selectDevice(vendorId: Int, productId: Int): Boolean { if (mUsbDevice == null || mUsbDevice!!.vendorId != vendorId || mUsbDevice!!.productId != productId) { closeConnectionIfExists() - val usbDevices = getDeviceList() - for (usbDevice in usbDevices) { - if (usbDevice.vendorId == vendorId && usbDevice.productId == productId) { - Log.v( - LOG_TAG, - "Request for device: vendor_id: " + usbDevice.vendorId + ", product_id: " + usbDevice.productId - ) - closeConnectionIfExists() - mUSBManager!!.requestPermission(usbDevice, mPermissionIntent) - return true - } + val usbDevice = getDeviceByVendorAndProductId(vendorId, productId) ?: return false + + Log.v(TAG, "Request for device: vendor_id: " + usbDevice.vendorId + ", product_id: " + usbDevice.productId) + closeConnectionIfExists() + + val flag = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE + else + PendingIntent.FLAG_UPDATE_CURRENT + + val intent = Intent(ACTION_USB_PERMISSION).apply { + putExtra("vendorId", vendorId) + putExtra("productId", productId) } - return false + + val mPermissionIntent = PendingIntent.getBroadcast(mContext, 0, intent, flag) + + mUSBManager!!.requestPermission(usbDevice, mPermissionIntent) + return true } return true } private fun openConnection(): Boolean { if (mUsbDevice == null) { - Log.e(LOG_TAG, "USB Device is not initialized") + Log.e(TAG, "USB Device is not initialized") return false } if (mUSBManager == null) { - Log.e(LOG_TAG, "USB Manager is not initialized") + Log.e(TAG, "USB Manager is not initialized") return false } if (mUsbDeviceConnection != null) { - Log.i(LOG_TAG, "USB Connection already connected") + Log.i(TAG, "USB Connection already connected") return true } val usbInterface = mUsbDevice!!.getInterface(0) @@ -151,7 +179,7 @@ class USBPrinterAdapter { if (ep.direction == UsbConstants.USB_DIR_OUT) { val usbDeviceConnection = mUSBManager!!.openDevice(mUsbDevice) if (usbDeviceConnection == null) { - Log.e(LOG_TAG, "failed to open USB Connection") + Log.e(TAG, "failed to open USB Connection") return false } Toast.makeText(mContext, "Device connected", Toast.LENGTH_SHORT).show() @@ -162,7 +190,7 @@ class USBPrinterAdapter { true } else { usbDeviceConnection.close() - Log.e(LOG_TAG, "failed to claim usb connection") + Log.e(TAG, "failed to claim usb connection") false } } @@ -172,51 +200,51 @@ class USBPrinterAdapter { } fun printText(text: String): Boolean { - Log.v(LOG_TAG, "start to print text") + Log.v(TAG, "start to print text") val isConnected = openConnection() return if (isConnected) { - Log.v(LOG_TAG, "Connected to device") + Log.v(TAG, "Connected to device") Thread { val bytes = text.toByteArray(Charset.forName("UTF-8")) val b = mUsbDeviceConnection!!.bulkTransfer(mEndPoint, bytes, bytes.size, 100000) - Log.i(LOG_TAG, "Return Status: b-->$b") + Log.i(TAG, "Return Status: b-->$b") }.start() true } else { - Log.v(LOG_TAG, "failed to connected to device") + Log.v(TAG, "failed to connected to device") false } } fun printRawText(data: String): Boolean { - Log.v(LOG_TAG, "start to print raw data $data") + Log.v(TAG, "start to print raw data $data") val isConnected = openConnection() return if (isConnected) { - Log.v(LOG_TAG, "Connected to device") + Log.v(TAG, "Connected to device") Thread { val bytes = Base64.decode(data, Base64.DEFAULT) val b = mUsbDeviceConnection!!.bulkTransfer(mEndPoint, bytes, bytes.size, 100000) - Log.i(LOG_TAG, "Return Status: $b") + Log.i(TAG, "Return Status: $b") }.start() true } else { - Log.v(LOG_TAG, "failed to connected to device") + Log.v(TAG, "failed to connected to device") false } } fun write(bytes: ByteArray): Boolean { - Log.v(LOG_TAG, "start to print raw data $bytes") + Log.v(TAG, "start to print raw data $bytes") val isConnected = openConnection() return if (isConnected) { - Log.v(LOG_TAG, "Connected to device") + Log.v(TAG, "Connected to device") Thread { val b = mUsbDeviceConnection!!.bulkTransfer(mEndPoint, bytes, bytes.size, 100000) - Log.i(LOG_TAG, "Return Status: $b") + Log.i(TAG, "Return Status: $b") }.start() true } else { - Log.v(LOG_TAG, "failed to connected to device") + Log.v(TAG, "failed to connected to device") false } } diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart index 6743173..7a46108 100644 --- a/example/test/widget_test.dart +++ b/example/test/widget_test.dart @@ -8,7 +8,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:flutter_usb_printer_example/main.dart'; +import '../lib/main.dart'; void main() { testWidgets('Verify Platform version', (WidgetTester tester) async {