入门USB通信

        • 一、Android USB开发模式
        • 二、进入Hello World
          • 1、 配置AndroidManifest.xml文件中usb模式
          • 2、配置usb设备插入的通知和相关usb设备的过滤
          • 3、android设备与USB设备连接和通信

前些日志去了一趟广州,老总对自动贩卖机有点想法,于是乎回来就开始查阅相关文档做好准备工作,这不记下自己的理解,如果大家有更好的理解,或者本人的一些介绍理解有错误或者偏差的地方,欢迎留言,大家一起共同进步!

一、Android USB开发模式

android 中usb有两种开发模式,一种是host模式,另一种是accessory模式,下面介绍一下这两种模式。

  1. Host模式:如图,此模式中,android设备充当主机,给usb外部设备供电,常见的Host模式有:鼠标、键盘、等。
  2. Accessory模式:如图,和Host模式相反,此模式中,usb设备充当主机,给android手机提供电源,常见的设备:无人机远程控制器等。

二、进入Hello World

1、 配置AndroidManifest.xml文件中usb模式

在android系统中,默认是关闭usb模式的,当我们将usb外部设备插入android设备时,android系统不回出任何响应。如果我们要打开系统usb模式,需要在android清单文件里使用标签声明响应的usb模式

  1. Host模式
    
  1. accessory模式
    
2、配置usb设备插入的通知和相关usb设备的过滤

若我们希望在插入usb设备时,android系统能接收到提示性通知,则需要在android组件中配置标签配置相关信息,中配置我们要接收的相关类型的信息通知,配置我们需要检测的指定的设备,标签内容对应一个xml资源文件,里面配置我们指定的usb设备。如下:

                                                                                    

其中xml资源文件的配置如下:

<?xml version="1.0" encoding="utf-8"?>                
3、android设备与USB设备连接和通信

无论是host模式还是accessory模式,在进行检测获取usb设备时,都需要用到UsbManager类,只是调用不同的方法而已。如下:

  1. 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;    }
  1. 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模式,在参考其他文章进行整理书写的,若有错误地方欢迎通知,必打赏。
第二遍:同上
第三遍:同上

更多相关文章

  1. No.11 使用firewall配置的防火墙策略的生效模式
  2. Android安全性和权限之入门篇
  3. Android(安卓)manifest中关于 sharedUserId 数据权限
  4. UBUNTU下以MTP模式自动挂载NEXUS 7
  5. Android(安卓)BLE最完整的工具类(扫描/连接/读写/通知设备)
  6. Android开发之AlarmManager的用法详解
  7. Android(安卓)Doze模式
  8. Android(安卓)MVP模式简单例子实战
  9. Android软键盘的工作原理

随机推荐

  1. Android与Linux分道扬镳
  2. Android之屏幕方向|显示方式|Activity重
  3. Linux Kernel and Android 休眠与唤醒(中
  4. Android的事件传递机制
  5. android之js与java互相调用
  6. 读取Android(安卓)GPS NMEA数据
  7. Android(安卓)通过shape画线,1条线2种颜色
  8. 解决android sdk无法更新
  9. Android context(Application/Activity)与
  10. 关于Android的keystore生成和查看keystor