前言

在Android开发过程中,我们有时会涉及到USB连接的问题,这里为了方便USB连接的使用,我将相关知识封装成了一个工具类—USBHelper,下面就来介绍下它的使用吧。

今天涉及的内容有:

USB 权限相关设置

USB 设备接口确定

USB 连接流程讲解

USBHelper在 MainActivity 中的使用

项目结构图

USBHelper 源码

一. USB 权限相关设置

1.1 Android设备上打开 OTG 开关

USB连接涉及到OTG技术,需要我们在带有USB接口的Android设备上打开相关设置。在Android设备上操作如下:

设置 -----> 更多设置 -----> OTG Host //将OTG Host 开关打开

1.2 在 androidmanifast.xml 中添加 usb 权限

在 Androidmanifast.xml 中添加如下权限:

android:name="android.hardware.usb.host"

android:required="true" />

然后在 Androidmanifast.xml 中给要进行USB连接的Activity下添加usb列表文件。假设我们要在MainActivity中进行USB连接,则在 Androidmanifast.xml 中的MainActivity注册下添加以下代码:

android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"

android:resource="@xml/usb" />

主要是在Usb连接相关的Activity注册下添加下面的代码:

android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"

android:resource="@xml/usb" />

这里我们需要在res/下新建xml文件夹,然后在xml文件夹下新建usb.xml文件。即usb.xml路径为:res/xml/usb.xml。usb.xml文件中主要放置的是每个USB接口相关信息(因为一个Android设备可能有多个USB接口),usb.xml文件内容大致如下:

usb.xml里面基本是放的一个Android设备中所有USB接口的信息了。以上代码中,一个即代表一个USB接口了。通常一个USB接口中有很多信息,包括vendor-id,product-id,DeviceID等信息。这里需要注意的是,同一个usb接口热插拔一次,DeviceID是会变化的,标记一个USB接口的唯一性,我们通常用vendor-id和product-id。

二. USB 设备接口确定

上面我们已经讲过了一个Android设备可能有很多USB接口,而区分一个USB接口的唯一性我们是用vendor-id和product-id。

首先,我们需要获取一个Android设备上所有USB接口信息列表,这里我们可以用USBHelper中的以下方法获得:

/**

* 获取设备所有USB接口信息

*

* @param context

* @return 设备无USB接口时,返回 null

*/

public String getUSBListInfo(Context context)

所有USB接口信息列表我们已经获得了,这样我们就可以把每个USB接口相关信息按上面讲的格式填入res/xml/usb.xml文件中了。那么怎么确定某个USB接口的vendor-id呢?

这里可以使用USBHelper中的以下方法:

//监听热插拔,找特定usb接口

mUSBHelper.registerUsb(new USBHelper.OnHotplugListener() {

@Override

public void find(UsbDevice device) {

int vendorId=device.getVendorId();

int productId=device.getProductId();

ToastUtil.shortShow("vendorId="+vendorId+" productId="+productId);

}

@Override

public void permission(boolean status) {

if(status){

LogUtil.i("======USB授权成功======");

}else{

LogUtil.i("======USB授权失败======");

}

}

});

这里其实是监听了USB插拔动作的广播,当我们在给USB接上和拔出的时候,以上方法中的find(UsbDevice device)中便可获得此接口的device,然后我们就可以通过该device获得该USB接口的vendorId和productId了。

三. USB 连接流程讲解

上面已经讲解了如何配置USB相关设置及找到具体USB接口连接时需要的信息。接下来讲讲USB连接的流程。

USB连接的流程分以下几步:

找到特定设备UsbDevice(需要根据具体的vendorId和productId)

检测USB权限

找接口对象UsbInterface

找usb通信通道

打开USB设备

usb建立连接

USB数据传输

USB通讯结束后关闭usb

四. USBHelper在 MainActivity 中的使用

下面给出USBHelper在 MainActivity 中使用代码:

public class MainActivity extends AppCompatActivity{

private TextView mTv;

private Button mBtn;

private USBHelper mUSBHelper;

private UsbDeviceConnection mUsbDeviceConnection;

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

LogUtil.setDebug(true);

initView();

initData();

setListener();

}

private void initView() {

mTv = findViewById(R.id.tv);

mBtn = findViewById(R.id.btn);

}

private void initData() {

mUSBHelper=new USBHelper(MainActivity.this);

}

