package hendrikschutter.com.externgnss; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbManager; import android.util.Log; import com.hoho.android.usbserial.driver.UsbSerialDriver; import com.hoho.android.usbserial.driver.UsbSerialPort; import com.hoho.android.usbserial.driver.UsbSerialProber; import com.hoho.android.usbserial.util.SerialInputOutputManager; import java.io.IOException; import java.util.concurrent.BlockingQueue; public class SerialUSB implements SerialInputOutputManager.Listener{ private MainActivity mainActivity = null; private enum UsbPermission { Unknown, Requested, Granted, Denied } private static final String INTENT_ACTION_GRANT_USB = BuildConfig.APPLICATION_ID + ".GRANT_USB"; private int deviceId, portNum, baudRate; private BroadcastReceiver broadcastReceiver = null; private SerialInputOutputManager usbIoManager; private UsbSerialPort usbSerialPort; private UsbPermission usbPermission = UsbPermission.Unknown; private BlockingQueue dataBytesQueue = null; private boolean connected = false; private int deviceVendorId; private int productID; public SerialUSB(MainActivity mainActivity, BlockingQueue dataBytesQueue){ this.mainActivity = mainActivity; this.dataBytesQueue = dataBytesQueue; } public boolean isConnected(){ return connected; } public int getDeviceId(){ return this.deviceId; } public int getBaudRate(){ return this.baudRate; } public int getUsbDeviceVendorId(){ return this.deviceVendorId; } public boolean findSerialDevice(){ // Find all available drivers from attached devices. UsbManager usbManager = (UsbManager) this.mainActivity.getSystemService(Context.USB_SERVICE); UsbSerialProber usbDefaultProber = UsbSerialProber.getDefaultProber(); boolean deviceFound = false; //check of at least one device is present if (usbManager.getDeviceList().values().size() > 0){ //get fist device UsbDevice device = (UsbDevice) usbManager.getDeviceList().values().toArray()[0]; UsbSerialDriver driver = usbDefaultProber.probeDevice(device); if(driver == null) { Log.e("SerialUSB", "driver is null"); } if(driver != null) { Log.i("SerialUSB", "ExternGNSS: device/driver found!"); this.deviceId = device.getDeviceId(); this.deviceVendorId = device.getVendorId(); deviceFound = true; } } else { Log.e("SerialUSB", "no serial device connected"); deviceFound = false; } return deviceFound; } public void connect(int baudRate, int portNum) { this.baudRate = baudRate; this.portNum = portNum; Log.i("connect", "starting to connect ..."); UsbDevice device = null; UsbManager usbManager = (UsbManager) this.mainActivity.getSystemService(Context.USB_SERVICE); for(UsbDevice v : usbManager.getDeviceList().values()) if(v.getDeviceId() == deviceId) device = v; if(device == null) { Log.i("connect", "connection failed: device not found"); return; } UsbSerialDriver driver = UsbSerialProber.getDefaultProber().probeDevice(device); if(driver == null) { Log.i("connect", "connection failed: no driver for device"); return; } if(driver.getPorts().size() < portNum) { Log.i("connect", "connection failed: not enough ports at device"); return; } usbSerialPort = driver.getPorts().get(portNum); UsbDeviceConnection usbConnection = null; try { usbConnection = usbManager.openDevice(driver.getDevice()); } catch (Exception e){ usbPermission = UsbPermission.Requested; PendingIntent usbPermissionIntent = PendingIntent.getBroadcast(this.mainActivity, 0, new Intent(INTENT_ACTION_GRANT_USB), 0); usbManager.requestPermission(driver.getDevice(), usbPermissionIntent); } usbConnection = usbManager.openDevice(driver.getDevice()); if(usbConnection == null && usbPermission == UsbPermission.Unknown && !usbManager.hasPermission(driver.getDevice())) { usbPermission = UsbPermission.Requested; PendingIntent usbPermissionIntent = PendingIntent.getBroadcast(this.mainActivity, 0, new Intent(INTENT_ACTION_GRANT_USB), 0); usbManager.requestPermission(driver.getDevice(), usbPermissionIntent); return; } if(usbConnection == null) { if (!usbManager.hasPermission(driver.getDevice())) Log.i("connect", "connection failed: permission denied"); else Log.i("connect", "connection failed: open failed"); return; } try { usbSerialPort.open(usbConnection); usbSerialPort.setParameters(baudRate, 8, 1, UsbSerialPort.PARITY_NONE); usbIoManager = new SerialInputOutputManager(usbSerialPort, this); usbIoManager.start(); Log.i("connect", "connected"); connected = true; } catch (Exception e) { Log.i("connect", "connection failed: " + e.getMessage()); disconnect(); } } public void disconnect() { connected = false; if(usbIoManager != null) { usbIoManager.setListener(null); usbIoManager.stop(); } usbIoManager = null; try { usbSerialPort.close(); } catch (IOException ignored) {} usbSerialPort = null; } @Override public void onNewData(byte[] data) { //Log.i("connect", "received data: " + data.length); //Log.i("connect", new String(data, StandardCharsets.US_ASCII) ); for (byte rawByte : data) { this.dataBytesQueue.add(rawByte); } } @Override public void onRunError(Exception e) { Log.e("SerialUSB", "runtime error: " + e.getMessage()); this.disconnect(); } }