first version example multiple port

pull/177/head
Felipe Herranz 2018-11-11 20:44:09 +01:00
rodzic a2ae5ab2e5
commit 10f493054b
6 zmienionych plików z 176 dodań i 57 usunięć

Wyświetl plik

@ -2,6 +2,9 @@
<manifest package="com.felhr.examplemultipleports" <manifest package="com.felhr.examplemultipleports"
xmlns:android="http://schemas.android.com/apk/res/android"> xmlns:android="http://schemas.android.com/apk/res/android">
<uses-feature android:name="android.hardware.usb.host"
android:required="true"/>
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
@ -16,6 +19,11 @@
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter> </intent-filter>
</activity> </activity>
<service
android:name="com.felhr.examplemultipleports.UsbService"
android:enabled="true">
</service>
</application> </application>
</manifest> </manifest>

Wyświetl plik

@ -13,8 +13,6 @@ import android.support.v7.app.AppCompatActivity;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
@ -55,6 +53,7 @@ public class MainActivity extends AppCompatActivity {
private EditText editText1, editText2; private EditText editText1, editText2;
private Button button1, button2; private Button button1, button2;
private MyHandler mHandler; private MyHandler mHandler;
private final ServiceConnection usbConnection = new ServiceConnection() { private final ServiceConnection usbConnection = new ServiceConnection() {
@Override @Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) { public void onServiceConnected(ComponentName arg0, IBinder arg1) {
@ -82,18 +81,15 @@ public class MainActivity extends AppCompatActivity {
button1 = findViewById(R.id.buttonSend1); button1 = findViewById(R.id.buttonSend1);
button2 = findViewById(R.id.buttonSend2); button2 = findViewById(R.id.buttonSend2);
button1.setOnClickListener(new View.OnClickListener() { button1.setOnClickListener((View v) -> {
@Override byte[] data = editText1.getText().toString().getBytes();
public void onClick(View view) { usbService.write(data, 0);
//TODO!!
}
}); });
button2.setOnClickListener(new View.OnClickListener() { button2.setOnClickListener((View v) -> {
@Override byte[] data = editText2.getText().toString().getBytes();
public void onClick(View view) { usbService.write(data, 1);
//TODO!!
}
}); });
mHandler = new MyHandler(this); mHandler = new MyHandler(this);
@ -152,19 +148,14 @@ public class MainActivity extends AppCompatActivity {
@Override @Override
public void handleMessage(Message msg) { public void handleMessage(Message msg) {
switch (msg.what) { switch (msg.what) {
case UsbService.MESSAGE_FROM_SERIAL_PORT:
String data = (String) msg.obj;
//mActivity.get().display.append(data);
break;
case UsbService.CTS_CHANGE:
Toast.makeText(mActivity.get(), "CTS_CHANGE",Toast.LENGTH_LONG).show();
break;
case UsbService.DSR_CHANGE:
Toast.makeText(mActivity.get(), "DSR_CHANGE",Toast.LENGTH_LONG).show();
break;
case UsbService.SYNC_READ: case UsbService.SYNC_READ:
String buffer = (String) msg.obj; String buffer = (String) msg.obj;
//mActivity.get().display.append(buffer); if(msg.arg1 == 0){
mActivity.get().display1.append(buffer);
}else if(msg.arg1 == 1){
mActivity.get().display2.append(buffer);
}
break; break;
} }
} }

Wyświetl plik

@ -1,5 +1,6 @@
package com.felhr.examplemultipleports; package com.felhr.examplemultipleports;
import android.annotation.SuppressLint;
import android.app.Service; import android.app.Service;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
@ -10,21 +11,24 @@ import android.hardware.usb.UsbManager;
import android.os.Binder; import android.os.Binder;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.widget.Toast; import android.widget.Toast;
import com.annimon.stream.Stream; import com.felhr.usbserial.SerialInputStream;
import com.felhr.usbserial.SerialPortBuilder; import com.felhr.usbserial.SerialPortBuilder;
import com.felhr.usbserial.SerialPortCallback; import com.felhr.usbserial.SerialPortCallback;
import com.felhr.usbserial.UsbSerialDevice; import com.felhr.usbserial.UsbSerialDevice;
import com.felhr.usbserial.UsbSerialInterface; import com.felhr.usbserial.UsbSerialInterface;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
/** /**
* Created by Felipe Herranz(felhr85@gmail.com) on 09/11/2018. * Created by Felipe Herranz(felhr85@gmail.com) on 09/11/2018.
*/ */
public class UsbService extends Service { public class UsbService extends Service implements SerialPortCallback {
public static final String ACTION_USB_READY = "com.felhr.connectivityservices.USB_READY"; public static final String ACTION_USB_READY = "com.felhr.connectivityservices.USB_READY";
public static final String ACTION_USB_ATTACHED = "android.hardware.usb.action.USB_DEVICE_ATTACHED"; public static final String ACTION_USB_ATTACHED = "android.hardware.usb.action.USB_DEVICE_ATTACHED";
@ -50,6 +54,11 @@ public class UsbService extends Service {
private UsbManager usbManager; private UsbManager usbManager;
private SerialPortBuilder builder; private SerialPortBuilder builder;
private Handler writeHandler;
private WriteThread writeThread;
private ReadThreadCOM readThreadCOM1, readThreadCOM2;
private IBinder binder = new UsbBinder(); private IBinder binder = new UsbBinder();
private Handler mHandler; private Handler mHandler;
@ -71,15 +80,12 @@ public class UsbService extends Service {
Toast.makeText(context, "Couldnt open the device", Toast.LENGTH_SHORT).show(); Toast.makeText(context, "Couldnt open the device", Toast.LENGTH_SHORT).show();
} else if (arg1.getAction().equals(ACTION_USB_DETACHED)) { } else if (arg1.getAction().equals(ACTION_USB_DETACHED)) {
UsbDevice usbDevice = arg1.getParcelableExtra(UsbManager.EXTRA_DEVICE); UsbDevice usbDevice = arg1.getParcelableExtra(UsbManager.EXTRA_DEVICE);
boolean ret = builder.disconnectDevice(usbDevice);
List<UsbSerialDevice> filteredDevice = Stream.of(serialPorts) if(ret)
.filter(p -> usbDevice.getDeviceId() == p.getDeviceId()) Toast.makeText(context, "Usb device disconnected", Toast.LENGTH_SHORT).show();
.toList(); else
Toast.makeText(context, "Usb device wasnt a serial port", Toast.LENGTH_SHORT).show();
if(filteredDevice.size() == 1){
UsbSerialDevice disconnectedDevice = filteredDevice.get(0);
disconnectedDevice.syncClose();
}
Intent intent = new Intent(ACTION_USB_DISCONNECTED); Intent intent = new Intent(ACTION_USB_DISCONNECTED);
arg0.sendBroadcast(intent); arg0.sendBroadcast(intent);
@ -88,12 +94,25 @@ public class UsbService extends Service {
} }
}; };
private final SerialPortCallback serialPortCallback = new SerialPortCallback() { @Override
@Override public void onSerialPortsDetected(List<UsbSerialDevice> serialPorts, boolean opened) {
public void onSerialPortsDetected(List<UsbSerialDevice> serialPorts, boolean opened) { if(opened) {
//TODO!! this.serialPorts = serialPorts;
if (writeThread == null) {
writeThread = new WriteThread();
writeThread.start();
}
if (readThreadCOM1 == null) {
readThreadCOM1 = new ReadThreadCOM(0,
serialPorts.get(0).getInputStream());
}else if(readThreadCOM2 == null){
readThreadCOM2 = new ReadThreadCOM(1,
serialPorts.get(1).getInputStream());
}
} }
}; }
@Override @Override
public void onCreate() { public void onCreate() {
@ -101,7 +120,7 @@ public class UsbService extends Service {
UsbService.SERVICE_CONNECTED = true; UsbService.SERVICE_CONNECTED = true;
setFilter(); setFilter();
usbManager = (UsbManager) getSystemService(Context.USB_SERVICE); usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
builder = SerialPortBuilder.createSerialPortBuilder(serialPortCallback); builder = SerialPortBuilder.createSerialPortBuilder(this);
boolean ret = builder.openSerialPorts(context, BAUD_RATE, boolean ret = builder.openSerialPorts(context, BAUD_RATE,
UsbSerialInterface.DATA_BITS_8, UsbSerialInterface.DATA_BITS_8,
@ -119,6 +138,22 @@ public class UsbService extends Service {
return binder; return binder;
} }
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_NOT_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
UsbService.SERVICE_CONNECTED = false;
}
public void write(byte[] data, int port){
if(writeThread != null)
writeHandler.obtainMessage(0, port, 0, data).sendToTarget();
}
public void setHandler(Handler mHandler) { public void setHandler(Handler mHandler) {
this.mHandler = mHandler; this.mHandler = mHandler;
} }
@ -137,4 +172,60 @@ public class UsbService extends Service {
return UsbService.this; return UsbService.this;
} }
} }
private class ReadThreadCOM extends Thread {
private int port;
private AtomicBoolean keep = new AtomicBoolean(true);
private SerialInputStream inputStream;
public ReadThreadCOM(int port, SerialInputStream serialInputStream){
this.port = port;
this.inputStream = serialInputStream;
}
@Override
public void run() {
while(keep.get()){
if(inputStream == null)
return;
int value = inputStream.read();
if(value != -1) {
String str = toASCII(value);
mHandler.obtainMessage(SYNC_READ, port, 0, str).sendToTarget();
}
}
}
public void setKeep(boolean keep){
this.keep.set(keep);
}
}
private static String toASCII(int value) {
int length = 4;
StringBuilder builder = new StringBuilder(length);
for (int i = length - 1; i >= 0; i--) {
builder.append((char) ((value >> (8 * i)) & 0xFF));
}
return builder.toString();
}
private class WriteThread extends Thread{
@Override
@SuppressLint("HandlerLeak")
public void run() {
Looper.prepare();
writeHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
int port = msg.arg1;
byte[] data = (byte[]) msg.obj;
UsbSerialDevice serialDevice = serialPorts.get(port);
serialDevice.getOutputStream().write(data);
}
};
Looper.loop();
}
}
} }

Wyświetl plik

@ -10,7 +10,9 @@ import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager; import android.hardware.usb.UsbManager;
import com.annimon.stream.Optional;
import com.annimon.stream.Stream; import com.annimon.stream.Stream;
import com.felhr.utils.Utils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -93,15 +95,24 @@ public class SerialPortBuilder {
return getSerialPorts(context); return getSerialPorts(context);
} }
public void disconnectDevice(UsbDevice usbDevice){ public boolean disconnectDevice(UsbSerialDevice usbSerialDevice){
List<UsbSerialDevice> filteredDevice = Stream.of(serialDevices) usbSerialDevice.syncClose();
.filter(p -> usbDevice.getDeviceId() == p.getDeviceId()) serialDevices = Utils.removeIf(serialDevices, p -> usbSerialDevice.getDeviceId() == p.getDeviceId());
.toList(); return true;
}
if(filteredDevice.size() == 1){ public boolean disconnectDevice(UsbDevice usbDevice){
UsbSerialDevice disconnectedDevice = filteredDevice.get(0); Optional<UsbSerialDevice> optionalDevice = Stream.of(serialDevices)
.filter(p -> usbDevice.getDeviceId() == p.getDeviceId())
.findSingle();
if(optionalDevice.isPresent()){
UsbSerialDevice disconnectedDevice = optionalDevice.get();
disconnectedDevice.syncClose(); disconnectedDevice.syncClose();
serialDevices = Utils.removeIf(serialDevices, p -> usbDevice.getDeviceId() == p.getDeviceId());
return true;
} }
return false;
} }
private boolean requestPermission(Context context){ private boolean requestPermission(Context context){
@ -188,14 +199,16 @@ public class SerialPortBuilder {
public void run() { public void run() {
int n =1; int n =1;
for (UsbSerialDevice usbSerialDevice : usbSerialDevices) { for (UsbSerialDevice usbSerialDevice : usbSerialDevices) {
if (usbSerialDevice.syncOpen()) { if (!usbSerialDevice.isOpen) {
usbSerialDevice.setBaudRate(baudRate); if (usbSerialDevice.syncOpen()) {
usbSerialDevice.setDataBits(dataBits); usbSerialDevice.setBaudRate(baudRate);
usbSerialDevice.setStopBits(stopBits); usbSerialDevice.setDataBits(dataBits);
usbSerialDevice.setParity(parity); usbSerialDevice.setStopBits(stopBits);
usbSerialDevice.setFlowControl(flowControl); usbSerialDevice.setParity(parity);
usbSerialDevice.setPortName(UsbSerialDevice.COM_PORT + String.valueOf(n)); usbSerialDevice.setFlowControl(flowControl);
n++; usbSerialDevice.setPortName(UsbSerialDevice.COM_PORT + String.valueOf(n));
n++;
}
} }
} }
serialPortCallback.onSerialPortsDetected(serialDevices, true); serialPortCallback.onSerialPortsDetected(serialDevices, true);

Wyświetl plik

@ -1,10 +1,7 @@
package com.felhr.usbserial; package com.felhr.usbserial;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import com.annimon.stream.Stream;
import com.felhr.deviceids.CH34xIds; import com.felhr.deviceids.CH34xIds;
import com.felhr.deviceids.CP210xIds; import com.felhr.deviceids.CP210xIds;
import com.felhr.deviceids.FTDISioIds; import com.felhr.deviceids.FTDISioIds;
@ -15,7 +12,6 @@ import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint; import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface; import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbRequest; import android.hardware.usb.UsbRequest;
public abstract class UsbSerialDevice implements UsbSerialInterface public abstract class UsbSerialDevice implements UsbSerialInterface
@ -279,6 +275,9 @@ public abstract class UsbSerialDevice implements UsbSerialInterface
this.portName = portName; this.portName = portName;
} }
public String getPortName(){
return this.portName;
}
public boolean isOpen(){ public boolean isOpen(){
return isOpen; return isOpen;

Wyświetl plik

@ -0,0 +1,17 @@
package com.felhr.utils;
import com.annimon.stream.Collectors;
import com.annimon.stream.Stream;
import com.annimon.stream.function.Predicate;
import java.util.Collection;
import java.util.List;
public class Utils {
public static <T> List<T> removeIf(Collection<T> c, Predicate<? super T> predicate) {
return Stream.of(c.iterator())
.filterNot(predicate)
.collect(Collectors.<T>toList());
}
}