zoukankan      html  css  js  c++  java
  • 一步一步教你简单完成 Android USB开发

    项目中有一个新的需求,要求可以连接一个USB体温枪,APP可以从体温枪中读取到体温数据,一番搜寻之后发现一个封装很棒的USB通信库。
    github地址:usb-serial-for-android

    准备工作

    1. 从 github 上 clone 这个库的源文件
    2. 在Android Studio中引入模块
      import module

    3. 在build.gradle中添加依赖compile project(path: ':usbSerialForAndroid')

    4. 复制 device_filter.xml 到项目的 res/xml/ 文件夹下
      设备列表

    5. 配置 AndroidManifest.xml 文件

    <uses-feature android:name="android.hardware.usb.host" />
    <application>
        <activity
            android:name="..."
            ...>
          <intent-filter>
            <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
          </intent-filter>
          <meta-data
              android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
              android:resource="@xml/device_filter" />
        </activity>
    </application>

    使用

    示例代码解析:

    // 获取系统服务得到UsbManager实例
    UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
    //查找所有插入的设备
    List<UsbSerialDriver> availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(manager);
    if (availableDrivers.isEmpty()) {
      return;
    }
    
    // 打开设备,建立通信连接
    UsbSerialDriver driver = availableDrivers.get(0);
    UsbDeviceConnection connection = manager.openDevice(driver.getDevice());
    if (connection == null) {
      // You probably need to call UsbManager.requestPermission(driver.getDevice(), ..)
      return;
    }
    
    //打开端口,设置端口参数,读取数据
    UsbSerialPort port = driver.getPorts().get(0);
    try {
      port.open(connection);
    //四个参数分别是:波特率,数据位,停止位,校验位
      port.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
    
      byte buffer[] = new byte[16];
      int numBytesRead = port.read(buffer, 1000);
      Log.d(TAG, "Read " + numBytesRead + " bytes.");
    } catch (IOException e) {
      // Deal with error.
    } finally {
      port.close();
    }

    上述代码是库作者写的一段示例代码,可以看出使用上非常简单,下面的代码演示了如何将USB操作都封装到一个类里。

    public class TemperatureUsbControl {
    
        private static final String TAG = TemperatureUsbControl.class.getSimpleName();
        private static final String TEMPERATURE_USB_VENDOR_ID = "067B";     //供应商id
        private static final String TEMPERATURE_USB_PRODUCT_ID = "2303";    //产品id
        private Context mContext;
        private UsbManager mUsbManager; //USB管理器
        private UsbSerialPort sTemperatureUsbPort = null;  //接体温枪的usb端口
        private SerialInputOutputManager mSerialIoManager;  //输入输出管理器(本质是一个Runnable)
        private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();  //用于不断从端口读取数据
        //数据输入输出监听器
        private final SerialInputOutputManager.Listener mListener =
                new SerialInputOutputManager.Listener() {
    
                    @Override
                    public void onRunError(Exception e) {
                        Log.d(TAG, "Runner stopped.");
                    }
    
                    @Override
                    public void onNewData(final byte[] data) {
                        Log.d(TAG, "new data.");
                    }
                };
    
        public TemperatureUsbControl(Context context) {
            mContext = context;
        }
    
        public void initUsbControl() {
            mUsbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
            //全部设备
            List<UsbSerialDriver> usbSerialDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(mUsbManager);
            //全部端口
            List<UsbSerialPort> usbSerialPorts = new ArrayList<UsbSerialPort>();
            for (UsbSerialDriver driver : usbSerialDrivers) {
                List<UsbSerialPort> ports = driver.getPorts();
                Log.d(TAG, String.format("+ %s: %s port%s",
                        driver, Integer.valueOf(ports.size()), ports.size() == 1 ? "" : "s"));
                usbSerialPorts.addAll(ports);
            }
            String vendorId;
            String productId;
            //校验设备,设备是 2303设备
            for (UsbSerialPort port : usbSerialPorts) {
                UsbSerialDriver driver = port.getDriver();
                UsbDevice device = driver.getDevice();
                vendorId = HexDump.toHexString((short) device.getVendorId());
                productId = HexDump.toHexString((short) device.getProductId());
                if (vendorId.equals(TEMPERATURE_USB_VENDOR_ID) && productId.equals(TEMPERATURE_USB_PRODUCT_ID)) {
                    sTemperatureUsbPort = port;
                }
            }
            if (sTemperatureUsbPort != null) {
                //成功获取端口,打开连接
                UsbDeviceConnection connection = mUsbManager.openDevice(sTemperatureUsbPort.getDriver().getDevice());
                if (connection == null) {
                    Log.e(TAG, "Opening device failed");
                    return;
                }
                try {
                    sTemperatureUsbPort.open(connection);
                    //设置波特率
                    sTemperatureUsbPort.setParameters(4800, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);
    
                } catch (IOException e) {
                    //打开端口失败,关闭!
                    Log.e(TAG, "Error setting up device: " + e.getMessage(), e);
                    try {
                        sTemperatureUsbPort.close();
                    } catch (IOException e2) {
                        // Ignore.
                    }
                    sTemperatureUsbPort = null;
                    return;
                }
            } else {
                //提示未检测到设备
            }
        }
    
    
        public void onDeviceStateChange() {
            //重新开启USB管理器
            stopIoManager();
            startIoManager();
        }
    
        private void startIoManager() {
            if (sTemperatureUsbPort != null) {
                Log.i(TAG, "Starting io manager ..");
                mSerialIoManager = new SerialInputOutputManager(sTemperatureUsbPort, mListener);
                mExecutor.submit(mSerialIoManager);  //实质是用一个线程不断读取USB端口
            }
        }
    
        private void stopIoManager() {
            if (mSerialIoManager != null) {
                Log.i(TAG, "Stopping io manager ..");
                mSerialIoManager.stop();
                mSerialIoManager = null;
            }
        }
    
        public void onPause() {
            stopIoManager();
            if (sTemperatureUsbPort != null) {
                try {
                    sTemperatureUsbPort.close();
                } catch (IOException e) {
                    // Ignore.
                }
                sTemperatureUsbPort = null;
            }
        }
    }

    在Activity中使用:

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_punch);
            initUsbControl();       //初始化USB控制器
        }
    
        /**
         * 初始化USB
         */
        private void initUsbControl() {
            mTemperatureUsbControl = new TemperatureUsbControl(mContext);
            mTemperatureUsbControl.initUsbControl();
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            IntentFilter usbFilter = new IntentFilter();
            usbFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
            usbFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
            registerReceiver(mUsbReceiver, usbFilter);
            mTemperatureUsbControl.onDeviceStateChange();
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            mTemperatureUsbControl.onPause();
            unregisterReceiver(mUsbReceiver);
        }
    
        /**
         * 用于检测usb插入状态的BroadcasReceiver
         */
        private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
                    //设备插入
                    mTemperatureUsbControl.initUsbControl();
                    mTemperatureUsbControl.onDeviceStateChange();
                    Log.e(TAG, "ACTION_USB_DEVICE_ATTACHED");
                } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
                    //设备移除
                    mTemperatureUsbControl.onPause();
                    Log.e(TAG, "ACTION_USB_DEVICE_DETACHED");
                }
            }
        };

    读到的数据如果需要在Activity中使用,可以使用EventBus来完成~

  • 相关阅读:
    什么是 bean 的自动装配?
    什么是 Spring 的内部 bean?
    什么是 Spring 的 MVC 框架?
    Spring AOP and AspectJ AOP 有什么区别?
    解释 JDBC 抽象和 DAO 模块?
    volatile 类型变量提供什么保证?
    一个 Spring Bean 定义 包含什么?
    什么是 Spring MVC 框架的控制器?
    使用 Spring 访问 Hibernate 的方法有哪些?
    什么是 Callable 和 Future?
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/9454985.html
Copyright © 2011-2022 走看看