Android USB编程



一、什么是USB
USB就是通用串行总线(Universal Serial Bus)的缩写,用于规范主从通信。USB接口支持设备的即插即用和热插拔功能。
与USB有关的OTG既是On-The-Go,主要用于各种不同的设备或移动设备件间的链接和数据交换。
二、Android的USB相关API
包:android.hardware.usb
类:UsbManager/UsbDevice/UsbInterface/UsbEndPoint/UsbDeviceConnection/UsbRequest/UsbConstants/UsbAccessory
获取UsbManager:UsbManager manager = (UsbManager)getSystemService(Context.USB_SERVICE);
三、Android设备与USB设备
第一种模式Host Mode:Android设备作为Host,向Usb设备供电,并进行数据传输;
第一种模式Accessory Mode:Usb设备作为Host,向Android设备供电,并进行数据传输;
四、例子(可以枚举设备/点击设备建立连接/接收数据/发送数据)
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.usbhelper"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

    <uses-feature android:name="android.hardware.usb.host" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name=".UsbReceiver" >
            <intent-filter android:priority="1000" >
                <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
            </intent-filter>
        </receiver>
    </application>

</manifest>

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.usbhelper"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

    <uses-feature android:name="android.hardware.usb.host" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name=".UsbReceiver" >
            <intent-filter android:priority="1000" >
                <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
            </intent-filter>
        </receiver>
    </application>

</manifest>

item.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.usbhelper"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

    <uses-feature android:name="android.hardware.usb.host" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name=".UsbReceiver" >
            <intent-filter android:priority="1000" >
                <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
            </intent-filter>
        </receiver>
    </application>

</manifest>

MainActivity.java
package com.example.usbhelper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
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.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

@SuppressLint("NewApi")
public class MainActivity extends Activity {
 private Button send = null;
 private Button receive = null;
 private Button list = null;
 private ListView information = null;
 private EditText content = null;
 private TextView result = null;

 private Handler mHandler = null;
 private ArrayList<UsbDevice> devicesList = null;
 private ArrayList<HashMap<String, Object>> showDevices = null;

 private SimpleAdapter adapter = null;

