`
bell0901
  • 浏览: 27806 次
社区版块
存档分类
最新评论

Android USB Host与HID设备通信

HID 
阅读更多

    参照了http://blog.csdn.net/qweadf1/article/details/41646439链接中的文章,实现了Android和HID设备的收发数据。

    直接上manifest文件。主要是usb.host权限,这边没有配置xml文件指定USB设备。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.com.hid" >

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

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

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action       android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/>
            </intent-filter>
            
        </activity>
    </application>

</manifest>

   

    接下来主要代码

package com.com.hid;

import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
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.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;

import java.util.HashMap;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "USB_HOST";
    private UsbManager myUsbManager;
    private UsbDevice myUsbDevice;
    private UsbInterface myInterface;
    private UsbDeviceConnection myDeviceConnection;
    private final int VendorID = 1042;
    private final int ProductID = 1;
    private TextView info;

    private UsbEndpoint epOut;
    private UsbEndpoint epIn;

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

    byte[] mybuffer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        mybuffer = new byte[]{(byte)0x02, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x05, (byte)0xcc, (byte)0xcc, (byte)0xcc, (byte)0xcc, (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00};
        Log.i("mybuffer", bytesToHexString(mybuffer));
        info = (TextView) findViewById(R.id.info);
        myUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
        enumerateDevice();

    }

    //枚举设备
    private void enumerateDevice() {
        if (myUsbManager == null)
            return;

        HashMap<String, UsbDevice> deviceList = myUsbManager.getDeviceList();
        if (!deviceList.isEmpty()) { // deviceList不为空
            StringBuffer sb = new StringBuffer();
            for (UsbDevice device : deviceList.values()) {
                sb.append(device.toString());
                sb.append("\n");
//                info.setText(sb);
                // 输出设备信息
                Log.d(TAG, "DeviceInfo: " + device.getVendorId() + " , "
                        + device.getProductId());

                // 枚举到设备
                if (device.getVendorId() == VendorID
                        && device.getProductId() == ProductID) {
                    myUsbDevice = device;
                    Toast.makeText(this, "枚举设备成功", Toast.LENGTH_SHORT).show();
                    Log.d(TAG, "枚举设备成功");
                    findInterface();
                } else {
//                    Toast.makeText(this, "Not Found VID and PID", Toast.LENGTH_SHORT).show();
                    Log.d(TAG, "Not Found VID and PID");
                }
            }
        } else {
            new AlertDialog.Builder(this).setTitle("未枚举到设备!")
                    .setMessage("请先连接设备")
                    .setCancelable(false)
                    .setNeutralButton("确定", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            //finish();
                        }
                    }).show();
        }
    }

    //    找到接口
    private void findInterface() {
        if (myUsbDevice == null) {
            return;
        }
        Log.d(TAG, "interfaceCounts : " + myUsbDevice.getInterfaceCount());
        for (int i = 0; i < myUsbDevice.getInterfaceCount(); i++) {
            UsbInterface intf = myUsbDevice.getInterface(i);
            // 根据手上的设备做一些判断,其实这些信息都可以在枚举到设备时打印出来
            if (intf.getInterfaceClass() == 3
                    && intf.getInterfaceSubclass() == 0
                    && intf.getInterfaceProtocol() == 0) {
                myInterface = intf;
                Log.d(TAG, "找到我的设备接口");
                openDevice();
            }
            break;
        }

    }

    //获取权限,打开设备
    private void openDevice() {
        if (myInterface != null) {
            UsbDeviceConnection conn = null;
            // 在open前判断是否有连接权限;对于连接权限可以静态分配,也可以动态分配权限,可以查阅相关资料
            PendingIntent pi = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
            if (!myUsbManager.hasPermission(myUsbDevice)) {
                myUsbManager.requestPermission(myUsbDevice, pi);
            }
            if (myUsbManager.hasPermission(myUsbDevice)) {
                conn = myUsbManager.openDevice(myUsbDevice);
            } else {
                Toast.makeText(this, "未获得权限", Toast.LENGTH_SHORT).show();
            }

            if (conn == null) {
                return;
            }

            if (conn.claimInterface(myInterface, true)) {
                myDeviceConnection = conn; // 到此你的android设备已经连上HID设备
                Log.d(TAG, "打开设备成功");
                Toast.makeText(this, "打开设备成功", Toast.LENGTH_SHORT).show();
                assignEndpoint();
            } else {
                conn.close();
            }
        }
    }

    //拿到端点,用bulkTransfer进行数据发收
    private void assignEndpoint() {
        if (myInterface.getEndpoint(1) != null) {
            epOut = myInterface.getEndpoint(1);
        }
        if (myInterface.getEndpoint(0) != null) {
            epIn = myInterface.getEndpoint(0);
        }
        info.setText(myUsbDevice.getDeviceName() + "\nInterfaceCount:" + myUsbDevice.getInterfaceCount() + "\nEndpointCount:" + myInterface.getEndpointCount());
        Log.d(TAG, "assignEndpoint");


        int re = myDeviceConnection.bulkTransfer(epOut, mybuffer, mybuffer.length, 3000);
        byte[] reByte = new byte[64];
        int re2 = myDeviceConnection.bulkTransfer(epIn, reByte, reByte.length, 3000);
        Log.i("reByte", "re"+re+"re2"+ re2 + "\n" + bytesToHexString(reByte));
        Toast.makeText(this, bytesToHexString(reByte), Toast.LENGTH_LONG).show();

    }




    public static String bytesToHexString(byte[] src){
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

    发送和接受的数据是64位的byte[]

    断开设备后用releaseInterface() 和close()关闭UsbInterface 和UsbDeviceConnection 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics