Android USB通信

xiaoxiao2021-02-28  139

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); } } 这里贴出所有代码,记住接收和发送信息的处理要在子线程中运行。

4.爬坑

刚刚开始做项目的时候,那叫一个酸爽,很多坑。首先要注意你是以那种方式通信,host还是accessory,然后再去Manifest里面添加相应的权限。其次明确你的传输方式,块传输还是控制传输,两个函数的参数都不一样,最后收发信息的处理逻辑最好放到子线程中运行,防止app挂掉

转载请注明原文地址: https://www.6miu.com/read-32676.html

最新回复(0)