private void setListener() {

//监听热插拔,找特定usb接口

mUSBHelper.registerUsb(new USBHelper.OnHotplugListener() {

@Override

public void find(UsbDevice device) {

int vendorId=device.getVendorId();

int productId=device.getProductId();

ToastUtil.shortShow("vendorId="+vendorId+" productId="+productId);

}

@Override

public void permission(boolean status) {

if(status){

LogUtil.i("======USB授权成功======");

}else{

LogUtil.i("======USB授权失败======");

}

}

});

mBtn.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

//遍历usb信息

String info=mUSBHelper.getUSBListInfo(MainActivity.this);

LogUtil.i("info="+info);

//建立连接

Mapmap=mUSBHelper.connectProcess(6495,1);

int tag=mUSBHelper.getMapTag(map);

switch (tag) {

case USBHelper.DEVICE_NOT_FOUNT://无usb设备

LogUtil.i("无usb设备");

break;

case USBHelper.NO_PERMISSION://无usb权限

LogUtil.i("无usb权限");

// //申请权限

// mUSBHelper.requestUsbPermission();

break;

case USBHelper.NO_INTERFACE://查找设备接口失败

LogUtil.i("查找设备接口失败");

break;

case USBHelper.NO_BULKOUT_CHANNEL://查找输出端点失败

LogUtil.i("查找输出端点失败");

break;

case USBHelper.NO_BULKIN_CHANNEL://查找读入端点失败

LogUtil.i("查找读入端点失败");

break;

case USBHelper.NO_CONTROL_CHANNEL://查找控制端点失败

LogUtil.i("查找控制端点失败");

break;

case USBHelper.NO_POINTOUT_CHANNEL://查找中断输出端点失败

LogUtil.i("查找中断输出端点失败");

break;

case USBHelper.NO_POINTIN_CHANNEL://查找中断读入端点失败

LogUtil.i("查找中断读入端点失败");

break;

case USBHelper.NO_OPEN://USB设备打开失败

LogUtil.i("USB设备打开失败");

break;

case USBHelper.CONNECT_FAILED://USB建立连接失败

LogUtil.i("USB建立连接失败");

break;

case USBHelper.CONNECT_SUCCESS://USB建立连接成功

LogUtil.i("USB建立连接成功");

mUsbDeviceConnection= (UsbDeviceConnection) mUSBHelper.getMapValue(map);

break;

default:

break;

}

//发送数据

new Thread(new Runnable() {

@Override

public void run() {

//发送数据

String message = "我是大神";

boolean flag=mUSBHelper.writeMessage(message,mUsbDeviceConnection,null);

if(flag){

LogUtil.i("发送成功");

}else{

LogUtil.i("发送失败");

}

}

}).start();

}

});

}

@Override

protected void onDestroy() {

//关闭USB

mUSBHelper.close(mUsbDeviceConnection);

super.onDestroy();

}

}

这里需要注意的是, String info=mUSBHelper.getUSBListInfo(MainActivity.this);只是用于罗列一个Android设备上Usb接口信息列表,然后在建立连接:

Mapmap=mUSBHelper.connectProcess(6495,1);

中的参数6495,1可以通过插拔USB接口,然后在mUSBHelper.registerUsb(new USBHelper.OnHotplugListener())方法中的find(UsbDevice device)中找到vendorId和productId。

然后USB连接流程已经封装到了:

/**连接sub流程**/

public Map connectProcess(int vendorId,int productId)

方法中,大家只要调用此方法就好,若USB无权限,大家可以在case USBHelper.NO_PERMISSION中进行Usb权限申请,就像下面这样:

case USBHelper.NO_PERMISSION://无usb权限

LogUtil.i("无usb权限");

//申请权限

mUSBHelper.requestUsbPermission();

break;

然后申请结果可以在mUSBHelper.registerUsb(new USBHelper.OnHotplugListener())方法中的permission(boolean status)中看到。

usb建立成功后,可以在case USBHelper.CONNECT_SUCCESS中获得连接对象UsbDeviceConnection,接下来便是新建一个线程向USB接口中写入数据,类似下面这样:

//发送数据

new Thread(new Runnable() {

@Override

public void run() {

//发送数据

String message = "我是大神";

boolean flag=mUSBHelper.writeMessage(message,mUsbDeviceConnection,null);

if(flag){

LogUtil.i("发送成功");

}else{

LogUtil.i("发送失败");

}

}

}).start();

写数据的方法已经在USBHelper的

/**写数据**/

public boolean writeMessage(String message,UsbDeviceConnection connection,String charsetName)

方法中封装好了,大家对照着调用就行。

最后,当我们USB通讯已经用完了,需要在界面销毁时关闭USB,类似下面这样:

@Override

protected void onDestroy() {

//关闭USB

mUSBHelper.close(mUsbDeviceConnection);

super.onDestroy();

}

这样的话,一个完成的USB连接通讯就讲完了。当然,USBHelper中还有很多其他方法,大家有时间也可以看看。

五. 项目结构图

