Closed Aromboy closed 5 years ago
Please follow the example . Where are UsbDevice and UsbDeviceConnection instantiated?
Please follow the example . Where are UsbDevice and UsbDeviceConnection instantiated?
I´m using the example you passed in my UsbService java class , i just want to check if the port is connected or supported.
I added this into my UsbService java class:
public void conexion(){
UsbDevice mc100 = null;
UsbDeviceConnection usbconnection = null;
UsbSerialDevice serial = UsbSerialDevice.createUsbSerialDevice(mc100,usbconnection);
boolean support = serial.isSupported(mc100);
if (support == true){
Toast.makeText(this,"sopoortado",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this,"no sopoortado",Toast.LENGTH_SHORT).show();
}
}
And in the fragment I wrote:
public class EstadoFragment extends Fragment {
private Button boton;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_estado,container,false);
boton= view.findViewById(R.id.connect);
boton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
USBservice srv = new USBservice();
srv.conexion();
}
});
return view;
}
}
Now it crashes when i click the button.
Why do you pass null values to createUsbSerialDevice?
UsbDevice mc100 = null;
UsbDeviceConnection usbconnection = null;
UsbSerialDevice serial = UsbSerialDevice.createUsbSerialDevice(mc100,usbconnection);
Why do you pass null values to createUsbSerialDevice?
UsbDevice mc100 = null; UsbDeviceConnection usbconnection = null; UsbSerialDevice serial = UsbSerialDevice.createUsbSerialDevice(mc100,usbconnection);
Because it sends me an error in createUsbSerialDevice line, "Variable might not have been initialized"
It is not going to work with null values. You are probably getting a NullPointer exception. Sorry for repeating myself again but please look in the example I mentioned before. You will see where both UsbDevice and UsbDeviceConnection are obtained.
I saw it, even if i copy-paste it, then how do I check the connected device in other fragment. Again sorry for my ignorance
That's more generic Android than UsbSerial related. Check out for posts like Activities-Fragment-Services communication. https://hackernoon.com/8-ways-to-communicate-between-fragment-and-activity-in-android-apps-235b60005d04
Maybe I´m not explaining well. I know that, but i don´t know how to call for a check of devices connected in another place that is not UsbService.java ... I will look some examples maybe i found something usefull
I wouldn't call for check devices elsewhere. try to call functions from UsbService from the Activity making them public because UsbService is bind to the Activity. look at findSerialPortDevice() for example
I called findSerialPortDevice() from UsbService before all of this, and it also crashed . I don´t know what its bad
I have been looking some examples. I managed to make the app to not crash, but still not working, The actual code is this:
public class EstadoFragment extends Fragment {
private EditText editText;
private Button boton;
private USBservice usbService;
private Handler mHandler;
private TextView display;
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case USBservice.ACTION_USB_PERMISSION_GRANTED: // USB PERMISSION GRANTED
Toast.makeText(context, "USB Ready", Toast.LENGTH_SHORT).show();
break;
case USBservice.ACTION_USB_PERMISSION_NOT_GRANTED: // USB PERMISSION NOT GRANTED
Toast.makeText(context, "USB Permission not granted", Toast.LENGTH_SHORT).show();
break;
case USBservice.ACTION_NO_USB: // NO USB CONNECTED
Toast.makeText(context, "No USB connected", Toast.LENGTH_SHORT).show();
break;
case USBservice.ACTION_USB_DISCONNECTED: // USB DISCONNECTED
Toast.makeText(context, "USB disconnected", Toast.LENGTH_SHORT).show();
break;
case USBservice.ACTION_USB_NOT_SUPPORTED: // USB NOT SUPPORTED
Toast.makeText(context, "USB device not supported", Toast.LENGTH_SHORT).show();
break;
}
}
};
private final ServiceConnection usbConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
usbService = ((USBservice.UsbBinder) arg1).getService();
usbService.setHandler(mHandler);
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
usbService = null;
}
};
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_estado,container,false);
editText=view.findViewById(R.id.edittext);
boton= view.findViewById(R.id.connect);
display = view.findViewById(R.id.state);
mHandler = new MyHandler(this );
boton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!editText.getText().toString().equals("")) {
String data = editText.getText().toString();
if (usbService != null) { // if UsbService was correctly binded, Send data
display.append(data);
usbService.write(data.getBytes());
}
}
}
});
return view;
}
@Override
public void onResume() {
super.onResume();
setFilters(); // Start listening notifications from UsbService
startService(USBservice.class, usbConnection, null); // Start UsbService(if it was not started before) and Bind it
}
@Override
public void onPause() {
super.onPause();
getActivity().unregisterReceiver(mUsbReceiver);
getActivity().unbindService(usbConnection);
}
private void startService(Class<?> service, ServiceConnection serviceConnection, Bundle extras) {
if (!USBservice.SERVICE_CONNECTED) {
Intent startService = new Intent(getActivity(), service);
if (extras != null && !extras.isEmpty()) {
Set<String> keys = extras.keySet();
for (String key : keys) {
String extra = extras.getString(key);
startService.putExtra(key, extra);
}
}
// startService(startService);
}
Intent bindingIntent = new Intent(getContext(), service);
getActivity().bindService(bindingIntent, serviceConnection, Context.BIND_AUTO_CREATE);
}
private void setFilters() {
IntentFilter filter = new IntentFilter();
filter.addAction(USBservice.ACTION_USB_PERMISSION_GRANTED);
filter.addAction(USBservice.ACTION_NO_USB);
filter.addAction(USBservice.ACTION_USB_DISCONNECTED);
filter.addAction(USBservice.ACTION_USB_NOT_SUPPORTED);
filter.addAction(USBservice.ACTION_USB_PERMISSION_NOT_GRANTED);
getActivity().registerReceiver(mUsbReceiver, filter);
}
/*
* This handler will be passed to UsbService. Data received from serial port is displayed through this handler
*/
private static class MyHandler extends Handler {
private final WeakReference<EstadoFragment> mActivity;
public MyHandler(EstadoFragment activity) {
mActivity = new WeakReference<>(activity);
}
@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;
}
}
}
}
and my UsbService is :
public class USBservice extends Service {
public static final String TAG = "UsbService";
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_DETACHED = "android.hardware.usb.action.USB_DEVICE_DETACHED";
public static final String ACTION_USB_NOT_SUPPORTED = "com.felhr.usbservice.USB_NOT_SUPPORTED";
public static final String ACTION_NO_USB = "com.felhr.usbservice.NO_USB";
public static final String ACTION_USB_PERMISSION_GRANTED = "com.felhr.usbservice.USB_PERMISSION_GRANTED";
public static final String ACTION_USB_PERMISSION_NOT_GRANTED = "com.felhr.usbservice.USB_PERMISSION_NOT_GRANTED";
public static final String ACTION_USB_DISCONNECTED = "com.felhr.usbservice.USB_DISCONNECTED";
public static final String ACTION_CDC_DRIVER_NOT_WORKING = "com.felhr.connectivityservices.ACTION_CDC_DRIVER_NOT_WORKING";
public static final String ACTION_USB_DEVICE_NOT_WORKING = "com.felhr.connectivityservices.ACTION_USB_DEVICE_NOT_WORKING";
public static final int MESSAGE_FROM_SERIAL_PORT = 0;
public static final int CTS_CHANGE = 1;
public static final int DSR_CHANGE = 2;
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
private static final int BAUD_RATE = 9600; // BaudRate. Change this value if you need
public static boolean SERVICE_CONNECTED = false;
private IBinder binder = new UsbBinder();
private Context context;
private Handler mHandler;
private UsbManager usbManager;
private UsbDevice device;
private UsbDeviceConnection connection;
private UsbSerialDevice serialPort;
private boolean serialPortConnected;
/*
* Data received from serial port will be received here. Just populate onReceivedData with your code
* In this particular example. byte stream is converted to String and send to UI thread to
* be treated there.
*/
private UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() {
@Override
public void onReceivedData(byte[] arg0) {
try {
String data = new String(arg0, "UTF-8");
if (mHandler != null)
mHandler.obtainMessage(MESSAGE_FROM_SERIAL_PORT, data).sendToTarget();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
};
/*
* State changes in the CTS line will be received here
*/
private UsbSerialInterface.UsbCTSCallback ctsCallback = new UsbSerialInterface.UsbCTSCallback() {
@Override
public void onCTSChanged(boolean state) {
if(mHandler != null)
mHandler.obtainMessage(CTS_CHANGE).sendToTarget();
}
};
/*
* State changes in the DSR line will be received here
*/
private UsbSerialInterface.UsbDSRCallback dsrCallback = new UsbSerialInterface.UsbDSRCallback() {
@Override
public void onDSRChanged(boolean state) {
if(mHandler != null)
mHandler.obtainMessage(DSR_CHANGE).sendToTarget();
}
};
/*
* Different notifications from OS will be received here (USB attached, detached, permission responses...)
* About BroadcastReceiver: http://developer.android.com/reference/android/content/BroadcastReceiver.html
*/
public final BroadcastReceiver usbReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context arg0, Intent arg1) {
if (arg1.getAction().equals(ACTION_USB_PERMISSION)) {
boolean granted = arg1.getExtras().getBoolean(UsbManager.EXTRA_PERMISSION_GRANTED);
if (granted) // User accepted our USB connection. Try to open the device as a serial port
{
Intent intent = new Intent(ACTION_USB_PERMISSION_GRANTED);
arg0.sendBroadcast(intent);
connection = usbManager.openDevice(device);
new ConnectionThread().start();
} else // User not accepted our USB connection. Send an Intent to the Main Activity
{
Intent intent = new Intent(ACTION_USB_PERMISSION_NOT_GRANTED);
arg0.sendBroadcast(intent);
}
} else if (arg1.getAction().equals(ACTION_USB_ATTACHED)) {
if (!serialPortConnected)
findSerialPortDevice(); // A USB device has been attached. Try to open it as a Serial port
} else if (arg1.getAction().equals(ACTION_USB_DETACHED)) {
// Usb device was disconnected. send an intent to the Main Activity
Intent intent = new Intent(ACTION_USB_DISCONNECTED);
arg0.sendBroadcast(intent);
serialPortConnected = false;
serialPort.close();
}
}
};
/*
* onCreate will be executed when service is started. It configures an IntentFilter to listen for
* incoming Intents (USB ATTACHED, USB DETACHED...) and it tries to open a serial port.
*/
@Override
public void onCreate() {
this.context = this;
serialPortConnected = false;
USBservice.SERVICE_CONNECTED = true;
setFilter();
usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
findSerialPortDevice();
}
/* MUST READ about services
* http://developer.android.com/guide/components/services.html
* http://developer.android.com/guide/components/bound-services.html
*/
@Override
public IBinder onBind(Intent intent) {
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;
}
/*
* This function will be called from MainActivity to write data through Serial Port
*/
public void write(byte[] data) {
if (serialPort != null)
serialPort.write(data);
}
public void setHandler(Handler mHandler) {
this.mHandler = mHandler;
}
private void findSerialPortDevice() {
// This snippet will try to open the first encountered usb device connected, excluding usb root hubs
HashMap<String, UsbDevice> usbDevices = usbManager.getDeviceList();
if (!usbDevices.isEmpty()) {
boolean keep = true;
for (Map.Entry<String, UsbDevice> entry : usbDevices.entrySet()) {
device = entry.getValue();
int deviceVID = device.getVendorId();
int devicePID = device.getProductId();
if (deviceVID != 0x1d6b && (devicePID != 0x0001 || devicePID != 0x0002 || devicePID != 0x0003)) {
// There is a device connected to our Android device. Try to open it as a Serial Port.
requestUserPermission();
keep = false;
} else {
connection = null;
device = null;
}
if (!keep)
break;
}
if (!keep) {
// There is no USB devices connected (but usb host were listed). Send an intent to MainActivity.
Intent intent = new Intent(ACTION_NO_USB);
sendBroadcast(intent);
}
} else {
// There is no USB devices connected. Send an intent to MainActivity
Intent intent = new Intent(ACTION_NO_USB);
sendBroadcast(intent);
}
}
private void setFilter() {
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_USB_PERMISSION);
filter.addAction(ACTION_USB_DETACHED);
filter.addAction(ACTION_USB_ATTACHED);
registerReceiver(usbReceiver, filter);
}
/*
* Request user permission. The response will be received in the BroadcastReceiver
*/
private void requestUserPermission() {
PendingIntent mPendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
usbManager.requestPermission(device, mPendingIntent);
}
public class UsbBinder extends Binder {
public USBservice getService() {
return USBservice.this;
}
}
/*
* A simple thread to open a serial port.
* Although it should be a fast operation. moving usb operations away from UI thread is a good thing.
*/
private class ConnectionThread extends Thread {
@Override
public void run() {
serialPort = UsbSerialDevice.createUsbSerialDevice(device, connection);
if (serialPort != null) {
if (serialPort.open()) {
serialPortConnected = true;
serialPort.setBaudRate(BAUD_RATE);
serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8);
serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1);
serialPort.setParity(UsbSerialInterface.PARITY_NONE);
/**
* Current flow control Options:
* UsbSerialInterface.FLOW_CONTROL_OFF
* UsbSerialInterface.FLOW_CONTROL_RTS_CTS only for CP2102 and FT232
* UsbSerialInterface.FLOW_CONTROL_DSR_DTR only for CP2102 and FT232
*/
serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
serialPort.read(mCallback);
serialPort.getCTS(ctsCallback);
serialPort.getDSR(dsrCallback);
//
// Some Arduinos would need some sleep because firmware wait some time to know whether a new sketch is going
// to be uploaded or not
//Thread.sleep(2000); // sleep some. YMMV with different chips.
// Everything went as expected. Send an intent to MainActivity
Intent intent = new Intent(ACTION_USB_READY);
context.sendBroadcast(intent);
} else {
// Serial port could not be opened, maybe an I/O error or if CDC driver was chosen, it does not really fit
// Send an Intent to Main Activity
if (serialPort instanceof CDCSerialDevice) {
Intent intent = new Intent(ACTION_CDC_DRIVER_NOT_WORKING);
context.sendBroadcast(intent);
} else {
Intent intent = new Intent(ACTION_USB_DEVICE_NOT_WORKING);
context.sendBroadcast(intent);
}
}
} else {
// No driver for given device, even generic CDC driver could not be loaded
Intent intent = new Intent(ACTION_USB_NOT_SUPPORTED);
context.sendBroadcast(intent);
}
}
}
}
It is pretty much generic I think , but in one of your examples it works fine and detect the conected devices, but in my app it does nothing when connecting something. Thanks for your patience and time.
Hi, first of all , I´m a little newbie with this. My problem is that when I create a new object of the UsbSerialDevice class in a Fragment and run the app, then when I open that fragment with a navigation drawer it crash and says it stopped. I did´n write pretty much:
I also tried putting everything in the onCreateView but it does the same. Probably this is an easy thing to resolve but i can´t figure it out how.I have to be missing something. I´m running the app with ADB using WiFi. The app crashes with and with AND without a device connected. PD: This code is just for testing the connection. Thanks for the help.