kopia lustrzana https://github.com/felHR85/UsbSerial
first version example multiple port
rodzic
a2ae5ab2e5
commit
10f493054b
|
@ -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>
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
Ładowanie…
Reference in New Issue