Andriod串口通信开发(免ROOT权限)

时间:2024-02-24 08:52:47

最近在尝试写一个安卓版的无人机地面站,参考了DroidPlanner的代码,发现了一个很好用的串口通信组件usb-serial-for-android,免root权限,不需要NDK,不过只支持Android 3.1+。

github地址:https://github.com/mik3y/usb-serial-for-android

 

关于用法README.md中已经介绍得很详尽了,可以简单归结为以下几点:

1. 把usb-serial-for-android复制到工程中,Eclipse和Android Studio的处理方式各不相同,具体步骤可参考这里

2. 复制device_filter.xml到工程的res/xml目录(没有则自行新建);

3. 配置AndroidManifest.xml;

 1 <activity
 2     android:name="..."
 3     ...>
 4   <intent-filter>
 5     <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
 6   </intent-filter>
 7   <meta-data
 8       android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
 9       android:resource="@xml/device_filter" />
10 </activity>

4. 编写代码。

 1 // Find all available drivers from attached devices.
 2 UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
 3 List<UsbSerialDriver> availableDrivers = 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                 List<UsbSerialDriver> availableDrivers = 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 version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.stshdz.drone.shdrone.MainActivity">

    <Button
        android:id="@+id/btn_send"
        android:text="send"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/tv_display"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="没有数据." />
</LinearLayout>

 

xml/device_filter.xml

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <resources>
 3     <!-- 0x0403 / 0x6001: FTDI FT232R UART -->
 4     <usb-device vendor-id="1027" product-id="24577" />
 5     
 6     <!-- 0x0403 / 0x6015: FTDI FT231X -->
 7     <usb-device vendor-id="1027" product-id="24597" />
 8 
 9     <!-- 0x2341 / Arduino -->
10     <usb-device vendor-id="9025" />
11 
12     <!-- 0x16C0 / 0x0483: Teensyduino  -->
13     <usb-device vendor-id="5824" product-id="1155" />
14 
15     <!-- 0x10C4 / 0xEA60: CP210x UART Bridge -->
16     <usb-device vendor-id="4292" product-id="60000" />
17     
18     <!-- 0x067B / 0x2303: Prolific PL2303 -->
19     <usb-device vendor-id="1659" product-id="8963" />
20     
21     <!-- 0x1a86 / 0x7523: Qinheng CH340 -->
22     <usb-device vendor-id="6790" product-id="29987" />
23 </resources>

 

AndroidManifest.xml

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3     package="com.stshdz.drone.shdrone" >
 4 
 5     <application
 6         android:allowBackup="true"
 7         android:icon="@mipmap/ic_launcher"
 8         android:label="@string/app_name"
 9         android:supportsRtl="true"
10         android:theme="@style/AppTheme" >
11 
12         <activity android:name=".MainActivity" >
13             <intent-filter>
14                 <action android:name="android.intent.action.MAIN" />
15 
16                 <category android:name="android.intent.category.LAUNCHER" />
17             </intent-filter>
18 
19             <intent-filter>
20                 <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
21             </intent-filter>
22             <meta-data
23                 android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
24                 android:resource="@xml/device_filter" />
25         </activity>
26     </application>
27 
28 </manifest>

 

Android设备通过OTG数据线连接USB转TTL模块,模块的TX与RX引脚短接(自发自收),点击SEND即可看到效果。