Android USB HOST设备通信传数据有误

duhanhao007 2016-01-07 11:57:16
准备用USB-OTG实现Android和设备对接(JAVA对C) 但是传过来的数据有问题 分4次发4条的9个包 共36个包 只有第一条是完整的 其他三条只有前后完整 中间转换后有丢失情况

设备指令:下发:byte[]形式 DI 0000 0000 0000 (DI下发指令)(条索引) (包序号)(有效长度) 如 第0条消息、第8包、有138个有效数据:DI 0 8 138==>byte[] 68 73 0 0 0 0 8 0 0 0 138 0 0 0
查了下资料发现 JAVA中byte为-128~127 C中byte为0~255 所以超过128部分是空值 然后对byte数组每一位都进行了与运算 bt[i]&0xFF; 结果还是不对 所以应该不是这个问题
而且发送的第一条数据总是可以成功 而剩下的2 3 4条有值但不是完整的
然后每次拔下设备重新初始化下发 以2 3 4条作为第一次下发 还是可以成功 后续不完整

请问这是为什么, 是USB-HOST使用有误吗?

代码如下
package com.example.testapp;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
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 android.os.Build;
import android.os.Message;
import android.util.Log;

@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
@SuppressLint({ "DefaultLocale", "NewApi" })
public class adwd {
static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";// 权限
public static UsbManager myUsbManager;
public static UsbEndpoint epBulkOut;
public static UsbInterface interface2;
public static UsbDevice myUsbDevice;
public static UsbInterface interface1;
public static UsbEndpoint epBulkIn;
public static UsbDeviceConnection mDeviceConnection;
static int vid = 7358, pid = 3;// 筛选设备vid、pid
private static Context context;

/***
* 枚举设备
*
* @param mUsbManager
*/
public static void enumerateDevice(UsbManager mUsbManager) {
if (mUsbManager == null) {
return;
} else {
HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
if (!(deviceList.isEmpty())) {
// deviceList不为空
Iterator<UsbDevice> deviceIterator = deviceList.values()
.iterator();
while (deviceIterator.hasNext()) {
UsbDevice device = deviceIterator.next();
// 输出设备信息
Log.i("TAG", "DeviceInfo: " + device.getVendorId() + " , "
+ device.getProductId());
// 保存设备VID和PID
int VendorID = device.getVendorId();
int ProductID = device.getProductId();
// 保存匹配到的设备
if (VendorID == vid && ProductID == pid) {
myUsbDevice = device;
break;
}
}
} else {
}
}
}

/***
* 获取接口
*/
public static void getDeviceInterface() {
if (myUsbDevice != null) {
Log.d("TAG", "interfaceCounts : " + myUsbDevice.getInterfaceCount());
for (int i = 0; i < myUsbDevice.getInterfaceCount(); i++) {
UsbInterface intf = myUsbDevice.getInterface(i);

if (i == 0) {
interface1 = intf;
}
if (i == 1) {
interface2 = intf;
}
}
if (!myUsbManager.hasPermission(myUsbDevice)) {
PendingIntent pi = PendingIntent.getBroadcast(context, 0,
new Intent(ACTION_USB_PERMISSION), 0);
adwd.myUsbManager.requestPermission(adwd.myUsbDevice, pi);
}

} else {
}

}

/***
* 分配端点
*
* @param mInterface
* @return
*/
public static UsbEndpoint assignEndpoint(UsbInterface mInterface) {
UsbEndpoint epControl = null;
UsbEndpoint epIntEndpointOut = null;
UsbEndpoint epIntEndpointIn = null;
UsbEndpoint ep0 = mInterface.getEndpoint(0);
UsbEndpoint ep1 = mInterface.getEndpoint(1);
epBulkOut = ep1;
epBulkIn = ep0;
if (epBulkOut == null && epBulkIn == null && epControl == null
&& epIntEndpointOut == null && epIntEndpointIn == null) {
throw new IllegalArgumentException("not endpoint is founded!");
}
return epIntEndpointIn;
}

/***
* 打开设备、获取连接对象
*
* @param mInterface
*/
public static void openDevice(UsbInterface mInterface) {
if (mInterface != null) {
UsbDeviceConnection conn = null;
// 在open前判断是否有连接权限;对于连接权限可以静态分配,也可以动态分配权限
if (myUsbManager.hasPermission(myUsbDevice)) {
conn = myUsbManager.openDevice(myUsbDevice);
}

if (conn != null && conn.claimInterface(mInterface, true)) {
mDeviceConnection = conn;
Message message = new Message();
message.what = 3;
MainActivity.handler.sendMessage(message);
if (mDeviceConnection != null)// 到此你的android设备已经连上硬件设备
;
// final String mySerial = mDeviceConnection.getSerial();
} else {
}
}
}

/***
* 初始化
*
* @param cont
* @param mUsbManager
* @param use
*/
public static void init(Context context, int use) {

myUsbManager = (UsbManager) context
.getSystemService(Context.USB_SERVICE);
// 枚举设备
enumerateDevice(myUsbManager);
// 查找设备接口
getDeviceInterface();
if (interface1 != null) {
// 获取设备endpoint
assignEndpoint(interface1);
// 打开conn连接
openDevice(interface1);
}

}

/***
* 下发数据
*
* @param buffer
*/
public static void dSend(final byte[] buffer) {
int ret = mDeviceConnection.bulkTransfer(epBulkOut, buffer,
buffer.length, 0);
if (ret < 0) {
mDeviceConnection.close();
} else {
Log.e("下发", "下发成功");
}
}

/***
* 关闭连接对象
*/
public static void close() {
mDeviceConnection.releaseInterface(interface1);
mDeviceConnection.close();
}

/***
* 下发方法
*
* @param lst2
*/
public static void issued(final Context context, final String ls,
final String lst) {
Thread t = new Thread() {
public void run() {
assignEndpoint(interface1);// 获取端点
openDevice(interface1);// 获取设备连接
send(0, ls, lst);
close();// 关闭连接 释放接口
}
};
t.start();
}

/***
* 发送
*
* @param index
* 索引条数
* @param id
* 身份证号
* @param name
* 名字
* @param x16
* 16进制虹膜
*/
public static void send(int index, String info, String x16) {
byte[] code = ArrayAdd(Arrays.copyOf(info.getBytes(), 26),
x16.getBytes());
Log.e("code", " " + code.length);// 总长应为2074 (18+8)+2048
int pack_total = 256;// 单包256-14头长度=242有效长度
int num;
if (code.length % (pack_total - 14) == 0) {
num = (code.length / (pack_total - 14));
} else {
num = (code.length / (pack_total - 14)) + 1;
}
int end_weight = (pack_total - 14)
- (num * (pack_total - 14) - code.length);// 不满包的配重
for (int piece = 0; piece < num; piece++) {
int start = (pack_total - 14) * piece;// 起始位
int end = (pack_total - 14) * (piece + 1);// 结束位
if ((piece + 1) == num && code.length % (pack_total - 14) != 0) {
end = start + end_weight;// 不满包结束位
}
byte[] a = make(index, piece, cutbyte(code, start, end));
dSend(a);

// 包头格式 D I _ _ _ 例: D I 第1条 第0包 有效数据242 D I 第1条 第8包 有效数据138
Log.e("包头",
new String(cutbyte(a, 0, 2)) + " "
+ bytes2Int(cutbyte(a, 2, 6), 0) + " "
+ bytes2Int(cutbyte(a, 6, 10), 0) + " "
+ bytes2Int(cutbyte(a, 10, 14), 0));
Log.e("包长", "" + bytes2Int(cutbyte(a, 10, 14), 0));
if (bytes2Int(cutbyte(a, 6, 10), 0) == 0) {
Log.e("包数据", new String(cutbyte(a, 14, 40)));
Log.e("包数据", new String(cutbyte(a, 40, a.length)));
} else {
Log.e("包数据", new String(cutbyte(a, 14, a.length)));
}
}
}

/***
* 头封装
*/

public static byte[] make(int index, int piece, byte[] n4) {
// "DI" 0000 0000 0000
byte[] di = ArrayAdd("D".getBytes(), "I".getBytes());
byte[] n1 = int2Bytes(index);
byte[] n2 = int2Bytes(piece);
byte[] n3 = int2Bytes(n4.length);
return ArrayAdd(ArrayAdd(ArrayAdd(ArrayAdd(di, n1), n2), n3), n4);
}

/***
* int转byte
*/
public static byte[] int2Bytes(int value) {
byte[] byte_src = new byte[4];
byte_src[3] = (byte) ((value & 0xFF000000) >> 24);
byte_src[2] = (byte) ((value & 0x00FF0000) >> 16);
byte_src[1] = (byte) ((value & 0x0000FF00) >> 8);
byte_src[0] = (byte) ((value & 0x000000FF));
return byte_src;
}

/**
* byte[]转int(高位前低位后)的顺序。
*/
public static int bytes2Int(byte[] ary, int offset) {
int value;
value = (int) ((ary[offset] & 0xFF) | ((ary[offset + 1] << 8) & 0xFF00)
| ((ary[offset + 2] << 16) & 0xFF0000) | ((ary[offset + 3] << 24) & 0xFF000000));
return value;
}

/***
* 数组拼接
*
* @param str1
* String2Byte[]
* @param str2
* String2Byte[]
* @return str1+str2 String2Byte[]
*/
public static byte[] ArrayAdd(byte[] str1, byte[] str2) {
int strLen1 = str1.length;// 保存第一个数组长度
int strLen2 = str2.length;// 保存第二个数组长度
str1 = Arrays.copyOf(str1, strLen1 + strLen2);// 扩容
System.arraycopy(str2, 0, str1, strLen1, strLen2);// 将第二个数组与第一个数组合并
return str1;
}

/***
* 截取byte[]数组
*
* @param by
* 原数组
* @param start
* 起始位置
* @param end
* 结束位置
* @return 新数组
*/
public static byte[] cutbyte(byte[] by, int start, int end) {
byte[] bt = new byte[end - start];
for (int i = start; i < end; i++) {
bt[i - start] = by[i];
}
return bt;
}
}


