最近在尝试写一个安卓版的无人机地面站,参考了DroidPlanner的代码,发现了一个很好用的串口通信组件usb-serial-for-android,免root权限,不需要NDK,不过只支持Android 3.1+。
github地址:
关于用法README.md中已经介绍得很详尽了,可以简单归结为以下几点:
1. 把usb-serial-for-android复制到工程中,Eclipse和Android Studio的处理方式各不相同,具体步骤可参考;
2. 复制到工程的res/xml目录(没有则自行新建);
3. 配置AndroidManifest.xml;
14 5 76 10
4. 编写代码。
1 // Find all available drivers from attached devices. 2 UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE); 3 ListavailableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager); 4 if (availableDrivers.isEmpty()) { 5 return; 6 } 7 8 // Open a connection to the first available driver. 9 UsbSerialDriver driver = availableDrivers.get(0);10 UsbDeviceConnection connection = manager.openDevice(driver.getDevice());11 if (connection == null) {12 // You probably need to call UsbManager.requestPermission(driver.getDevice(), ..)13 return;14 }15 16 // Read some data! Most have just one port (port 0).17 UsbSerialPort port = driver.getPorts().get(0);18 try {19 port.open(connection);20 port.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);21 22 byte buffer[] = new byte[16];23 int numBytesRead = port.read(buffer, 1000);24 Log.d(TAG, "Read " + numBytesRead + " bytes.");25 } catch (IOException e) {26 // Deal with error.27 } finally {28 port.close();29 }
以下是我修改过的简单的例子(基于Android Studio 2.2.3)。
MainActivity.java
1 package com.stshdz.drone.shdrone; 2 3 import android.content.Context; 4 import android.hardware.usb.UsbDeviceConnection; 5 import android.hardware.usb.UsbManager; 6 import android.os.Handler; 7 import android.os.Message; 8 import android.support.v7.app.AppCompatActivity; 9 import android.os.Bundle; 10 import android.view.View; 11 import android.widget.TextView; 12 13 import com.hoho.android.usbserial.driver.UsbSerialDriver; 14 import com.hoho.android.usbserial.driver.UsbSerialPort; 15 import com.hoho.android.usbserial.driver.UsbSerialProber; 16 17 import java.io.IOException; 18 import java.util.List; 19 20 public class MainActivity extends AppCompatActivity { 21 UsbSerialPort port = null; 22 23 class MyHandler extends Handler { 24 @Override 25 public void handleMessage(Message msg) { 26 switch (msg.what) { 27 case 0x11: 28 TextView tv_display = (TextView)findViewById(R.id.tv_display); 29 Bundle bundle = msg.getData(); 30 tv_display.setText(tv_display.getText() + bundle.getString("text")); 31 break; 32 default: 33 break; 34 } 35 } 36 } 37 38 39 private MyHandler myHandler = new MyHandler(); 40 41 @Override 42 protected void onCreate(Bundle savedInstanceState) { 43 super.onCreate(savedInstanceState); 44 getSupportActionBar().hide(); 45 setContentView(R.layout.activity_main); 46 47 findViewById(R.id.btn_send).setOnClickListener(new View.OnClickListener() { 48 @Override 49 public void onClick(View v) { 50 try { 51 if(port != null){ 52 port.write("Hello\r\n".getBytes(), 1000); 53 } 54 } catch (IOException e) { 55 e.printStackTrace(); 56 } 57 } 58 }); 59 60 new Thread(new Runnable() { 61 @Override 62 public void run() { 63 64 // Find all available drivers from attached devices. 65 UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE); 66 ListavailableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager); 67 if (availableDrivers.isEmpty()) { 68 return; 69 } 70 71 // Open a connection to the first available driver. 72 UsbSerialDriver driver = availableDrivers.get(0); 73 UsbDeviceConnection connection = manager.openDevice(driver.getDevice()); 74 if (connection == null) { 75 // You probably need to call UsbManager.requestPermission(driver.getDevice(), ..) 76 return; 77 } 78 79 // Read some data! Most have just one port (port 0). 80 port = driver.getPorts().get(0); 81 try { 82 port.open(connection); 83 port.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE); 84 85 while(true) { 86 byte buffer[] = new byte[16]; 87 int numBytesRead = port.read(buffer, 1000); 88 89 if(numBytesRead > 0){ 90 Message message = new Message(); 91 message.what = 0x11; 92 Bundle bundle = new Bundle(); 93 bundle.putString("text", new String(buffer, "UTF-8")); 94 message.setData(bundle); 95 myHandler.sendMessage(message); 96 } 97 } 98 99 } catch (IOException e) {100 // Deal with error.101 } finally {102 try {103 port.close();104 } catch (IOException e) {105 e.printStackTrace();106 }107 }108 }109 }).start();110 }111 }
activity_main.xml
xml/device_filter.xml
1 23 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
AndroidManifest.xml
1 24 5 11 12 27 2813 2614 18 1915 16 17 20 2221 25
Android设备通过OTG数据线连接USB转TTL模块,模块的TX与RX引脚短接(自发自收),点击“SEND”即可看到效果。