1.说在前面的话
这次做了一个项目,要求android端与外接设备进行通信,用到的是otg线连接开发板。然而网上有关USB host通信的资料很少,这里我就把自己的想法以及遇到的坑说一下吧(鄙视鄙视鄙视)。
2.Android Studio 配置
2.1Manifest配置
<!--android作为host端的权限-->
<uses-feature android:name="android.hardware.usb.host" android:required="true" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/usbfilter">
</meta-data>
</activity>
这里的action是外接设备被检测的动作,下面的usbfilter是过滤文件,里面存放外接设备的vendor-id和product-id。
2.2Usbfilter配置
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<usb-device vendor-id="1234" product-id="1234" />
</resources>
配置这个主要为了过滤出你的设备,然后再android端会提示你打开相应的app。这两个id可以在电脑上面获取,将你的设备利用usb线插入电脑,然后再设备管理器里面找到你的设备,右键属性,在详细信息中查看你的硬件id(上面显示的是16进制的),将他转换成10进制的数字就可以了。或者利用这个软件进行查询。
3.通信
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private EditText et_content;
private TextView tv_receive;
private Button btn_send, btn_receive;
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
private HashMap<String, UsbDevice> deviceList; //设备列表
private UsbManager usbManager; //USB管理器:负责管理USB设备的类
private UsbDevice usbDevice; //找到的USB设备
private UsbInterface usbInterface; //代表USB设备的一个接口
private UsbDeviceConnection deviceConnection; //USB连接的一个类。用此连接可以向USB设备发送和接收数据,这里我们使用这个类下面的块传输方式
private UsbEndpoint usbEpIn; //代表一个接口的某个节点的类:读数据节点
private UsbEndpoint usbEpOut; //代表一个接口的某个节点的类:写数据节点
private PendingIntent intent; //意图
private byte[] sendBytes; //要发送信息字节
private byte[] receiveBytes; //接收到的信息字节
private Message message = new Message();
private DataUtil dataUtil = new DataUtil();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent = PendingIntent.getBroadcast(this,0,new Intent(ACTION_USB_PERMISSION),0);
registerReceiver(broadcastReceiver, new IntentFilter(ACTION_USB_PERMISSION));
initUsbDevice();
initView();
initListener();
}
//初始化USB设备
private void initUsbDevice() {
usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
deviceList = usbManager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
while (deviceIterator.hasNext()) {
UsbDevice device = deviceIterator.next();
//找到指定的设备
if (device.getVendorId() == 2588 && device.getProductId() == 9030) {
usbDevice = device;
Log.e(TAG, "找到设备");
}
}
findInterface();
}
//获取设备接口
private void findInterface() {
if (usbDevice == null) {
Log.e(TAG, "没有找到设备");
return;
}
for (int i = 0; i < usbDevice.getInterfaceCount(); i++) {
//一个设备上面一般只有一个接口,有两个端点,分别接受和发送数据
UsbInterface uInterface = usbDevice.getInterface(i);
usbInterface = uInterface;
Log.e(TAG, usbInterface.toString());
break;
}
getEndpoint(usbInterface);
if (usbInterface != null) {
UsbDeviceConnection connection = null;
//判断是否有权限
if (usbManager.hasPermission(usbDevice)) {
Log.e(TAG, "已经获得权限");
connection = usbManager.openDevice(usbDevice);
Log.e(TAG, connection == null ? "true" : "false");
if (connection == null) {
Log.e(TAG, "设备连接为空");
return;
}
if (connection != null && connection.claimInterface(usbInterface, true)) {
deviceConnection = connection;
Log.e(TAG, deviceConnection == null ? "true" : "false");
} else {
connection.close();
}
} else {
Log.e(TAG, "正在获取权限...");
usbManager.requestPermission(usbDevice, intent);
if (usbManager.hasPermission(usbDevice)) {
Log.e(TAG, "获取权限");
} else {
Log.e(TAG, "没有权限");
}
}
} else {
Log.e(TAG, "没有找到接口");
}
}
//获取端点
private void getEndpoint (UsbInterface usbInterface) {
for (int i = 0; i < usbInterface.getEndpointCount(); i++) {
UsbEndpoint ep = usbInterface.getEndpoint(i);
if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
usbEpOut = ep;
Log.e(TAG, "获取发送数据的端点");
} else {
usbEpIn = ep;
Log.e(TAG, "获取接受数据的端点");
}
}
}
}
//初始化
private void initView() {
et_content = (EditText) findViewById(R.id.et_content);
tv_receive = (TextView) findViewById(R.id.tv_receive);
btn_send = (Button) findViewById(R.id.btn_send);
btn_receive = (Button) findViewById(R.id.btn_receive);
}
//初始化监听
private void initListener() {
btn_send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@Override
public void run() {
Log.e(TAG, usbDevice.getDeviceName());
Log.e(TAG, usbEpIn.getEndpointNumber() + "------" + usbEpOut.getEndpointNumber());
Log.e(TAG, deviceConnection == null ? "true" : "false");
byte[] sendData = new byte[4];
sendData[0] = (byte) 0x31;
sendData[1] = (byte) 0x32;
sendData[2] = (byte) 0x33;
sendData[3] = (byte) 0x34;
Log.e(TAG, sendData[0] + "");
int result = deviceConnection.bulkTransfer(usbEpOut, sendData, sendData.length, 3000);
Log.e(TAG, "发送状态码:" + result);
receiveBytes = new byte[1024];
result = deviceConnection.bulkTransfer(usbEpIn, receiveBytes, receiveBytes.length, 3000);
Log.e(TAG, "接受状态码:" + result);
Log.e(TAG, receiveBytes[0] + "" );
deviceConnection.releaseInterface(usbInterface);
}
}).start();
}
});
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, intent.getAction());
if (intent.getAction().equals(ACTION_USB_PERMISSION)) {
boolean granted = intent.getExtras().getBoolean(UsbManager.EXTRA_PERMISSION_GRANTED);
Log.e("granted", granted + "");
}
}
};
//取消广播
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(broadcastReceiver);
}
}