[Android]USB开发

声明:主要参照文档:
Android开发之USB数据通信
安卓USB通信之权限管理

第一:请求权限和请求权限回调(通过广播回调)

注册一个广播接收器用于接收USB权限被同意或拒绝后发出的广播

 //注册USB设备权限管理广播
         IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION); //ACTION_USB_PERMISSION为自定义的字符串
         context.registerReceiver(usbReceiver, filter);

其中usbReceiver的实现是:

private  BroadcastReceiver usbReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if(action.equals(ACTION_USB_PERMISSION)){//ACTION_USB_PERMISSION是前面我们自己自定义的字符串
                UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                    if (device != null) {
                        LogUtils.i("已获取USB权限");
                    }
                } else {
                    LogUtils.i("USB权限被拒绝");
                }
                   
    };

请求权限:

PendingIntent  mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);//关于这个mPermissionIntent ,具体的作用我还没弄明白,明白以后补充
manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
manager.requestPermission(device,mPermissionIntent);//device是具体某个usb设备

执行完这个后,界面会弹出对话框询问用户是否授予权限,然后会发送权限广播,所以上面我们注册一个广播接收器来判断权限状态

第二:注册USB设备插拔广播

USB设备被插/拔后同样会发送一个广播,因此我们需要注册一个接收器来接收这个广播

        IntentFilter stateFilter = new IntentFilter();
        stateFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        stateFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        context.registerReceiver(usbStateReceiver, stateFilter);

其中.usbStateReceiver的实现如下:

private  BroadcastReceiver usbStateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            //USB连接上手机时会发送广播android.hardware.usb.action.USB_STATE"及UsbManager.ACTION_USB_DEVICE_ATTACHED
            if (action.equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
                LogUtils.i("有USB设备连接");
              
            
            } else if (action.equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {//USB被拔出
                LogUtils.i("USB连接断开,程序退出!");
              
            }
        }
    };

详细介绍以上两种,另附一个自己写的USBUtil,里面的思路是,初始化话时传入要连接设备的VendorId和ProductId,然后自动进行搜索,连接,授权等。只暴露读/写,开/关给外界,其他的全部自己处理

未经测试,请勿直接使用,仅供参考!!!!

package com.police.policefaceproject.utils;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;

import java.util.Iterator;
import java.util.Map;

/**
 * Created by Administrator on 2018/4/18.
 */

