mirror of
				https://github.com/mik3y/usb-serial-for-android
				synced 2025-10-31 10:27:27 +00:00 
			
		
		
		
	README with SerialInputOutputManager for read() and port for write()
test the usually not used read/write variants
This commit is contained in:
		
							parent
							
								
									800381e370
								
							
						
					
					
						commit
						b3631dff58
					
				
							
								
								
									
										87
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										87
									
								
								README.md
									
									
									
									
									
								
							| @ -33,66 +33,67 @@ dependencies { | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| **2.** Copy [device_filter.xml](https://github.com/mik3y/usb-serial-for-android/blob/master/usbSerialExamples/src/main/res/xml/device_filter.xml) to your project's `res/xml/` directory. | ||||
| 
 | ||||
| **3.** Configure your `AndroidManifest.xml` to notify your app when a device is attached (see [Android USB Host documentation](http://developer.android.com/guide/topics/connectivity/usb/host.html#discovering-d) for help). | ||||
| **2.** If the app should be notified when a device is attached, add  | ||||
| [device_filter.xml](https://github.com/mik3y/usb-serial-for-android/blob/master/usbSerialExamples/src/main/res/xml/device_filter.xml)  | ||||
| to your project's `res/xml/` directory and configure in your `AndroidManifest.xml`. | ||||
| 
 | ||||
| ```xml | ||||
| <activity | ||||
|     android:name="..." | ||||
|     ...> | ||||
|   <intent-filter> | ||||
|     <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> | ||||
|   </intent-filter> | ||||
|   <meta-data | ||||
|       android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" | ||||
|       android:resource="@xml/device_filter" /> | ||||
|     <intent-filter> | ||||
|         <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /> | ||||
|     </intent-filter> | ||||
|     <meta-data | ||||
|         android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" | ||||
|         android:resource="@xml/device_filter" /> | ||||
| </activity> | ||||
| ``` | ||||
| 
 | ||||
| **4.** Use it! Example code snippet: | ||||
| **3.** Use it! Example code snippet: | ||||
| 
 | ||||
| ```java | ||||
| // Find all available drivers from attached devices. | ||||
| UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE); | ||||
| List<UsbSerialDriver> availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager); | ||||
| if (availableDrivers.isEmpty()) { | ||||
|   return; | ||||
| } | ||||
|     // Find all available drivers from attached devices. | ||||
|     UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE); | ||||
|     List<UsbSerialDriver> availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager); | ||||
|     if (availableDrivers.isEmpty()) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
| // Open a connection to the first available driver. | ||||
| UsbSerialDriver driver = availableDrivers.get(0); | ||||
| UsbDeviceConnection connection = manager.openDevice(driver.getDevice()); | ||||
| if (connection == null) { | ||||
|   // You probably need to call UsbManager.requestPermission(driver.getDevice(), ..) | ||||
|   return; | ||||
| } | ||||
|     // Open a connection to the first available driver. | ||||
|     UsbSerialDriver driver = availableDrivers.get(0); | ||||
|     UsbDeviceConnection connection = manager.openDevice(driver.getDevice()); | ||||
|     if (connection == null) { | ||||
|         // add UsbManager.requestPermission(driver.getDevice(), ..) handling here | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
| // Read some data! Most have just one port (port 0). | ||||
| UsbSerialPort port = driver.getPorts().get(0); | ||||
| try { | ||||
|   port.open(connection); | ||||
|   port.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE); | ||||
| 
 | ||||
|   byte buffer[] = new byte[16]; | ||||
|   int numBytesRead = port.read(buffer, 1000); | ||||
|   Log.d(TAG, "Read " + numBytesRead + " bytes."); | ||||
| } catch (IOException e) { | ||||
|   // Deal with error. | ||||
| } finally { | ||||
|   port.close(); | ||||
|     UsbSerialPort port = driver.getPorts().get(0); // Most devices have just one port (port 0) | ||||
|     port.open(connection); | ||||
|     port.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE); | ||||
|     usbIoManager = new SerialInputOutputManager(usbSerialPort, this); | ||||
|     Executors.newSingleThreadExecutor().submit(usbIoManager); | ||||
| ``` | ||||
| ```java | ||||
|     port.write("hello".getBytes(), WRITE_WAIT_MILLIS); | ||||
| ``` | ||||
| ```java | ||||
| @Override | ||||
| public void onNewData(byte[] data) { | ||||
|     runOnUiThread(() -> { textView.append(new String(data)); }); | ||||
| } | ||||
| ``` | ||||
| ```java | ||||
|     port.close(); | ||||
| ``` | ||||
| 
 | ||||
| For a simple example, see the | ||||
| [UsbSerialExamples project](https://github.com/mik3y/usb-serial-for-android/blob/master/usbSerialExamples) | ||||
| in git, which is a simple application for reading and showing serial data. | ||||
| 
 | ||||
| For a simple example, see | ||||
| [UsbSerialExamples](https://github.com/mik3y/usb-serial-for-android/blob/master/usbSerialExamples) | ||||
| folder in this project. | ||||
| 
 | ||||
| For a more complete example, see separate github project  | ||||
| [SimpleUsbTerminal](https://github.com/kai-morich/SimpleUsbTerminal) | ||||
| 
 | ||||
| A [simple Arduino application](https://github.com/mik3y/usb-serial-for-android/blob/master/arduino) | ||||
| is also available which can be used for testing. | ||||
| [SimpleUsbTerminal](https://github.com/kai-morich/SimpleUsbTerminal). | ||||
| 
 | ||||
| ## Probing for Unrecognized Devices | ||||
| 
 | ||||
|  | ||||
| @ -1,43 +0,0 @@ | ||||
| /* Copyright 2012 Google Inc.
 | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public | ||||
|  * License as published by the Free Software Foundation; either | ||||
|  * version 2.1 of the License, or (at your option) any later version. | ||||
|  * | ||||
|  * This library is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * Lesser General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Lesser General Public | ||||
|  * License along with this library; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, | ||||
|  * USA. | ||||
|  * | ||||
|  * Project home page: http://code.google.com/p/usb-serial-for-android/
 | ||||
|  */ | ||||
| 
 | ||||
| // Sample Arduino sketch for use with usb-serial-for-android.
 | ||||
| // Prints an ever-increasing counter, and writes back anything
 | ||||
| // it receives.
 | ||||
| 
 | ||||
| static int counter = 0; | ||||
| void setup() { | ||||
|   Serial.begin(115200); | ||||
| } | ||||
| 
 | ||||
| void loop() { | ||||
|   Serial.print("Tick #"); | ||||
|   Serial.print(counter++, DEC); | ||||
|   Serial.print("\n"); | ||||
| 
 | ||||
|   if (Serial.peek() != -1) { | ||||
|     Serial.print("Read: "); | ||||
|     do { | ||||
|       Serial.print((char) Serial.read()); | ||||
|     } while (Serial.peek() != -1); | ||||
|     Serial.print("\n"); | ||||
|   } | ||||
|   delay(1000); | ||||
| } | ||||
| @ -194,22 +194,7 @@ public class DeviceTest implements SerialInputOutputManager.Listener { | ||||
|         try { | ||||
|             telnetRead(0); | ||||
|         } catch (Exception ignored) {} | ||||
| 
 | ||||
|         try { | ||||
|             usbIoManager.setListener(null); | ||||
|             usbIoManager.stop(); | ||||
|         } catch (Exception ignored) {} | ||||
|         try { | ||||
|             usbSerialPort.setDTR(false); | ||||
|             usbSerialPort.setRTS(false); | ||||
|             usbSerialPort.close(); | ||||
|         } catch (Exception ignored) {} | ||||
|         try { | ||||
|             usbDeviceConnection.close(); | ||||
|         } catch (Exception ignored) {} | ||||
|         usbIoManager = null; | ||||
|         usbSerialPort = null; | ||||
|         usbDeviceConnection = null; | ||||
|         usbClose(); | ||||
|         usbSerialDriver = null; | ||||
|     } | ||||
| 
 | ||||
| @ -261,10 +246,15 @@ public class DeviceTest implements SerialInputOutputManager.Listener { | ||||
| 
 | ||||
|     private void usbClose() { | ||||
|         if (usbIoManager != null) { | ||||
|             usbIoManager.setListener(null); | ||||
|             usbIoManager.stop(); | ||||
|             usbIoManager = null; | ||||
|         } | ||||
|         if (usbSerialPort != null) { | ||||
|             try { | ||||
|                 usbSerialPort.setDTR(false); | ||||
|                 usbSerialPort.setRTS(false); | ||||
|             } catch (Exception ignored) { | ||||
|             } | ||||
|             try { | ||||
|                 usbSerialPort.close(); | ||||
|             } catch (IOException ignored) { | ||||
| @ -274,6 +264,18 @@ public class DeviceTest implements SerialInputOutputManager.Listener { | ||||
|         if(usbDeviceConnection != null) | ||||
|             usbDeviceConnection.close(); | ||||
|         usbDeviceConnection = null; | ||||
|         if(usbIoManager != null) { | ||||
|             for(int i=0; i<2000; i++) { | ||||
|                 if(SerialInputOutputManager.State.STOPPED == usbIoManager.getState()) break; | ||||
|                 try { | ||||
|                     Thread.sleep(1); | ||||
|                 } catch (InterruptedException e) { | ||||
|                     e.printStackTrace(); | ||||
|                 } | ||||
|             } | ||||
|             assertEquals(SerialInputOutputManager.State.STOPPED, usbIoManager.getState()); | ||||
|             usbIoManager = null; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void usbOpen(boolean withIoManager) throws Exception { | ||||
| @ -520,6 +522,11 @@ public class DeviceTest implements SerialInputOutputManager.Listener { | ||||
|             usbSerialPort.close(); | ||||
|         } catch (IOException ignored) { | ||||
|         } | ||||
| 
 | ||||
|         if (usbSerialDriver instanceof Cp21xxSerialDriver) { // why needed? | ||||
|             usbIoManager.stop(); | ||||
|             usbIoManager = null; | ||||
|         } | ||||
|         // full re-open supported | ||||
|         usbClose(); | ||||
|         usbOpen(true); | ||||
| @ -640,8 +647,8 @@ public class DeviceTest implements SerialInputOutputManager.Listener { | ||||
|                     assertNotEquals(data1, buf1); | ||||
|                     assertNotEquals(data2, buf2); | ||||
|                 } | ||||
|                 assertThat("42000/8N1", data1, equalTo(buf1)); | ||||
|             } else { | ||||
|                 assertThat("42000/8N1", data1, equalTo(buf1)); | ||||
|                 assertThat("42000/8N1", data2, equalTo(buf2)); | ||||
|             } | ||||
|         } | ||||
| @ -1109,4 +1116,85 @@ public class DeviceTest implements SerialInputOutputManager.Listener { | ||||
| 
 | ||||
|         // todo: purge receive buffer | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     // WriteAsync rarely makes sense, as data is not written until something is read | ||||
|     public void writeAsync() throws Exception { | ||||
|         if (usbSerialDriver instanceof FtdiSerialDriver) | ||||
|             return; // periodically sends status messages, so does not block here | ||||
|         usbParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE); | ||||
|         telnetParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE); | ||||
| 
 | ||||
|         SerialInputOutputManager ioManager; | ||||
|         ioManager = new SerialInputOutputManager(null); | ||||
|         assertEquals(null, ioManager.getListener()); | ||||
|         ioManager.setListener(this); | ||||
|         assertEquals(this, ioManager.getListener()); | ||||
|         ioManager = new SerialInputOutputManager(null, this); | ||||
|         assertEquals(this, ioManager.getListener()); | ||||
| 
 | ||||
|         byte[] data, buf = new byte[]{1}; | ||||
|         int len; | ||||
|         usbIoManager.writeAsync(buf); | ||||
|         usbIoManager.writeAsync(buf); | ||||
|         data = telnetRead(1); | ||||
|         assertEquals(0, data.length); | ||||
|         telnetWrite(buf); | ||||
|         data = usbRead(1); | ||||
|         assertEquals(1, data.length); | ||||
|         data = telnetRead(2); | ||||
|         assertEquals(2, data.length); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     // Blocking read should be avoided in the UI thread, as it makes the app unresponsive. | ||||
|     // You better use the SerialInputOutputManager. | ||||
|     // | ||||
|     // With the change from bulkTransfer to queued requests, the read timeout has no effect | ||||
|     // and the call blocks until close() if no data is available! | ||||
|     // The change from bulkTransfer to queued requests was necessary to prevent data loss. | ||||
|     public void readSync() throws Exception { | ||||
|         if (usbSerialDriver instanceof FtdiSerialDriver) | ||||
|             return; // periodically sends status messages, so does not block here | ||||
| 
 | ||||
|         Runnable closeThread = new Runnable() { | ||||
|             @Override | ||||
|             public void run() { | ||||
|                 try { | ||||
|                     Thread.sleep(100); | ||||
|                 } catch (InterruptedException e) { | ||||
|                     e.printStackTrace(); | ||||
|                 } | ||||
|                 usbClose(); | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         usbClose(); | ||||
|         usbOpen(false); | ||||
|         usbParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE); | ||||
|         telnetParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE); | ||||
| 
 | ||||
|         byte[] buf = new byte[]{1}; | ||||
|         int len; | ||||
|         long time; | ||||
|         telnetWrite(buf); | ||||
|         len = usbSerialPort.read(buf, 0); // not blocking because data is available | ||||
|         assertEquals(1, len); | ||||
| 
 | ||||
|         time = System.currentTimeMillis(); | ||||
|         Executors.newSingleThreadExecutor().submit(closeThread); | ||||
|         len = usbSerialPort.read(buf, 0); // blocking until close() | ||||
|         assertEquals(0, len); | ||||
|         assertTrue(System.currentTimeMillis()-time >= 100); | ||||
| 
 | ||||
|         usbOpen(false); | ||||
|         usbParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE); | ||||
|         telnetParameters(19200, 8, 1, UsbSerialPort.PARITY_NONE); | ||||
| 
 | ||||
|         time = System.currentTimeMillis(); | ||||
|         Executors.newSingleThreadExecutor().submit(closeThread); | ||||
|         len = usbSerialPort.read(buf, 10); // timeout not used any more -> blocking until close() | ||||
|         assertEquals(0, len); | ||||
|         assertTrue(System.currentTimeMillis()-time >= 100); | ||||
|    } | ||||
| } | ||||
|  | ||||
| @ -50,7 +50,7 @@ public class SerialInputOutputManager implements Runnable { | ||||
|     // Synchronized by 'mWriteBuffer' | ||||
|     private final ByteBuffer mWriteBuffer = ByteBuffer.allocate(BUFSIZ); | ||||
| 
 | ||||
|     private enum State { | ||||
|     public enum State { | ||||
|         STOPPED, | ||||
|         RUNNING, | ||||
|         STOPPING | ||||
| @ -111,7 +111,7 @@ public class SerialInputOutputManager implements Runnable { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private synchronized State getState() { | ||||
|     public synchronized State getState() { | ||||
|         return mState; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user