happyboy200032的博客

[转]Android(安卓)系统USB-OTG-HID外设通讯开发

google官方文档https://developer.android.com/guide/topics/connectivity/usb/host.html 
 
Android系统3.1及以上版本才能支持USBHOST,这样我们才能连接HID设备进行通讯 
 
项目新建完成之后,AndroidManifest.xml中加入以下代码 
 
然后res下增加xml文件夹,新建device_filter.xml,并加入一下代码,这里是声明HID设备VID以及PID,注意是10进制 
 
package com.android.missilelauncher; 
 
import java.nio.ByteBuffer; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.HashMap; 
import java.util.Iterator; 
 
import android.app.Activity; 
import android.content.Context; 
import android.content.Intent; 
import android.hardware.Sensor; 
import android.hardware.SensorEvent; 
import android.hardware.SensorEventListener; 
import android.hardware.SensorManager; 
import android.hardware.usb.UsbConstants; 
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.hardware.usb.UsbRequest; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.Gravity; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.ArrayAdapter; 
import android.widget.Button; 
import android.widget.ListView; 
import android.widget.TextView; 
import android.widget.Toast; 
 
public class MissileLauncherActivity extends Activity 

    private static final String TAG = "MissileLauncherActivity"; 
 
    private Button btsend; // 发送按钮 
    private UsbManager manager; // USB管理器 
    private UsbDevice mUsbDevice; // 找到的USB设备 
    private ListView lsv1; // 显示USB信息的 
    private UsbInterface mInterface; 
    private UsbDeviceConnection mDeviceConnection; 
 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
        super.onCreate(savedInstanceState); 
 
        setContentView(R.layout.launcher); 
 
        btsend = (Button) findViewById(R.id.btsend); 
        btsend.setOnClickListener(btsendListener); 
 
        lsv1 = (ListView) findViewById(R.id.lsv1); 
 
        // 获取USB设备 
        manager = (UsbManager) getSystemService(Context.USB_SERVICE); 
        if (manager == null) 
        { 
            return; 
        } 
        else 
        { 
            Log.i(TAG, "usb设备:" + String.valueOf(manager.toString())); 
        } 
 
        HashMap<String, UsbDevice> deviceList = manager.getDeviceList(); 
        Log.i(TAG, "usb设备:" + String.valueOf(deviceList.size())); 
        Iterator<UsbDevice> deviceIterator = deviceList.values().iterator(); 
        ArrayList<String> USBDeviceList = new ArrayList<String>(); // 存放USB设备的数量 
        while (deviceIterator.hasNext()) 
        { 
            UsbDevice device = deviceIterator.next(); 
 
            USBDeviceList.add(String.valueOf(device.getVendorId())); 
            USBDeviceList.add(String.valueOf(device.getProductId())); 
 
            // 在这里添加处理设备的代码 
            if (device.getVendorId() == 6790 && device.getProductId() == 57360) 
            { 
                mUsbDevice = device; 
                Log.i(TAG, "找到设备"); 
            } 
        } 
 
        // 创建一个ArrayAdapter 
        lsv1.setAdapter(new ArrayAdapter<String>(this, 
                        android.R.layout.simple_list_item_1, USBDeviceList)); 
        findIntfAndEpt(); 
    } 
 
    // 寻找接口和分配结点 
    private void findIntfAndEpt() 
    { 
        if (mUsbDevice == null) 
        { 
            Log.i(TAG, "没有找到设备"); 
            return; 
        } 
 
        for (int i = 0; i < mUsbDevice.getInterfaceCount();) 
        { 
            // 获取设备接口,一般都是一个接口,你可以打印getInterfaceCount()方法查看接 
            // 口的个数,在这个接口上有两个端点,OUT 和 IN 
            UsbInterface intf = mUsbDevice.getInterface(i); 
            Log.d(TAG, i + " " + intf); 
            mInterface = intf; 
            break; 
        } 
 
        if (mInterface != null) 
        { 
            UsbDeviceConnection connection = null; 
            // 判断是否有权限 
            if (manager.hasPermission(mUsbDevice)) 
            { 
                // 打开设备,获取 UsbDeviceConnection 对象,连接设备,用于后面的通讯 
                connection = manager.openDevice(mUsbDevice); 
                if (connection == null) 
                { 
                    return; 
                } 
 
                if (connection.claimInterface(mInterface, true)) 
                { 
                    Log.i(TAG, "找到接口"); 
                    mDeviceConnection = connection; 
                    // 用UsbDeviceConnection 与 UsbInterface 进行端点设置和通讯 
                    getEndpoint(mDeviceConnection, mInterface); 
                } 
                else 
                { 
                    connection.close(); 
                } 
            } 
            else 
            { 
                Log.i(TAG, "没有权限"); 
            } 
        } 
        else 
        { 
            Log.i(TAG, "没有找到接口"); 
        } 
    } 
 
    private UsbEndpoint epOut; 
    private UsbEndpoint epIn; 
 
    // 用UsbDeviceConnection 与 UsbInterface 进行端点设置和通讯 
    private void getEndpoint(UsbDeviceConnection connection, UsbInterface intf) 
    { 
        if (intf.getEndpoint(1) != null) 
        { 
            epOut = intf.getEndpoint(1); 
        } 
 
        if (intf.getEndpoint(0) != null) 
        { 
            epIn = intf.getEndpoint(0); 
        } 
    } 
 
    private byte[] Sendbytes; // 发送信息字节 
    private byte[] Receiveytes; // 接收信息字节 
    private OnClickListener btsendListener = new OnClickListener() 
    { 
        int ret = -100; 
 
        @Override 
        public void onClick(View v) 
        { 
            String testString = "010A"; 
            //String testString = "C783CC30"; 
            byte[] bt = clsPublic.HexString2Bytes(testString); 
 
            Sendbytes = Arrays.copyOf(bt, bt.length); 
 
            // 1,发送准备命令 
            ret = mDeviceConnection.bulkTransfer(epOut, Sendbytes, 
                                                 Sendbytes.length, 5000); 
            Log.i(TAG, "已经发送!"); 
 
            // 2,接收发送成功信息 
            Receiveytes = new byte[32]; 
            ret = mDeviceConnection.bulkTransfer(epIn, Receiveytes, 
                                                 Receiveytes.length, 10000); 
            Log.i(TAG, "接收返回值:" + String.valueOf(ret)); 
            if (ret != 32) 
            { 
                DisplayToast("接收返回值" + String.valueOf(ret)); 
                return; 
            } 
            else 
            { 
                // 查看返回值 
                DisplayToast(clsPublic.Bytes2HexString(Receiveytes)); 
                Log.i(TAG, clsPublic.Bytes2HexString(Receiveytes)); 
            } 
        } 
    }; 
 
    public void DisplayToast(CharSequence str) 
    { 
        Toast toast = Toast.makeText(this, str, Toast.LENGTH_LONG); 
        // 设置Toast显示的位置 
        toast.setGravity(Gravity.TOP, 0, 200); 
        // 显示Toast 
        toast.show(); 
    } 

 
这里还有一个需要解决的问题就是如何设置输入输出报文,函数是controlTransfer(requestType, request, value, index, buffer, length, timeout)

评论
热度(1)

技术经验积累

© happyboy200032的博客 | Powered by LOFTER