Android usb 配件模式通信示例
当使用 Android 设备作为 USB 配件时,可以使用 Android 提供的 USB Accessory API 来进行 USB 通信。以下是一个简单的 Android USB 配件模式的通信例子。在本例中,我们将接收连接到 Android 设备的 USB 主机发送的数据并向 USB 主机发送响应。
首先,在 AndroidManifest.xml 文件中添加以下权限:
<uses-feature android:name="android.hardware.usb.accessory" />
<uses-permission android:name="android.permission.ACCESSORY" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
接着,在 res/xml 文件夹中创建一个名为 accessory_filter.xml 的文件,用于指定 USB 配件的属性及其应用程序的信息。以下是示例文件的内容:
<?xml version="1.0" encoding="utf-8"?>
<resources><usb-accessory model="Android Accessory" manufacturer="Android" version="1.0" />
</resources>
在 Activity 中,添加以下代码:
private static final String TAG = "USBAccessoryDemo";private static final String ACTION_USB_PERMISSION = "com.example.android.usbaccessory.USB_PERMISSION";
private static final int TIMEOUT = 1000;
private static final int MAX_PACKET_SIZE = 16384;private UsbAccessory mAccessory;
private UsbManager mUsbManager;
private PendingIntent mPermissionIntent;
private boolean mPermissionRequestPending;
private UsbAccessoryConnection mAccessoryConnection;@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);registerReceiver(mUsbReceiver, filter);HashMap<String, UsbAccessory> accessoryList = mUsbManager.getAccessoryList();if (accessoryList != null) {UsbAccessory accessory = accessoryList.get(0);if (accessory != null) {if (mUsbManager.hasPermission(accessory)) {openAccessory(accessory);} else {mUsbManager.requestPermission(accessory, mPermissionIntent);mPermissionRequestPending = true;}} else {Log.d(TAG, "accessory is null");}} else {Log.d(TAG, "accessoryList is null");}
}@Override
public void onResume() {super.onResume();if (mAccessoryConnection != null && mAccessoryConnection.isOpen()) {mAccessoryConnection.startReading();}
}@Override
public void onPause() {super.onPause();if (mAccessoryConnection != null && mAccessoryConnection.isOpen()) {mAccessoryConnection.stopReading();}
}@Override
protected void onDestroy() {super.onDestroy();unregisterReceiver(mUsbReceiver);if (mAccessoryConnection != null && mAccessoryConnection.isOpen()) {mAccessoryConnection.close();}
}private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {public void onReceive(Context context, Intent intent) {String action = intent.getAction();if (ACTION_USB_PERMISSION.equals(action)) {synchronized (this) {UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {openAccessory(accessory);} else {Log.d(TAG, "permission denied for accessory " + accessory);}mPermissionRequestPending = false;}}}
};private void openAccessory(UsbAccessory accessory) {mAccessoryConnection = new UsbAccessoryConnection(this, accessory);mAccessoryConnection.open();
}private class UsbAccessoryConnection implements Runnable {private final UsbManager mUsbManager;private final UsbAccessory mAccessory;private UsbDeviceConnection mConnection;private UsbEndpoint mInEndpoint;private UsbEndpoint mOutEndpoint;private InputStream mInputStream;private OutputStream mOutputStream;private Thread mReadThread;private boolean mIsRunning;public UsbAccessoryConnection(Context context, UsbAccessory accessory) {mUsbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);mAccessory = accessory;}public void open() {mConnection = mUsbManager.openAccessory(mAccessory);if (mConnection != null) {mInEndpoint = mAccessory.getEndpoint(0);mOutEndpoint = mAccessory.getEndpoint(1);mInputStream = new BufferedInputStream(mConnection.openInputStream(mInEndpoint), MAX_PACKET_SIZE);mOutputStream =new BufferedOutputStream(mConnection.openOutputStream(mOutEndpoint), MAX_PACKET_SIZE);mIsRunning = true;mReadThread = new Thread(this);mReadThread.start();} else {Log.d(TAG, "openAccessory failed");}}public void close() {mIsRunning = false;if (mReadThread != null) {try {mReadThread.join();} catch (InterruptedException e) {e.printStackTrace();}}if (mInputStream != null) {try {mInputStream.close();} catch (IOException e) {e.printStackTrace();}}if (mOutputStream != null) {try {mOutputStream.close();} catch (IOException e) {e.printStackTrace();}}if (mConnection != null) {mConnection.close();}}public boolean isOpen() {return mConnection != null;}public void startReading() {if (mReadThread != null && !mReadThread.isAlive()) {mIsRunning = true;mReadThread = new Thread(this);mReadThread.start();}}public void stopReading() {mIsRunning = false;}public void write(byte[] data) {if (mOutputStream != null) {try {mOutputStream.write(data);mOutputStream.flush();} catch (IOException e) {e.printStackTrace();}}}@Overridepublic void run() {byte[] buffer = new byte[MAX_PACKET_SIZE];while (mIsRunning) {try {int len = mInputStream.read(buffer);if (len > 0) {final String receivedData = new String(buffer, 0, len);runOnUiThread(new Runnable() {@Overridepublic void run() {// 处理接收到的数据}});}} catch (IOException e) {e.printStackTrace();mIsRunning = false;}}}
}
在上面的代码中,我们首先检查是否已连接 USB 配件。如果已连接,则尝试打开连接。如果没有权限,则请求权限。如果没有可用的 USB 配件,则在日志中记录错误消息。
在打开连接后,我们创建一个 UsbAccessoryConnection 对象,并使用 open() 方法打开连接。在 open() 方法中,我们获取连接的 UsbDeviceConnection 对象,并使用它来获取读取和写入数据的输入/输出流。我们还启动了一个读线程,该线程不断地从输入流中读取数据,并将其传递给主线程以进行处理。
最后,我们可以使用 write() 方法向 USB 主机发送数据,并使用 close() 方法关闭连接。
以上就是Android usb 配件模式下的示例,在实际的开发过程中会比较复杂,但原理基本类似。如果文档对你有帮助,欢迎点赞、收藏和评论,谢谢!
相关文章:
Android usb 配件模式通信示例
当使用 Android 设备作为 USB 配件时,可以使用 Android 提供的 USB Accessory API 来进行 USB 通信。以下是一个简单的 Android USB 配件模式的通信例子。在本例中,我们将接收连接到 Android 设备的 USB 主机发送的数据并向 USB 主机发送响应。 首先&am…...

【Hive实战】Hive的压缩池与锁
文章目录 Hive的压缩池池的分配策略自动分配手动分配隐式分配 池的等待超时Labeled worker pools 标记的工作线程(自定义线程池)Default pool 默认池Worker allocation 工作线程的分配 锁Turn Off ConcurrencyDebuggingConfigurationhive.support.concur…...
【VUE】使用elementUI tree组件根据所选id自动回显
需求如下: 1.点击父级节点 将父级节点下children中所有id放入数组 2.点击父级下的子节点 将点击的子节点放入数组 3.取消选择父节点,将放入数组的所有子节点id删除 4.根据选择的子节点数组,匹配他所属的父节点 <el-tree:data"tre…...

RocketMQ, Dashboard, 控制台安装
文章说明 本文主要说明RocketMQ的控制台(Dashboard)的安装过程。工作中一直用的是别人装好的,这次终于自己亲手装了一遍。 由于每次都要启动三个应用,比较烦,于是我写了一键启动脚本,分享给大家。这个脚本…...

chrome解决http自动跳转https问题
1.地址栏输入: chrome://net-internals/#hsts 2.找到底部Delete domain security policies一栏,输入想处理的域名,点击delete。 3.再次访问http域名不再自动跳转https了。...
FastGithub 下载
Releases dotnetcore/FastGithub GitHub 无需安装,双击UI程序即可运行。...

TSINGSEE青犀视频安防监控管理平台EasyNVR如何配置鉴权?
视频监控汇聚平台EasyNVR是基于RTSP/Onvif协议的视频平台,可支持将接入的视频流进行全平台、全终端的分发,分发的视频流包括RTSP、RTMP、HTTP-FLV、WS-FLV、HLS、WebRTC等格式。为了满足用户的集成与二次开发需求,我们也提供了丰富的API接口供…...

unittest 数据驱动DDT应用
前言 一般进行接口测试时,每个接口的传参都不止一种情况,一般会考虑正向、逆向等多种组合。所以在测试一个接口时通常会编写多条case,而这些case除了传参不同外,其实并没什么区别。 这个时候就可以利用ddt来管理测试数据…...
素数个数——数论
题目描述 求 1,2,⋯,N 中素数的个数。 输入格式 一行一个整数 N。 输出格式 一行一个整数,表示素数的个数。 样例 #1 样例输入 #1 10样例输出 #1 4提示 对于 100% 的数据,1≤1081≤N≤108。 本题时间限制在2秒以内。 因为题目时间限制是2秒,所…...

express编写一个简单的get接口
/01编写get接口.jsconst express require(express) const app express()// 创建路由 const useRouter require(./router/user.js) // 注册路由 app.use(/api,useRouter)app.listen(8080, (req, res) > {console.log(8080监听) }) ./02编写post接口 // 注意:如…...
【力扣刷题C++】环形链表
来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/linked-list-cycle 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 【题目】给你一个链表的头节点 head ,判断链表中是否有…...

如何用Python统计CSDN质量分
文章目录 CSDN质量分查询selenium爬取博客地址单篇测试批量查询分析 CSDN质量分查询 CSDN对博客有一套分数评价标准,其查询入口在这里:质量分查询,效果大致如下 如果质量分太低,就会在博文的标题下面出现黄底黄字: 这…...

gin框架内容(三)--中间件
gin框架内容(三)--中间件 Gin框架允许开发者在处理请求的过程中,加入用户自己的函数。这个函数就叫中间件,中间件适合处理一些公共的业务逻辑,比如登录认证、权限校验、数据分页、记录日志、耗时统计等 即比如&#x…...

如何在工作中利用Prompt高效使用ChatGPT
导读 AI 不是来替代你的,是来帮助你更好工作。用better prompt使用chatgpt,替换搜索引擎,让你了解如何在工作中利用Prompt高效使用ChatGPT。 01背景 现在 GPT 已经开启了人工智能狂潮,不过是IT圈,还是金融圈。 一开…...

uniapp-小程序button分享传参,当好友通过分享点开该页面时,进行一些判断……
一、需求描述: 该小程序中,点击圈子列表页面—>进入圈子详情页面,在圈子详情页面点击button分享按钮后,发送给好友。当好友通过分享点开该页面时: 1.先判断是否登录,如果没有,先去登录&#…...

Ceph部署方法介绍
Ceph部署方法介绍 Installing Ceph — Ceph Documentation Ceph环境规划 admin是一个部署节点...

GoogleLeNet V2 V3 —— Batch Normalization
文章目录 Batch Normalizationinternal covariate shift激活层的作用BN执行的位置数据白化网络中的BN层训练过程 BN的实验效果MNIST与GoogleLeNet V1比较 GoogleLeNet出来之后,Google在这个基础上又演进了几个版本,一般来说是说有4个版本,之前…...

Mac 系统钥匙串证书不受信任
Mac 系统钥匙串证书不受信任 解决办法 通过尝试安装 Apple PKI 的 Worldwide Developer Relations - G4 (Expiring 12/10/2030 00:00:00 UTC) 解决该异常问题 以上便是此次分享的全部内容,希望能对大家有所帮助!...

一个企业级的文件上传组件应该是什么样的
目录 1.最简单的文件上传 2.拖拽粘贴样式优化 3.断点续传秒传进度条 文件切片 计算hash 断点续传秒传(前端) 断点续传秒传(后端) 进度条 4.抽样hash和webWorker 抽样hash(md5) webWorker 时间切片 5.文件类型判断 通过文件头判断文件类型 6.异步并发数控制(重要…...
安全渗透重点内容
this是js中的一个关键字,在不同的场合使用,this的值会发生变化,下面我将详细的介绍this在函数中的各种指向。 在方法中,this表示该方法所属的对象。 如果单独使用,this表示全局对象。 在函数中,this表示全…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...

【PX4飞控】mavros gps相关话题分析,经纬度海拔获取方法,卫星数锁定状态获取方法
使用 ROS1-Noetic 和 mavros v1.20.1, 携带经纬度海拔的话题主要有三个: /mavros/global_position/raw/fix/mavros/gpsstatus/gps1/raw/mavros/global_position/global 查看 mavros 源码,来分析他们的发布过程。发现前两个话题都对应了同一…...

【QT控件】显示类控件
目录 一、Label 二、LCD Number 三、ProgressBar 四、Calendar Widget QT专栏:QT_uyeonashi的博客-CSDN博客 一、Label QLabel 可以用来显示文本和图片. 核心属性如下 代码示例: 显示不同格式的文本 1) 在界面上创建三个 QLabel 尺寸放大一些. objectName 分别…...
Linux中INADDR_ANY详解
在Linux网络编程中,INADDR_ANY 是一个特殊的IPv4地址常量(定义在 <netinet/in.h> 头文件中),用于表示绑定到所有可用网络接口的地址。它是服务器程序中的常见用法,允许套接字监听所有本地IP地址上的连接请求。 关…...
WEB3全栈开发——面试专业技能点P8DevOps / 区块链部署
一、Hardhat / Foundry 进行合约部署 概念介绍 Hardhat 和 Foundry 都是以太坊智能合约开发的工具套件,支持合约的编译、测试和部署。 它们允许开发者在本地或测试网络快速开发智能合约,并部署到链上(测试网或主网)。 部署过程…...