public class USBUtils {
    private  Activity activity;
    private  final String ACTION_USB_PERMISSION = "com.gudi.usb.permission";
    private  UsbManager manager;
    private  PendingIntent mPermissionIntent;
    private  BroadcastReceiver usbReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if(action.equals(ACTION_USB_PERMISSION)){
                UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                    if (device != null) {
                        USBCtrl(context);
                    }
                } else {
                    LogUtils.i("USB权限被拒绝");
                    if(activity!=null && !activity.isDestroyed()){
                        activity.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                UiUtils.Alert(activity, "权限错误", "请重新插拔设备后,授予应用访问USB权限","确定", new UiUtils.AlertCallBackOne() {

                                    @Override
                                    public void onClick(DialogInterface dialogInterface, int i) {

                                    }
                                });
                               ;
                            }
                        });
                    }

                }
            }
        }
    };
    private  UsbDeviceConnection usbConnection;
    private  UsbEndpoint uepIn;
    private  UsbEndpoint uepOut;
    private  int mProductId,mVendorId;
    private  BroadcastReceiver usbStateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            //USB连接上手机时会发送广播android.hardware.usb.action.USB_STATE"及UsbManager.ACTION_USB_DEVICE_ATTACHED
            if (action.equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {//判断其中一个就可以了
                LogUtils.i("有USB设备连接");
                showMsg("有USB设备连接");
                USBCtrl(context);
            } else if (action.equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {//USB被拔出
                LogUtils.i("USB连接断开,程序退出!");
                showMsg("USB连接断开,请重试");
                closeConn();
            }
        }
    };

    public  void init(Activity context,int productId,int vendorId){
        activity = context;
        mProductId = productId;
        mVendorId = vendorId;
        manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
        mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
         //注册USB设备权限管理广播
         IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
         context.registerReceiver(usbReceiver, filter);
        //注册USB设备插拔广播
        IntentFilter stateFilter = new IntentFilter();
        stateFilter.addAction(UsbManager.ACTION_USB_ACCESSORY_ATTACHED);
        stateFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        stateFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        context.registerReceiver(usbStateReceiver, stateFilter);
     }

    private  Map<String,UsbDevice> getDevices(){
         if(manager != null){
             Map<String,UsbDevice> deviceMap = manager.getDeviceList();
             return  deviceMap;
         }

         return null;

     }

    private  UsbDeviceConnection openDevice(Context context,UsbDevice device){
        if(manager.hasPermission(device)){
            UsbDeviceConnection  DeviceConnection = manager.openDevice(device);
            return DeviceConnection;
        }else{
            LogUtils.i("请求USB权限");
            manager.requestPermission(device,mPermissionIntent);
            return null;
        }

    }

    private  void USBCtrl(Context context){
        //获取设备列表
        Map<String,UsbDevice> devicesList= getDevices();
        if(devicesList == null || devicesList.size() <=0){
            LogUtils.e("未查找到USB设备");
            showMsg("未查找到设备,请重新插拔设备");

        }else{
            //遍历寻找指定设备
            Iterator<UsbDevice> deviceIterator = devicesList.values().iterator();
            while(deviceIterator.hasNext()){
                UsbDevice usb= deviceIterator.next();
                if(usb.getVendorId() == mVendorId && usb.getProductId() == mProductId){
                    //查找到指定设备
                    connDevice(context,usb);
                    break;
                }
            }

        }
    }

    private  void connDevice(Context context,UsbDevice device){
        UsbEndpoint uep;

        //获得设备接口
        UsbInterface usbInterface = device.getInterface(0);
        //查找输入,输出端
        for(int i =0;i<usbInterface.getEndpointCount();i++){
            uep=usbInterface.getEndpoint(i);
            if(uep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK){
                if(uep.getDirection() == UsbConstants.USB_DIR_IN){
                    uepIn = uep;
                }else if(uep.getDirection() == UsbConstants.USB_DIR_OUT){
                    uepOut = uep;
                }
            }
        }
        usbConnection = openDevice(context,device);
        if(usbConnection == null){
            LogUtils.e("连接设备失败");
            showMsg("连接设备失败,请赋予权限");
            return ;
        }
        if(usbConnection.claimInterface(usbInterface,true)){//声明独占此接口,在发送或接收数据前完成
            //锁定成功

        }else{
            //锁定失败
            usbConnection.close();
            usbConnection = null;
            LogUtils.e("锁定接口失败");
            showMsg("锁定接口失败,请插拔设备重试");
        }

    }

    public   int  write(byte[] data){
        if(usbConnection != null){
           int len= usbConnection.bulkTransfer(uepOut, data, data.length, 3000);
            LogUtils.i("通过USB接口发送"+data.length+"数据");
            return len;
        }else{
            LogUtils.i("usbConnection为null");
            return -1;
        }
    }

    public  byte[] read(byte[] data){
        if(usbConnection != null){
            int len= usbConnection.bulkTransfer(uepOut, data, data.length, 3000);
            LogUtils.i("通过USB接口接收"+data.length+"数据");
            return data;
        }else{
            LogUtils.i("接收数据,usbConnection为null");
            return null;
        }
    }

    public  void closeConn(){
        if(usbConnection != null){
            usbConnection.close();
            usbConnection=null;
        }
    }
    private  void showMsg(final String msg){

        if(activity!=null ){
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    UiUtils.toast(activity.getApplicationContext(),msg);
                }
            });
        }
    }




}

未经测试,请勿直接使用,仅供参考!!!!

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android通过两种模式支持各种USB设备: USB accessory 和USB host。(Android ...
    wangdy12阅读 9,604评论 1 6
  • 一、先大致了解下Android里关于USB的API,下图很清晰的表示了Android里面USB的树状(图随便画的表...
    CrazyYong阅读 5,489评论 0 4
  • 项目中有一个新的需求,要求可以连接一个USB体温枪,APP可以从体温枪中读取到体温数据,一番搜寻之后发现一个封装很...
    junerver阅读 11,716评论 18 29
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,678评论 25 708
  • 你,此时此刻,正在看手机...... 你有认真的算过吗?除了打电话,你每天泡在手机上的时间有多长? 你是不是总低头...
    马大哈哈镜花缘阅读 1,168评论 5 4