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

Wyświetl plik

@ -13,8 +13,6 @@ import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
@ -55,6 +53,7 @@ public class MainActivity extends AppCompatActivity {
private EditText editText1, editText2;
private Button button1, button2;
private MyHandler mHandler;
private final ServiceConnection usbConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
@ -82,18 +81,15 @@ public class MainActivity extends AppCompatActivity {
button1 = findViewById(R.id.buttonSend1);
button2 = findViewById(R.id.buttonSend2);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//TODO!!
}
button1.setOnClickListener((View v) -> {
byte[] data = editText1.getText().toString().getBytes();
usbService.write(data, 0);
});
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//TODO!!
}
button2.setOnClickListener((View v) -> {
byte[] data = editText2.getText().toString().getBytes();
usbService.write(data, 1);
});
mHandler = new MyHandler(this);
@ -152,19 +148,14 @@ public class MainActivity extends AppCompatActivity {
@Override
public void handleMessage(Message msg) {
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:
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;
}
}

Wyświetl plik

@ -1,5 +1,6 @@
package com.felhr.examplemultipleports;
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
@ -10,21 +11,24 @@ import android.hardware.usb.UsbManager;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.Nullable;
import android.widget.Toast;
import com.annimon.stream.Stream;
import com.felhr.usbserial.SerialInputStream;
import com.felhr.usbserial.SerialPortBuilder;
import com.felhr.usbserial.SerialPortCallback;
import com.felhr.usbserial.UsbSerialDevice;
import com.felhr.usbserial.UsbSerialInterface;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* 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_ATTACHED = "android.hardware.usb.action.USB_DEVICE_ATTACHED";
@ -50,6 +54,11 @@ public class UsbService extends Service {
private UsbManager usbManager;
private SerialPortBuilder builder;
private Handler writeHandler;
private WriteThread writeThread;
private ReadThreadCOM readThreadCOM1, readThreadCOM2;
private IBinder binder = new UsbBinder();
private Handler mHandler;
@ -71,15 +80,12 @@ public class UsbService extends Service {
Toast.makeText(context, "Couldnt open the device", Toast.LENGTH_SHORT).show();
} else if (arg1.getAction().equals(ACTION_USB_DETACHED)) {
UsbDevice usbDevice = arg1.getParcelableExtra(UsbManager.EXTRA_DEVICE);
boolean ret = builder.disconnectDevice(usbDevice);
List<UsbSerialDevice> filteredDevice = Stream.of(serialPorts)
.filter(p -> usbDevice.getDeviceId() == p.getDeviceId())
.toList();
if(filteredDevice.size() == 1){
UsbSerialDevice disconnectedDevice = filteredDevice.get(0);
disconnectedDevice.syncClose();
}
if(ret)
Toast.makeText(context, "Usb device disconnected", Toast.LENGTH_SHORT).show();
else
Toast.makeText(context, "Usb device wasnt a serial port", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(ACTION_USB_DISCONNECTED);
arg0.sendBroadcast(intent);
@ -88,12 +94,25 @@ public class UsbService extends Service {
}
};
private final SerialPortCallback serialPortCallback = new SerialPortCallback() {
@Override
public void onSerialPortsDetected(List<UsbSerialDevice> serialPorts, boolean opened) {
//TODO!!
@Override
public void onSerialPortsDetected(List<UsbSerialDevice> serialPorts, boolean opened) {
if(opened) {
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
public void onCreate() {
@ -101,7 +120,7 @@ public class UsbService extends Service {
UsbService.SERVICE_CONNECTED = true;
setFilter();
usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
builder = SerialPortBuilder.createSerialPortBuilder(serialPortCallback);
builder = SerialPortBuilder.createSerialPortBuilder(this);
boolean ret = builder.openSerialPorts(context, BAUD_RATE,
UsbSerialInterface.DATA_BITS_8,
@ -119,6 +138,22 @@ public class UsbService extends Service {
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) {
this.mHandler = mHandler;
}
@ -137,4 +172,60 @@ public class UsbService extends Service {
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.UsbManager;
import com.annimon.stream.Optional;
import com.annimon.stream.Stream;
import com.felhr.utils.Utils;
import java.util.ArrayList;
import java.util.HashMap;
@ -93,15 +95,24 @@ public class SerialPortBuilder {
return getSerialPorts(context);
}
public void disconnectDevice(UsbDevice usbDevice){
List<UsbSerialDevice> filteredDevice = Stream.of(serialDevices)
.filter(p -> usbDevice.getDeviceId() == p.getDeviceId())
.toList();
public boolean disconnectDevice(UsbSerialDevice usbSerialDevice){
usbSerialDevice.syncClose();
serialDevices = Utils.removeIf(serialDevices, p -> usbSerialDevice.getDeviceId() == p.getDeviceId());
return true;
}
if(filteredDevice.size() == 1){
UsbSerialDevice disconnectedDevice = filteredDevice.get(0);
public boolean disconnectDevice(UsbDevice usbDevice){
Optional<UsbSerialDevice> optionalDevice = Stream.of(serialDevices)
.filter(p -> usbDevice.getDeviceId() == p.getDeviceId())
.findSingle();
if(optionalDevice.isPresent()){
UsbSerialDevice disconnectedDevice = optionalDevice.get();
disconnectedDevice.syncClose();
serialDevices = Utils.removeIf(serialDevices, p -> usbDevice.getDeviceId() == p.getDeviceId());
return true;
}
return false;
}
private boolean requestPermission(Context context){
@ -188,14 +199,16 @@ public class SerialPortBuilder {
public void run() {
int n =1;
for (UsbSerialDevice usbSerialDevice : usbSerialDevices) {
if (usbSerialDevice.syncOpen()) {
usbSerialDevice.setBaudRate(baudRate);
usbSerialDevice.setDataBits(dataBits);
usbSerialDevice.setStopBits(stopBits);
usbSerialDevice.setParity(parity);
usbSerialDevice.setFlowControl(flowControl);
usbSerialDevice.setPortName(UsbSerialDevice.COM_PORT + String.valueOf(n));
n++;
if (!usbSerialDevice.isOpen) {
if (usbSerialDevice.syncOpen()) {
usbSerialDevice.setBaudRate(baudRate);
usbSerialDevice.setDataBits(dataBits);
usbSerialDevice.setStopBits(stopBits);
usbSerialDevice.setParity(parity);
usbSerialDevice.setFlowControl(flowControl);
usbSerialDevice.setPortName(UsbSerialDevice.COM_PORT + String.valueOf(n));
n++;
}
}
}
serialPortCallback.onSerialPortsDetected(serialDevices, true);

Wyświetl plik

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