Android 开源一个USB读写demo,从多个USB设备中选择一个实现外设控制的通信

news/2024/11/29 9:35:12/

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();方法获取,例如我的运行截图
在这里插入图片描述


http://www.ppmy.cn/news/1588.html

相关文章

秒懂数据结构之Map _ Set ,竟如此简单

Map、Set 文章目录 前言一、Map、Set的初步理解二、Map、Set的CURD方法的实现三、Map、Set的遍历总结前言 Set和Map天然就是高效搜索/查找的语义在这里我为什么将这两个集合分别列举比较呢&#xff1f;希望通过我的这篇博客可以增进大家对Map和Set的认识&#xff01;一、Map、…

jsp儿童网站系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 jsp 儿童网站系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开 发&#xff0c;数据库为Mysql&#xff0c;使用ja…

Java实验七

文章目录前言一、判断E盘指定目录下是否有后缀名为.jpg的文件&#xff0c;如果有就输出此文件名称。二、分别使用字节流和字节缓冲流的两种读取方式实现对图片文件的复制操作并比较两种方式在复制时间上的效率。三、编写一个程序&#xff0c;分别使用转换流、字符流和缓冲字符流…

Linux开发常用ps命令选项详解

【摘要】本文介绍了在Linux应用/内核开发调试中&#xff0c;经常需要用到的两个选项组合&#xff0c;当然&#xff0c;如果你需要查看更多更详尽的选项说明&#xff0c;可以参考man说明文档&#xff0c;即命令行下输入man ps进行查看。 aux选项组合 使用场景&#xff1a;更多…

uImage的制作过程详解

1、uImage镜像介绍 参考博客&#xff1a;《vmlinuz/vmlinux、Image、zImage与uImage的区别》&#xff1b; 2、uImage镜像的制作 2.1、mkimage工具介绍 参考博客&#xff1a;《uImage的制作工具mkimage详解(源码编译、使用方法、添加的头解析、uImage的制作)》&#xff1b; 2.2…

MySQL日志管理、备份与恢复

一.MySQL 日志管理 MySQL 的日志默认保存位置为 /usr/local/mysql/data MySQL 的日志配置文件为/etc/my.cnf &#xff0c;里面有个[mysqld]项 修改配置文件&#xff1a; vim /etc/my.cnf [mysqld] 1、错误日志 错误日志&#xff0c;用来记录当MySQL启动、停止或运行时发生…

简洁自增ID实现方案

简介 从数据库性能角度考虑&#xff0c;我们经常需要数字型的自增主键&#xff0c;有时候我们并不想用像MySQL自带的自增&#xff0c;因为从1开始很数据位数不一样&#xff0c;对有点强迫症的人来说&#xff0c;不是很友好。 另外&#xff0c;别人也容易根据这种从1开始的自增…

C语言Socket编程,实现两个程序间的通信

文章目录server和client通信流程图实现两个程序间的通信1.服务端server2.客户端client3.怎么运行呢&#xff1f;4.重写代码已剪辑自: https://www.cnblogs.com/fisherss/p/12085123.html server和client通信流程图 在mooc上找到的,使用Socket客户端client和服务端server通信的…