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表示全…...
Wan2.2-I2V-A14B企业级部署案例:单卡24GB显存实现高并发视频API服务
Wan2.2-I2V-A14B企业级部署案例:单卡24GB显存实现高并发视频API服务 1. 企业级视频生成解决方案概述 在数字内容创作领域,视频生成技术正经历革命性变革。Wan2.2-I2V-A14B作为新一代文生视频模型,通过私有化部署方案,为企业提供…...
Python安全开发之简易Xss检测工具(详细注释)
核心代码:import requests # requests 库 - HTTP 请求处理库 # 【常用功能】: # requests.get(url) - 发送 HTTP GET 请求 # requests.post(url, data) - 发送 HTTP POST 请求 # response.text - 获取响应体内容(字符串) #…...
别再只盯着EMD了!滚动轴承故障诊断,试试VMD和MCKD这些新方法(附Python代码对比)
滚动轴承故障诊断:VMD与MCKD的实战对比与Python实现 滚动轴承作为旋转机械的核心部件,其健康状态直接影响设备运行安全。传统经验模态分解(EMD)虽广泛应用,但在处理强噪声和非平稳信号时存在明显局限。本文将深入解析变…...
Phi-4-mini-reasoning部署教程:Nginx反向代理+Basic Auth安全加固
Phi-4-mini-reasoning部署教程:Nginx反向代理Basic Auth安全加固 1. 项目介绍 Phi-4-mini-reasoning是一款由微软开源的轻量级AI模型,专注于数学推理、逻辑推导和多步解题等强逻辑任务。这个3.8B参数的模型虽然体积小巧,但在推理能力上表现…...
别再手动调时间了!手把手教你用LinuxPTP的ptp4l和phc2sys搞定TSN网络时钟同步
工业TSN网络高精度时钟同步实战:从原理到生产环境部署 在工业自动化、智能驾驶和实时音视频传输领域,微秒级的时间同步已成为刚需。传统NTP协议毫秒级的精度在这些场景下显得力不从心,而基于IEEE 1588和802.1AS协议的PTP(精确时间…...
智能电网RAG优化:闭环协同与精准检索
RAG论文原理解析、公式含义与错误点对点修正方案 一、论文核心原理详细解析(含场景举例) 本文针对通用RAG框架在术语密集、强监管垂直领域(智能电网)的三大原生适配瓶颈,提出了** RAG领域原生闭环协同RAG范式**,核心是将智能电网领域知识嵌入检索-生成-评估全生命周期,…...
2026硬核对比:Claude 4.6官网双版本解析与Gemini 3.1 Pro镜像如何选
对于追求极致编码质量与深度推理的开发者与技术决策者,2026年Anthropic推出的Claude 4.6系列(含旗舰Opus与高性价比Sonnet)在智能体(Agent)能力与长上下文处理上树立了新标杆。 若想在国内网络环境下零成本深度对比其…...
【HALCON实战】set_window_param:解锁图形窗口高级定制与性能调优
1. 为什么你需要掌握set_window_param? 在机器视觉项目开发中,图形窗口就像工程师的眼睛。我见过太多同行把90%的精力花在算法优化上,却忽视了窗口显示这个"最后一公里"问题。直到某次在客户现场演示时,程序因为频繁刷新…...
C++程序发生崩溃闪退后为什么会自动重启?是因为程序中启用了重启管理器,系统感知到程序异常退出后自动重启程序
最近在使用sdkdemo程序测试我们的SDK功能时,发现当我们关闭程序后(程序确实关闭了),程序居然又自动启动起来了!后来运行Debug版本的sdkdemo,在关闭程序时会弹出报错提示框:估计是程序在退出时产…...
ArcGIS Pro脚本工具实战:一键自动化面要素数据质量检查与修复
1. 为什么需要自动化面要素质检工具 在GIS数据处理工作中,面要素的质量检查是个绕不开的痛点。我做过不少国土调查和城市规划项目,每次拿到甲方提供的原始数据,光是检查拓扑错误就得花上大半天。传统的手动检查流程有多繁琐呢?你得…...
