CSDN 下载链接https://download.csdn.net/download/gao511147456/87226599(可0积分免费下载)
如果你不想下载可以阅读下面教程并复制代码到自己的项目中
这是我插拔USB的运行视频
device-2022-11-27-231324
AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"package="com.rongzl.usbdemo"><!-- 添加1 --><uses-feature android:name="android.hardware.usb.host" android:required="true"/><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.USBdemo"tools:targetApi="31"><activityandroid:name=".MainActivity"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /><!-- 添加2 --><action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /></intent-filter><!-- 添加3 --><meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"android:resource="@xml/device_filter" /></activity></application></manifest>
MainActivity
private static final String TAG = "MainActivity";private UsbManager mUsbManager;private UsbDevice mDevice;private UsbInterface inft;private AppCompatButton btSend;private UsbEndpoint mEndpointIN;private UsbEndpoint mEndpointOUT;private UsbDeviceConnection mUsbConnection;private TextView mTextView;private TextView mTextViewDeviceStatus;private TextView mTextViewDeviceInfo;
初始USB端口
mDevice.getProductName().startsWith(“USB2.0-Ser”)方法筛选了我的USB端口,如果不做这一步,会误连接到相机等USB设备
@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mTextView = findViewById(R.id.tv_usb_msg);mTextViewDeviceStatus = findViewById(R.id.tv_usb_status);mTextViewDeviceInfo = findViewById(R.id.tv_usb_info);btSend = findViewById(R.id.bt_send);btSend.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {sendMsg(view);}});UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);String ACTION_USB_PERMISSION ="com.android.example.USB_PERMISSION";String ACTION_USB_DEVICE_DETACHED = "android.hardware.usb.action.USB_DEVICE_DETACHED";PendingIntent permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);PendingIntent permissionIntent1 = PendingIntent.getBroadcast(this, 12, new Intent(ACTION_USB_DEVICE_DETACHED), 0);IntentFilter filter1 = new IntentFilter(ACTION_USB_DEVICE_DETACHED);registerReceiver(usbPerMissionReceiver, filter);registerReceiver(usbDetachedReceiver, filter1);mUsbManager = (UsbManager) this.getSystemService(Context.USB_SERVICE);HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();while (deviceIterator.hasNext()) {mDevice = deviceIterator.next();//因为只有一个设备插入,所以直接获取该设备的接口及端点//请求访问/连接usb设备的权限if (mDevice.getProductName().startsWith("USB2.0-Ser")){mUsbManager.requestPermission(mDevice, permissionIntent);inft = mDevice.getInterface(0);Log.d(TAG,"Interface Count:" + mDevice.getInterfaceCount());int endpointCount = inft.getEndpointCount();for (int i = 0; i < endpointCount; i++) {if (inft.getEndpoint(i).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {if (inft.getEndpoint(i).getDirection() == UsbConstants.USB_DIR_IN) {mEndpointIN = inft.getEndpoint(i);Log.d(TAG, "获取到mEndpointIN");} else if (inft.getEndpoint(i).getDirection() == UsbConstants.USB_DIR_OUT) {mEndpointOUT = inft.getEndpoint(i);Log.d(TAG, "获取到mEndpointOUT");}}}}}}
数据接收广播
private static final String ACTION_USB_PERMISSION ="com.android.example.USB_PERMISSION";private final BroadcastReceiver usbPerMissionReceiver = new BroadcastReceiver() {public void onReceive(Context context, Intent intent) {Log.d(TAG, "onReceive");String action = intent.getAction();if (ACTION_USB_PERMISSION.equals(action)) {synchronized (this) {if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {//获取连接权限成功mDevice = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);if (mDevice != null) {//打开设备mUsbConnection = mUsbManager.openDevice(mDevice);mUsbConnection.claimInterface(inft,true);if (mUsbConnection != null) {Log.d(TAG, "连接设备成功");runOnUiThread(new Runnable() {@Overridepublic void run() {mTextViewDeviceInfo.setText(mDevice.toString());mTextViewDeviceStatus.setText("连接设备成功");}});}//开启接收数据线程if (myThread==null){//设置波特率Log.d(TAG, "Start the thread");configUsb(9600);myThread = new MyThread();myThread.start();sendMsg(null);}}} else {runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(MainActivity.this,"访问权限被拒绝",Toast.LENGTH_SHORT);}});//Log.d(TAG, "访问权限被拒绝 " + mDevice);}}}}};
设置波特率
paramInt 为usb 波特率值
private boolean configUsb(int paramInt) {byte[] arrayOfByte = new byte[8];mUsbConnection.controlTransfer(192, 95, 0, 0, arrayOfByte, 8, 1000);mUsbConnection.controlTransfer(64, 161, 0, 0, null, 0, 1000);long l1 = 1532620800 / paramInt;for (int i = 3; ; i--) {if ((l1 <= 65520L) || (i <= 0)) {long l2 = 65536L - l1;int j = (short) (int) (0xFF00 & l2 | i);int k = (short) (int) (0xFF & l2);mUsbConnection.controlTransfer(64, 154, 4882, j, null, 0, 1000);mUsbConnection.controlTransfer(64, 154, 3884, k, null, 0, 1000);mUsbConnection.controlTransfer(192, 149, 9496, 0, arrayOfByte, 8, 1000);mUsbConnection.controlTransfer(64, 154, 1304, 80, null, 0, 1000);mUsbConnection.controlTransfer(64, 161, 20511, 55562, null, 0, 1000);mUsbConnection.controlTransfer(64, 154, 4882, j, null, 0, 1000);mUsbConnection.controlTransfer(64, 154, 3884, k, null, 0, 1000);mUsbConnection.controlTransfer(64, 164, 0, 0, null, 0, 1000);return true;}l1 >>= 3;}}
轮询读线程
如果影响性能记得增加延时设置执行频率例如“SystemClock.sleep(1000);
”
MyThread myThread;public void sendMsg(View view) {Log.i(getClass().getSimpleName(),"sendMsgClick");sendMessage("updataTem");}public class MyThread extends Thread {private boolean isReceive = true;String message = null;byte[] bytes = new byte[5];@Overridepublic void run() {super.run();while (isReceive) {int i = mUsbConnection.bulkTransfer(mEndpointIN, bytes, 0, bytes.length, 3000);if(i < 0){// Log.d(TAG,"没有收到数据。。。");}else{try {message = new String(bytes,"UTF-8");Log.d(TAG, "接收到数据:" + message);runOnUiThread(new Runnable() {@Overridepublic void run() {mTextView.setText(message);}});isReceive = false;} catch (UnsupportedEncodingException e) {e.printStackTrace();}}SystemClock.sleep(1000);}}}
发送数据方法封装
private void sendMessage(String msg) {byte[] bytes = msg.getBytes();Log.d(TAG, "mUsbConnection-->msg length: "+bytes.length+";"+mEndpointOUT.getMaxPacketSize());if (mUsbConnection != null) {int result = mUsbConnection.bulkTransfer(mEndpointOUT, bytes, bytes.length, 3000);if (result < 0) {Log.d(TAG, "发送失败");} else {Log.d(TAG, "发送成功"+msg);}} else {Log.d(TAG, "mUsbConnection-->null");}}
断开USB 监听广播(可选)
BroadcastReceiver usbDetachedReceiver = new BroadcastReceiver() {public void onReceive(Context context, Intent intent) {String action = intent.getAction();if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);if (device != null) {mUsbConnection.releaseInterface(inft);mUsbConnection.close();runOnUiThread(new Runnable() {@Overridepublic void run() {mTextViewDeviceStatus.setText("设备已断开连接");mTextViewDeviceInfo.setText("请重启连接设备");}});}}}};
device_filter
<?xml version="1.0" encoding="utf-8"?>
<resource xmlns:android="http://schemas.android.com/apk/res/android"><usb-device vendor-id="6790" product-id="29987" class="255" subclass="0" protocol="0" />
</resource>
上面的值可以通过打印mDevice.toString();方法获取,例如我的运行截图