 private boolean isRunning = false;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  mHandler = new Handler() {

   @Override
   public void handleMessage(Message msg) {
    // TODO Auto-generated method stub
    // super.handleMessage(msg);
    int what = msg.what;
    switch (what) {
    case 0: {
     String string = msg.obj.toString();
     result.setText(result.getText().toString() + "\n" + string);
    }
     break;
    default:
     break;
    }
   }

  };
  initData();
 }

 private UsbManager mUsbManager = null;

 private void initData() {
  findViewsById();
  showDevices = new ArrayList<HashMap<String, Object>>();
  devicesList = new ArrayList<UsbDevice>();
  mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
  registerUsbReceiver();
  initListView();

 }

 private PendingIntent mPermissionIntent = null;

 private void registerUsbReceiver() {
  mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(
    ACTION_USB_PERMISSION), 0);
  IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
  registerReceiver(mUsbReceiver, filter);
 }

 private void findViewsById() {
  send = (Button) findViewById(R.id.btn_send_main);
  receive = (Button) findViewById(R.id.btn_receive_main);
  content = (EditText) findViewById(R.id.et_content_main);
  result = (TextView) findViewById(R.id.tv_result_main);
  list = (Button) findViewById(R.id.btn_list_main);
  information = (ListView) findViewById(R.id.lv_devices_main);

  send.setOnClickListener(mOnClickListener);
  receive.setOnClickListener(mOnClickListener);
  list.setOnClickListener(mOnClickListener);

  information.setOnItemClickListener(new OnItemClickListener() {

   @Override
   public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
     long arg3) {
    // TODO Auto-generated method stub
    mUsbManager.requestPermission(devicesList.get(arg2),
      mPermissionIntent);
   }
  });
 }

 private void listTheDevice() {
  if (mUsbManager == null) {
   return;
  }
  HashMap<String, UsbDevice> devices = mUsbManager.getDeviceList();
  Iterator<UsbDevice> iterator = devices.values().iterator();
  showDevices.clear();
  devicesList.clear();

  while (iterator.hasNext()) {
   UsbDevice device = iterator.next();
   HashMap<String, Object> map = new HashMap<String, Object>();
   map.put("device_id", device.getDeviceId());
   map.put("device_name", device.getDeviceName());
   showDevices.add(map);
   devicesList.add(device);
  }
  if (showDevices.size() > 0) {
   adapter = new SimpleAdapter(MainActivity.this, showDevices,
     R.layout.item, new String[] { "device_id", "device_name" },
     new int[] { R.id.device_id, R.id.device_name });
   information.setAdapter(adapter);
  }
  Toast.makeText(this, "设备数:" + devicesList.size(), Toast.LENGTH_SHORT)
    .show();

 }

 private void initListView() {
  HashMap<String, Object> map = new HashMap<String, Object>();
  map.put("device_id", "测试数据");
  map.put("device_name", "测试数据");
  showDevices.add(map);
  adapter = new SimpleAdapter(MainActivity.this, showDevices,
    R.layout.item, new String[] { "device_id", "device_name" },
    new int[] { R.id.device_id, R.id.device_name });
  information.setAdapter(adapter);
 }

 private View.OnClickListener mOnClickListener = new View.OnClickListener() {

  @Override
  public void onClick(View arg0) {
   // TODO Auto-generated method stub
   int id = arg0.getId();
   switch (id) {
   case R.id.btn_list_main:
    listTheDevice();
    break;
   case R.id.btn_send_main: {
    String message = content.getText().toString();
    if (message != null && message.length() > 0) {
     new Thread(new SendRunnable(message.getBytes()));
    }
   }
    break;
   case R.id.btn_receive_main: {
    if (isRunning) {
     isRunning = false;
    } else {
     isRunning = true;
     new Thread(new ReceiveRunnable()).start();
    }
   }

    break;
   default:
    Toast.makeText(MainActivity.this, "我真的不知道你对我做了什么",
      Toast.LENGTH_SHORT).show();
    break;
   }
  }
 };

 private class ReceiveRunnable implements Runnable {
  public void run() {
   byte[] buffer = new byte[64];
   while (isRunning) {
    mDeviceConnection.bulkTransfer(epin, buffer, buffer.length, 0);
    Message msg = new Message();
    msg.what = 0;
    msg.obj = new String(buffer);
    mHandler.sendMessage(msg);
    System.out.println("received true");
   }
  }
 }

 private class SendRunnable implements Runnable {
  private byte[] buffer;

  public SendRunnable(byte[] buffer) {
   this.buffer = buffer;
  }

  public void run() {
   int length = mDeviceConnection.bulkTransfer(epout, buffer,
     buffer.length, 0);
   if (length > 0) {
    mDeviceConnection.bulkTransfer(epin, buffer, buffer.length, 0);
    Message msg = new Message();
    msg.what = 0;
    msg.obj = new String(buffer);
    mHandler.sendMessage(msg);
   }
  }
 }

 // mUsbManager.requestPermission(device, mPermissionIntent);

 private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";

 private UsbDeviceConnection mDeviceConnection = null;
 private UsbEndpoint epin = null;
 private UsbEndpoint epout = null;
 private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {

  public void onReceive(Context context, Intent intent) {
   String action = intent.getAction();
   if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
   } else if (ACTION_USB_PERMISSION.equals(action)) {
    synchronized (this) {
     UsbDevice mUsbDevice;
     mUsbDevice = (UsbDevice) intent
       .getParcelableExtra(UsbManager.EXTRA_DEVICE);

     if (intent.getBooleanExtra(
       UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
      if (mUsbDevice != null) {
       // call method to set up device communication
       UsbInterface intf = mUsbDevice.getInterface(0);
       epin = intf.getEndpoint(0);
       epout = intf.getEndpoint(1);
       mDeviceConnection = mUsbManager
         .openDevice(mUsbDevice);
       mDeviceConnection.claimInterface(intf, true);
      }
     } else {
      Log.d("UsbHelper", "permission denied for device "
        + mUsbDevice.getDeviceName());
     }
    }
   }
  }
 };
}


UsbReceiver.java
package com.example.usbhelper;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.sax.StartElementListener;

public class UsbReceiver extends BroadcastReceiver {

 @Override
 public void onReceive(Context arg0, Intent arg1) {
  // TODO Auto-generated method stub
  Intent intent = new Intent(arg0, MainActivity.class);
  intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  arg0.startActivity(intent);
 }
}

五、小结
USB通信是一种不会磨灭的通信,你懂的。随着物联网的到来和发展,WIFI/蓝牙/Zigbee火起来的,但随着物联网的进一步发展,USB或者类似的通信协议也将会得到空前的应用,因为,组件化会成为智能产品快速研发的关键,即插即用,安全可靠。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。