Android AOA协议Android端 流程总结
源文: http://www.codes51.com/article/detail_4282884_1.html
上篇文章中我们了解了嵌入式设备端将Android手机设置为accessory模式的流程以及嵌入式设备端接收和发送数据的流程,本文将对应介绍Android端accessory模式被激活的过程,以及接下来如何与嵌入式设备端进行通信。本文的源码下载地址:https://git.oschina.net/vonchenchen/aoa_android.git
实现
USBConnStatusManager 底层启动accessory模式
Android系统api通过UsbManager类管理usb相关,这里我们关注一下与accessory模式相关的内容。
当设备端启动android的accessory模式时,系统将会发送一条广播,设备拔出时也会发送一条广播,同时还有一条申请usb使用权限的广播。所以,要做的第一步就是动态注册这些广播,并编写一个广播接收者来处理对应的事件。这里对于的方法我们封装到了USBConnStatusManager类中,用来管理accessory相关连接。
IntentFilter filter = new IntentFilter();//接收权限信息filter.addAction(ACTION_USB_PERMISSION);//接收accessory连接事件filter.addAction(UsbManager.ACTION_USB_ACCESSORY_ATTACHED);//接收accessory断开事件filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);getContext().registerReceiver(mUsbReceiver, filter);
下面是对应的广播接收者,这里其实只需要监听两个广播,一个是获取usb权限,一旦这个广播发出我们就可以认为设备现在正在启动手机的accessory模式,第一次连接时手机会弹出对话框,让我们选择是否运行usb权限,另外一个就是需要在usb断开时做出反应,告诉设备连接已经断开了。下面是处理广播事件的过程:
mUsbReceiver =new BroadcastReceiver() {@Overridepublicvoid onReceive(Context context, Intent intent) {String action = intent.getAction();Log.i(TAG, "receive usb connect broadcast:"+ action);if (ACTION_USB_PERMISSION.equals(action)) {synchronized (this) {//UsbAccessory accessory = UsbManager.getAccessory(intent);UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);//获取accessory句柄成功if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {Log.d(TAG, "prepare to open usb stream");sCurStatus = STATUS_CONN_OK;mUsbAccessory = accessory;if (mOnUSBConnStatusChanged !=null) {mOnUSBConnStatusChanged.onUSBConnect(accessory);}} else {Log.d(TAG, "permission denied for accessory "+ accessory);sCurStatus = STATUS_CONN_ERR;mUsbAccessory =null;if (mOnUSBConnStatusChanged !=null) {mOnUSBConnStatusChanged.onUSBConnectFailed(accessory);}}}} elseif (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);//if (accessory != null && accessory.equals(mAccessory)) {//检测到usb断开Log.d(TAG, "USB_ACCESSORY_DETACHED "+ accessory);sCurStatus = STATUS_DISCONN;mUsbAccessory =null;//closeAccessory();//synchronized (USBConnStatusManager.class) {if (mOnUSBConnStatusChanged !=null) {mOnUSBConnStatusChanged.onUSBDisconnect(accessory);}//}//}}}};
这里拿到accessory的引用以后就可以用这个引用获取usb的读写流,然后将accessory交给外部接口,由外部类处理数据的具体读写内容。如果接收到设备拔出广播,则手动释放引用,更新连接状态。
另外,如果设备已经插入并且处于accessory模式,广播接受者并不会调用,这时可以同步开启设备。可以检查mUsbManager.getAccessoryList(),如果有accessory设备则可以直接获取设备引用。由于一般手机都只有一个U口,此处默认只要有一个accessory连接就是我们的设备。下面代码用于同步开启已经存在的于accessory表中的设备:
publicvoidcheckUSBDevice() {UsbAccessory[] accessories = mUsbManager.getAccessoryList();if(accessories == null){Log.i(TAG, "accessories list is null");return;}Log.i(TAG, "accessories length "+accessories.length);UsbAccessory accessory = (accessories == null ? null : accessories[0]);if (accessory != null) {if (mUsbManager.hasPermission(accessory)) {sCurStatus = STATUS_CONN_OK;mUsbAccessory = accessory;//synchronized (USBConnStatusManager.class) {if (mOnUSBConnStatusChanged != null) {mOnUSBConnStatusChanged.onUSBConnect(accessory);}//}} else {//synchronized (mUsbReceiver) {if (!mPermissionRequestPending) {mUsbManager.requestPermission(accessory, mPermissionIntent);mPermissionRequestPending = true;}//} }}}
USBHelper 具体操作usb的开关和读写等功能
USBHelper类具体操作usb的功能,这个类中持有USBConnStatusManager的单例对象,有了USBConnStatusManager就可以拿到accessroy,通过USBConnStatusManager获取到读写流,这个类就是在外层调用USBConnStatusManager方法,对usb进行操作。
openAsync
这个方法用来开启usb,首先注册广播接收者回调,用来检测usb插拔信息,注册完毕后检查当前系统中存在的accessory设备,如果已经连接了accessroy设备,则直接获取其accessroy的引用,通过这个引用获取读写流,者就是usb的打开过程。
/*** accessory模式打开android的 usb设备* 如果当前列表有处于accessory模式的句柄则直接打开* 如果当前没有则回监听usb插拔,监听到对应事件后检查系统列表* @param onUSBConnStatusChanged*/@OverridepublicvoidopenAsync(final OnUSBConnStatusChanged onUSBConnStatusChanged) {mReciveBuffer = newbyte[RECIVE_BUF_SIZE];//注册USB连接状态监听mUSBConnStatusManager.registOnUSBConnStatusChangedListener(new OnUSBConnStatusChanged() {@OverridepublicvoidonUSBConnect(UsbAccessory accessory) {openAccessory(accessory);if (onUSBConnStatusChanged != null) {onUSBConnStatusChanged.onUSBConnect(accessory);}}@OverridepublicvoidonUSBConnectFailed(UsbAccessory accessory) {closeAccessory();if (onUSBConnStatusChanged != null) {onUSBConnStatusChanged.onUSBConnectFailed(accessory);}}@OverridepublicvoidonUSBDisconnect(UsbAccessory accessory) {closeAccessory();if (onUSBConnStatusChanged != null) {onUSBConnStatusChanged.onUSBDisconnect(accessory);}}});//检查usb列表 查看是否已经连接accessory设备mUSBConnStatusManager.checkUSBDevice();}/*** 通过accessory句柄拿到usb设备的输入输出流* @param accessory*/privatevoidopenAccessory(UsbAccessory accessory) {mFileDescriptor = mUsbManager.openAccessory(accessory);if (mFileDescriptor != null) {mAccessory = accessory;FileDescriptor fd = mFileDescriptor.getFileDescriptor();//usb读写流mInputStream = new FileInputStream(fd);mOutputStream = new FileOutputStream(fd);if (mOnDataTranPrepared != null) {Log.d(TAG, "accessory opened DataTranPrepared");mOnDataTranPrepared.onDataTranPrepared(mInputStream, mOutputStream);}Log.d(TAG, "accessory opened");} else {Log.d(TAG, "accessory open fail");}}
另外这个类还提供了usb数据读写和关闭设备等方法,大家可以参考项目源码。
SimpleTcpWrapper 封装上层通信协议
打通底层数据通道,下面就是封装我们自己协议了,在项目中使用tcp头简单封装了一个协议,可以实现三次握手,数据包通过序列号校验以及根据不同端口分发数据的功能。本章只讨论Android设备底层通信的实现,所以删除了协议部分,只是将usb发送过来的数据原样发送回去。
SimpleTcpWrapper中创建一个USBHelper对象用来管理usb数据通信,调用openAsync异步打开数据。一旦数据连接成功,我们就是开启一个数据接收线程,读取这个accessory的inputstream,一旦收到数据就将数据写入accessory的outputstrem中。
Android AOA协议Android端 流程总结相关推荐
- Android usb学习笔记:Android AOA协议Android端 流程总结
背景 上篇文章中我们了解了嵌入式设备端将Android手机设置为accessory模式的流程以及嵌入式设备端接收和发送数据的流程,本文将对应介绍Android端accessory模式被激活的过程,以及 ...
- Android USB的AOA协议设备端(主机模式,配件模式),ADB连接
USB的ADB/AOA协议(一种是ADB模式,一种是AOA模式).AOA协议是Google公司推出的用于实现Android设备与外围设备之间USB通信的协议. ADK中与USB配件模式相关的两个类是U ...
- android 许可协议,Android 基本控件的使用二(注册许可协议)(CheckBox)
需要注意的是:按钮部分,在复选框选中之前是显示不可点击状态,一旦被选中之后就会变成可点击按钮. 为复选框设置的监听为:setOnCheckedChangeListener 实现的方法有两种: 方法一: ...
- android自定义协议,Android / iOS-自定义URI /协议处理
编辑5/2014,因为这似乎是一个受欢迎的问题,所以我在回答中添加了很多细节: Android: 对于Android,请单击单击自定义URI时,请参阅意图过滤器以启动我的活动. 您使用一个意图过滤器: ...
- Android onvif协议 服务端
先做个大致分析:这篇文章是把Android设备当做摄像机,通过onvif协议,可以让nvr进行访问,传输rtsp流. 先说下我的思路:第一步:先看文档,了解到onvif协议是通过http建立的连接.第 ...
- android spp协议,Android蓝牙开发SPP协议通信
最近项目中使用到蓝牙SPP协议通信,然后在网上看了很多资料,进行学习使用,为了加深印象,做个简单的整理. 1.使用蓝牙权限< uses-permission android:name=" ...
- android蓝牙协议,Android蓝牙协议-蓝牙扫描 startDiscovery
蓝牙开启位于setting中,即 package:com.android.settings.bluetooth BluetoothSettings.java 中. 菜单选项MENU_ID_SCAN: ...
- Andriod AOA协议通信总结
Andriod AOA协议通信总结 Android从3.1版本可开始引进了对 AOA协议 ( Android Open Accessory Protocol) 的支持,这是一种允许外部USB硬件与An ...
- 【Android RTMP】Android Camera 视频数据采集预览 ( 图像传感器方向设置 | Camera 使用流程 | 动态权限申请 )
文章目录 安卓直播推流专栏博客总结 一. Camera 传感器方向简介 二. Camera 图像传感器横向显示数据 三. Camera 图像传感器纵向显示数据 四. 设置 Camera 预览数据方向 ...
最新文章
- c语言返回一个数的任意倍数,几道基础C语言题
- 批量复制文件名-修改文件路径小工具
- oracle百万级数据导入,用Perl从oracle导出百万级数据到excel
- Tomcat执行start文件后有乱码
- HashMap的key可以是可变的对象吗???
- DVWA教程实践之Brute Force
- word 插入公式技巧
- 怎么用html创建表格,HTML创建表格
- Exp3 免杀原理与实践 20154328 常城
- UC刘兰奇极速版制动刷金币
- 内存屏障 Memery Barrier
- DI高速计数器编码器脉冲计数器PNPNPN输入模块高低电平
- JS面向对象/继承/原型链/this指向/call方法
- html5单位转换器,液体单位在线换算工具
- 安全、智慧是 Oppo 快充技术最新的发展方向
- FineReport 填报报表数据自定义提交
- 7-1 验证哥德巴赫猜想
- 员工与客户之间就是一个微信
- 智能车竞赛技术报告 | 全向行进组 - 东北林业大学- 进取号E
- Nginx入门与实践