issued(getApplicationContext(), nam, x16);

四条数据为
nam:16位身份证+00000000(预留汉字姓名位)
x16:2048位16进制字符串
...全文
170 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
Yellow_Beard 2016-10-09
  • 打赏
  • 举报
回复
android usb host这个很正常
课程以技术人的网络知识为中心和基线,通过基础理论篇、进阶拓展篇和实践练习篇三个部分的分解与层层递进,全面覆盖OSI七层模型与封装和解封装等网络通信核心思想、TCP协议、TCP三次握手与四次挥手过程原理、time-wait状态及连接过多处理等经典网络硬核基础知识,互联网、云计算与云原生时代下CDN、容器集群网络通信原理等进阶延伸知识,和以读懂/绘制拓扑图、网络诊断与调试命令、生产环境典型的网络故障处理、基于Wireshark和tcpdump进行常见环境尤其是容器环境(包括Docker和Kubernetes容器集群)下报文抓取及分析和分步法来分析并排除故障为代表的实践性知识。 课程大纲如下:课程的设计摒弃过于细分的网工专属的CCNA/CCNP等受众面小的路线,以互联网业界典型的技术岗对网络知识的共性需求为主线,理论联系实际,实践演示反哺验证理论,以突出实用性和可实践性为特色,让以往抽象、空洞的网络知识以接地气、看得见、能实际感知观测的方式来授讲解,有图有真相,有作业有练习,有引导思考和相应解答,有模型有实践演示,还有众多生活中鲜活的举例。确保稍微具备一点基础背景的同学,都能听得懂、学得会、用得上,切实提升大多数技术岗(开发人员、测试人员、运维人员、架构师、解决方案架构师、售前顾问、技术支持工程师、技术客服人员等)的职场竞争力和个人影响力。 除了讲授知识模块本身,还有底层思想的剖析讲解和思维层面的发散引导,以帮助同学们构筑基础知识框架体系和技术性思维。课程同时融入微服务、CDN、TCP协议及通信原理、云原生与容器集群等互联网界刚需前沿性知识模块,并穿插进部分互联网界技术岗高频基础面试题及解答,以及典型的生产环境网络故障处理举例和少有地方讲解清楚的部分技术疑点和区(如容器网络flannel的host-gw模式下节点是否必须在同一个二层网络,容器网络Calico中blackhole路由的作用,Calico中IP分配机制是否存在不足等),以最大程度上覆盖满足主要技术岗位对网络及其相关延伸知识的技能需求,确保同学们的学习能紧跟工作实际和主流技术趋势,学有所成、学有所值,并实实在在增加职场筹码。 学习本课程,可有效支撑同学们在物理机、虚拟机、云计算、容器集群、Server-less等不同基础设施环境下,以及单体架构、分布式架构、SOA架构、微服务架构、云原生架构等不同应用架构下,对底层网络基础及相关知识的实际需求运用。

80,362

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