Android小白usb通信入门篇(一)
16lz
2021-01-25
入门USB通信
- 一、Android USB开发模式
- 二、进入Hello World
- 1、 配置AndroidManifest.xml文件中usb模式
- 2、配置usb设备插入的通知和相关usb设备的过滤
- 3、android设备与USB设备连接和通信
前些日志去了一趟广州,老总对自动贩卖机有点想法,于是乎回来就开始查阅相关文档做好准备工作,这不记下自己的理解,如果大家有更好的理解,或者本人的一些介绍理解有错误或者偏差的地方,欢迎留言,大家一起共同进步!
一、Android USB开发模式
android 中usb有两种开发模式,一种是host模式,另一种是accessory模式,下面介绍一下这两种模式。
- Host模式:如图,此模式中,android设备充当主机,给usb外部设备供电,常见的Host模式有:鼠标、键盘、等。
- Accessory模式:如图,和Host模式相反,此模式中,usb设备充当主机,给android手机提供电源,常见的设备:无人机远程控制器等。
二、进入Hello World
1、 配置AndroidManifest.xml文件中usb模式
在android系统中,默认是关闭usb模式的,当我们将usb外部设备插入android设备时,android系统不回出任何响应。如果我们要打开系统usb模式,需要在android清单文件里使用
标签声明响应的usb模式
- Host模式
- accessory模式
2、配置usb设备插入的通知和相关usb设备的过滤
若我们希望在插入usb设备时,android系统能接收到提示性通知,则需要在android组件中配置
和 标签配置相关信息, 中配置我们要接收的相关类型的信息通知, 配置我们需要检测的指定的设备,标签内容对应一个xml资源文件,里面配置我们指定的usb设备。如下:
其中xml资源文件的配置如下:
<?xml version="1.0" encoding="utf-8"?>
3、android设备与USB设备连接和通信
无论是host模式还是accessory模式,在进行检测获取usb设备时,都需要用到UsbManager类,只是调用不同的方法而已。如下:
- host模式
1)获取UsbManager
2)通过usbManager获取连接到的usb外部设备
3)获取usb设备引用,通过usbManager检测是否有对应权限,若无则请求权限,通过广播接收权限信息获取情况。
4)与usb设备进行通信
public static final String action_usb_permission = "org.zhuhailong.myviewproject.permission"; public void hostModel(Context context) { //获取UsbManager UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE); //获取usb设备列表 HashMap deviceList = usbManager.getDeviceList(); Set> entries = deviceList.entrySet(); UsbDevice mUsbDevice = null; for (Map.Entry entry : entries) { UsbDevice value = entry.getValue(); String key = entry.getKey(); if (filterDevice(key, value)) {//判断是否使我们要连接的usb设备 mUsbDevice = value; break; } } if (usbManager.hasPermission(mUsbDevice)) {//检测是否有usb权限 requestPermission(mUsbDevice); } else { connect(mUsbDevice); } } /** * 请求usb权限 * @param usbManager * @param parcelable */ public void requestPermission(Parcelable parcelable,UsbManager usbManager) { UsbDevice usbDevice = (UsbDevice) parcelable; if (!usbManager.hasPermission(usbDevice)) { IntentFilter intentFilter = new IntentFilter(action_usb_permission); registerReceiver(mMyBroadcastReceiver, intentFilter); PendingIntent broadcast = PendingIntent.getBroadcast(this, 0, new Intent(action_usb_permission), 0); usbManager.requestPermission(usbDevice, broadcast); } else { Toast.makeText(context, "already have permission", Toast.LENGTH_SHORT).show(); } } } public boolean connect(UsbDevice mUsbDevice) { if (mUsbDevice != null) { UsbInterface anInterface = mUsbDevice.getInterface(0); mUsbDeviceConnection = mUsbManager.openDevice(mUsbDevice);//连接usb设备 if (mUsbDeviceConnection == null) { Toast.makeText(mContext, "mUsbDeviceConnection can't be null", Toast.LENGTH_SHORT).show(); return false; } if (mUsbDeviceConnection.claimInterface(anInterface, true)) { Toast.makeText(mContext, "找到USB接口", Toast.LENGTH_SHORT).show(); int endpointCount = anInterface.getEndpointCount(); for (int i = 0; i < endpointCount; i++) { UsbEndpoint endpoint = anInterface.getEndpoint(i); if (endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) { if (UsbConstants.USB_DIR_IN == endpoint.getDirection()) { mUsbEndpoint_in = endpoint;//获取读数据通道 } else { mUsbEndpoint_out = endpoint;//获取写数据通道 } } } return true; } else { mUsbDeviceConnection.close();//关闭连接 Toast.makeText(mContext, "找不到USB接口", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(mContext, "mUsbDevice can't be null", Toast.LENGTH_SHORT).show(); } return false; } /** * 从usb通信设备中读取数据 * @return */ public byte[] readData() { int inMax = mUsbEndpoint_in.getMaxPacketSize(); byte[] bytes = new byte[inMax]; ByteBuffer byteBuffer = ByteBuffer.allocate(inMax); UsbRequest usbRequest = new UsbRequest(); usbRequest.initialize(mUsbDeviceConnection, mUsbEndpoint_in); usbRequest.queue(byteBuffer, inMax); if (mUsbDeviceConnection.requestWait() == usbRequest) { bytes = byteBuffer.array(); } return bytes; } /** * 将数据写入到usb设备中 * @param bytes */ public void sendData(byte[] bytes) { if (mUsbDeviceConnection == null) { Toast.makeText(mContext, "mUsbDeviceConnection can't be null", Toast.LENGTH_SHORT).show(); return; } if (mUsbEndpoint_out == null) { Toast.makeText(mContext, "mUsbEndpoint_out can't be null", Toast.LENGTH_SHORT).show(); return; } int i = mUsbDeviceConnection.bulkTransfer(mUsbEndpoint_out, bytes, bytes.length, 1000); if (i < 0) { Toast.makeText(mContext, "failure to write", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(mContext, "success to write", Toast.LENGTH_SHORT).show(); } } /** * 权限广播接收器 */ private BroadcastReceiver mMyBroadcastReceiver=new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action_usb_permission.equals(action)) { synchronized (this) { UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); if (usbDevice != null) { if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { connect(usbDevice); Toast.makeText(context, "success get permission", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(context, "failure get permission", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(context, "the usbDevice be null", Toast.LENGTH_SHORT).show(); } } } } }; /** * 筛选出我们想要的usb设备 * @param name * @param usbDevice * @return */ public boolean filterDevice(String name, UsbDevice usbDevice) { // TODO: 2019/3/13 对应判断设备是否是我们要连接的设备 return false; }
- accessory模式(和host模式差不多,大致步骤一样,只是相关类不同而已如下)
1)获取UsbManager
2)通过usbManager获取连接到的usb外部设备UsbAccessory
3)获取usb设备引用,通过usbManager检测是否有对应权限,若无则请求权限,通过广播接收权限信息获取情况。
4)与UsbAccessory设备进行通信
public static final String action_usb_permission = "org.zhuhailong.myviewproject.permission"; private UsbManager usbManager; public void hostAccessory(Context context) { //获取UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE); //获取usb设备列表 UsbAccessory[] accessoryList = usbManager.getAccessoryList(); if (accessoryList == null || accessoryList.length <= = 0) { Toast.makeText(context, "未查询到对应设备", Toast.LENGTH_SHORT).show(); return; } UsbAccessory mUsbAccessory = null; for (UsbAccessory usbAccessory : accessoryList) { if (filterDevice(usbAccessory)) {//判断是否使我们要连接的usb设备 break; } } if (usbManager.hasPermission(mUsbAccessory)) {//检测是否有usb权限 requestPermission(mUsbAccessory);//请求usb权限 } else { connect(mUsbAccessory);//连接usb设备 } } /** * 请求usb权限 * * @param usbManager * @param parcelable */ public void requestPermission(Parcelable parcelable, UsbManager usbManager) { UsbAccessory usbAccessory = (UsbAccessory) parcelable; if (!usbManager.hasPermission(usbAccessory)) { IntentFilter intentFilter = new IntentFilter(action_usb_permission); registerReceiver(mMyBroadcastReceiver, intentFilter); PendingIntent broadcast = PendingIntent.getBroadcast(this, 0, new Intent(action_usb_permission), 0); usbManager.requestPermission(usbAccessory, broadcast); } else { Toast.makeText(context, "already have permission", Toast.LENGTH_SHORT).show(); } } private FileInputStream mFileInputStream; private FileOutputStream mFileOutputStream; /** * 连接设备 * @param usbAccessory * @return */ public boolean connect(UsbAccessory usbAccessory) { ParcelFileDescriptor parcelFileDescriptor = usbManager.openAccessory(usbAccessory); if (parcelFileDescriptor != null) { FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor(); mFileInputStream = new FileInputStream(fileDescriptor); mFileOutputStream = new FileOutputStream(fileDescriptor); } return false; } /** * 写入数据 * @param data */ public void write(byte[] data) { try { mFileOutputStream.write(data); } catch (IOException e) { e.printStackTrace(); } } /** * 读取数据 */ public void read() { int max;//字节数据根据协议来确定 byte[] data = new byte[max]; mFileInputStream.read(data); } /** * 权限广播接收器 */ private BroadcastReceiver mMyBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action_usb_permission.equals(action)) { synchronized (this) { UsbAccessory usbAccessory = intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY); if (usbAccessory != null) { if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { connect(usbAccessory); Toast.makeText(context, "success get permission", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(context, "failure get permission", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(context, "the usbDevice be null", Toast.LENGTH_SHORT).show(); } } } } }; /** * 筛选出我们想要的usb设备 * * @param usbAccessory * @return */ public boolean filterDevice(UsbAccessory usbAccessory) { // TODO: 2019/3/13 对应判断设备是否是我们要连接的设备 return false; }
注意!!!重要的事情说三遍,由于本人未使用过Accessory模式,在参考其他文章进行整理书写的,若有错误地方欢迎通知,必打赏。
第二遍:同上
第三遍:同上
更多相关文章
- No.11 使用firewall配置的防火墙策略的生效模式
- Android安全性和权限之入门篇
- Android(安卓)manifest中关于 sharedUserId 数据权限
- UBUNTU下以MTP模式自动挂载NEXUS 7
- Android(安卓)BLE最完整的工具类(扫描/连接/读写/通知设备)
- Android开发之AlarmManager的用法详解
- Android(安卓)Doze模式
- Android(安卓)MVP模式简单例子实战
- Android软键盘的工作原理