项目结构图.png

六. USBHelper 源码

下面给出USBHelper源码:

Android连接多个usb,Android实现USB连接相关推荐

  1. docker容器连接Android设备,通过ADB连接到Docker容器中的USB Android设备

    我创建了一个包含Android SDK的Docker镜像,并试图在运行此图像的容器中公开我的Android手机.所以我使用了–privileged标志并安装了USB设备,如下所示: $docker r ...

  2. Android 11源码 Framework修改默认usb连接模式为MTP模式

    Android 11源码 Framework修改默认usb连接模式为MTP模式 Android 11源码 Framework修改默认usb连接模式为MTP模式 修改Framework层源码 编译修改后 ...

  3. Android的USB通信(AOA连接)

    USB 主机和配件概览 Android 通过 USB 配件和 USB 主机两种模式支持各种 USB 外围设备和 Android USB 配件(实现 Android 配件协议的硬件).在 USB 配件模 ...

  4. android 网络re,Gnirehtet让Android设备通过USB连接电脑上网

    Gnirehtet让Android设备通过USB连接电脑上网 2020年08月02日 | 萬仟网移动技术 | 我要评论 目录Gnirehtet简介Gnirehtet教程Gnirehtet下载地址功能快 ...

  5. android手机蓝屏代码,电脑通过usb连接多个android手机,出现蓝屏现象

    今天上班带着小米,在两个手机之间倒腾通讯录与名片,后来没电了,拿到手之后没充过.但我插上usb连接线,3秒之后,电脑蓝屏了,当时我的诺基亚E66也在usb充电,我就以为是电压的原因.但事实证明远不是那 ...

  6. Android之判断USB传输模式与USB连接状态

    1.监听UsbManager.ACTION_USB_STATE public class UsbManager {private static final String TAG = "Usb ...

  7. android连不上电脑,安卓手机USB数据线连接不上电脑的最佳解决方法

    许多用户都喜欢将手机连接电脑来解决一些问题或者上传一些图片到电脑中存储,不过近日有使用安卓手机的用户在将usb数据线连接电脑的时候,发现无法连接,导致无法上传手机照片图片到电脑上和传送apk手机软件到 ...

  8. Android连上USb不充电,手机连接电脑只显示充电没有usb连接怎么办?

    手机连接电脑只显示充电没有usb连接怎么办?我们在办公室的时候,经常会使用usb数据线来为手机充电,正常情况下,不仅可以充电,也可以连接电脑传输数据,然而有用户反馈说手机连接电脑只显示充电,这该怎么办 ...

  9. android usb连接不到手机,为什么手机USB连接不上电脑

    刚买的新手机,手机USB为什么不能正常连接到电脑上呢?如何解决手机usb连不上电脑的问题呢? 手机USB连接不上电脑的解决方法 硬件问题 第一步:检查手机数据线是否正常,可以拿其他人的手机进行检查,千 ...

最新文章

  1. Docker安全加固——利用LXCFS增强docker容器隔离性和资源可见性
  2. Java并发编程实战系列10之避免活跃性危险
  3. 机器学习之过拟合与欠拟合以及偏差-方差分解
  4. Scala Akka的Actor模型
  5. 解密:LL与LR解析 2(译,完结)
  6. 现代软件工程系列 学生的精彩文章 (3) 如何在Bug 不断的情况下还能保持平常心...
  7. linux “命令行自动补全”功能用命令
  8. c4503文件服务器,理光C3503/C4503/C5503检查状态下各项目说明解释
  9. Android开源库
  10. Lingo解决最优化问题
  11. Commit Message 规范
  12. Linux的ftp设置
  13. 经典卷积神经网络---VGG16详解
  14. 射频(RF)和微波电路发展简史(一)
  15. 四种快速简单添加视频字幕的方法,总有一款适合你
  16. like功能以及check功能
  17. MicroPython-On-ESP8266——WIFI与网络
  18. gk的树---dfs+贪心
  19. 零知识证明(zero knowledge validation)
  20. 制作3D动漫模型原来这么简单,会建模还能拿高薪?

热门文章

  1. MAC M1安装Node
  2. Filter为什么会在一次请求执行多次doFilter?
  3. 【OpenHarmony】napi基本用法----HelloWorld
  4. stm32中常见的通信协议之SPI
  5. 以太坊·电影院场景区块链应用探索
  6. Inventor冲压加强筋_Inventor教程之创建加强筋
  7. 门禁系统一定要服务器吗,门禁系统服务器功能配置
  8. urllib2 解析
  9. 流体力学-----连续性方程的推导和理解
  10. 阅读笔记之《DisenQNet: Disentangled Representation Learning for Educational Questions》