- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我创建了一个 java 应用程序,它将自己设置为 USB 配件并通过批量传输发送一些数据。
Android 设备应该看到这个并将数据打印到 TextView。目前我拥有它,以便 Android 设备可以看到附件的连接,并启动批量传输的应用程序,但失败并显示以下内容。
org.usb4java.LibUsbException: USB error 5: Bulk write error!: Entity not found
at com.xxx.xxx.AccessoryTest.writeAndRead(AccessoryTest.java:60)
at com.xxx.xxx.AccessoryTest.main(AccessoryTest.java:37)
欢迎提出任何建议!
我有另一个实用程序,它将 Android 设备的端点信息报告为
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 512
bInterval 0
extralen 0
extra:
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 512
bInterval 0
extralen 0
extra:
我正在尝试写入 0x02 端点
安卓代码
public class MainActivity extends AppCompatActivity implements Runnable {
private UsbManager manager;
private UsbAccessory accessory;
private ParcelFileDescriptor accessoryFileDescriptor;
private FileInputStream accessoryInput;
private FileOutputStream accessoryOutput;
private TextView questionTV;
private final BroadcastReceiver usbBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (UsbManager.ACTION_USB_ACCESSORY_ATTACHED.equals(action)) {
synchronized (this) {
accessory = intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
}
} else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
UsbAccessory accessory = intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
if (accessory != null) {
// call your method that cleans up and closes communication with the accessory
try {
accessoryFileDescriptor.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
manager = (UsbManager) getSystemService(Context.USB_SERVICE);
IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_ACCESSORY_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
registerReceiver(usbBroadcastReceiver, filter);
if (getLastNonConfigurationInstance() != null)
{
accessory = (UsbAccessory) getLastNonConfigurationInstance();
openAccessory();
}
setContentView(R.layout.activity_main);
}
private void openAccessory() {
accessoryFileDescriptor = manager.openAccessory(accessory);
if(accessoryFileDescriptor != null) {
FileDescriptor fd = accessoryFileDescriptor.getFileDescriptor();
accessoryInput = new FileInputStream(fd);
accessoryOutput = new FileOutputStream(fd);
Thread thread = new Thread(null, this, "AccessoryThread");
thread.start();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void run() {
int ret = 0;
byte[] buffer = new byte[51];
int bufferUsed = 0;
while(ret >= 0) {
try {
ret = accessoryInput.read(buffer);
} catch (IOException e) {
Log.e("MainActivity", "Exception in USB accessory input reading", e);
break;
}
}
String question = new String(buffer);
LinearLayout layout= (LinearLayout) findViewById(R.id.layout);
questionTV = new TextView(this);
questionTV.setText(question);
layout.addView(questionTV);
}
}
Java 应用程序代码
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import org.usb4java.BufferUtils;
import org.usb4java.Context;
import org.usb4java.Device;
import org.usb4java.DeviceDescriptor;
import org.usb4java.DeviceHandle;
import org.usb4java.DeviceList;
import org.usb4java.LibUsb;
import org.usb4java.LibUsbException;
public class AccessoryTest {
private final static byte REQUEST_TYPE_READ = (byte) 0xC0;
private final static byte END_POINT_IN = (byte) 0x81;
private final static byte END_POINT_OUT = (byte) 0x02;
private final static short NEXUS7_VENDORID = (short) 0x18D1;
private final static short NEXUS7_PRODUCTID = (short) 0x4EE1;
private static Context context;
private static Device device;
private static DeviceHandle handle;
public static void main(String[] args) {
try {
init();
int result = setupAccessory("PCHost", "PCHost1", "Description", "1.0", "http://www.mycompany.com",
"SerialNumber");
if (result != LibUsb.SUCCESS)
throw new LibUsbException("Unable to setup Accessory", result);
writeAndRead();
} catch (Exception e) {
e.printStackTrace();
} finally {
LibUsb.releaseInterface(handle, 0);
LibUsb.resetDevice(handle);
LibUsb.close(handle);
LibUsb.exit(context);
}
}
private static void writeAndRead() {
String question = "Hello Android I'll be your host today, how are you?";
byte[] questionBuffer = question.getBytes();
ByteBuffer questionData = BufferUtils.allocateByteBuffer(questionBuffer.length);
IntBuffer transferred = IntBuffer.allocate(1);
int result = 0;
//THIS IS THE PART WHERE IT FAILS!
result = LibUsb.bulkTransfer(handle, END_POINT_OUT, questionData, transferred, 5000);
if(result < 0) {
throw new LibUsbException("Bulk write error!", result);
}
}
private static void init() {
context = new Context();
int result = LibUsb.init(context);
if (result != LibUsb.SUCCESS)
throw new LibUsbException("Unable to initialize libusb.", result);
device = findDevice(NEXUS7_VENDORID);
handle = new DeviceHandle();
result = LibUsb.open(device, handle);
if (result < 0)
throw new LibUsbException("Unable to open USB device", result);
result = LibUsb.claimInterface(handle, 0);
if (result != LibUsb.SUCCESS)
throw new LibUsbException("Unable to claim interface", result);
}
private static Device findDevice(short vendorId) {
// Read the USB device list
DeviceList list = new DeviceList();
int result = LibUsb.getDeviceList(null, list);
if (result < 0)
throw new LibUsbException("Unable to get device list", result);
try {
// Iterate over all devices and scan for the right one
for (Device device : list) {
DeviceDescriptor descriptor = new DeviceDescriptor();
result = LibUsb.getDeviceDescriptor(device, descriptor);
if (result != LibUsb.SUCCESS)
throw new LibUsbException("Unable to read device descriptor", result);
if (descriptor.idVendor() == vendorId)
return device;
}
} finally {
// Ensure the allocated device list is freed
LibUsb.freeDeviceList(list, true);
}
// Device not found
return null;
}
private static int setupAccessory(String vendor, String model, String description, String version, String url,
String serial) throws LibUsbException {
int response = 0;
// Setup setup token
response = transferSetupPacket((short) 2, REQUEST_TYPE_READ, (byte) 51);
// Setup data packet
response = transferAccessoryDataPacket(vendor, (short) 0);
response = transferAccessoryDataPacket(model, (short) 1);
response = transferAccessoryDataPacket(description, (short) 2);
response = transferAccessoryDataPacket(version, (short) 3);
response = transferAccessoryDataPacket(url, (short) 4);
response = transferAccessoryDataPacket(serial, (short) 5);
// Setup handshake packet
response = transferSetupPacket((short) 0, (byte) (LibUsb.REQUEST_TYPE_VENDOR | LibUsb.ENDPOINT_OUT), (byte) 53);
LibUsb.releaseInterface(handle, 0);
return response;
}
private static int transferSetupPacket(short bufferLength, byte requestType, byte request) throws LibUsbException {
int response = 0;
byte[] bytebuff = new byte[bufferLength];
ByteBuffer data = BufferUtils.allocateByteBuffer(bytebuff.length);
data.put(bytebuff);
final short wValue = 0;
final short wIndex = 0;
final long timeout = 1000;
data.rewind();
response = LibUsb.controlTransfer(handle, requestType, request, wValue, wIndex,
data, timeout);
if(response < 0)
throw new LibUsbException("Unable to transfer setup packet ", response);
return response;
}
private static int transferAccessoryDataPacket(String param, short index) {
int response;
byte[] byteArray = param.getBytes();
ByteBuffer data = BufferUtils.allocateByteBuffer(byteArray.length);
data.put(byteArray);
final byte bRequest = (byte) 52;
final short wValue = 0;
final long timeout = 0;
response = LibUsb.controlTransfer(handle, LibUsb.REQUEST_TYPE_VENDOR, bRequest, wValue, index,
data, timeout);
if(response < 0)
throw new LibUsbException("Unable to control transfer.", response);
return response;
}
}
AndroidManifest.xml
<uses-feature android:name="android.hardware.usb.accessory" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<uses-library android:name="com.android.future.usb.accessory" />
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
android:resource="@xml/accessory_filter" />
</activity>
</application>
最佳答案
根据 AOP 标准,一旦 Android 设备进入配件模式,它的 VID 和 PID 就会发生变化
因此在设置配件后需要回收设备句柄和接口(interface)。
关于java - 安卓接收usb批量传输,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32627760/
我想将 EditText 始终设置为 LTR,我该怎么做?android:textDirection 似乎确实是答案,我无法让项目使用该指令进行编译 最佳答案 为 editText 使用引力 andr
我希望我的应用在每次打开时都显示登录屏幕。使用 android:clearTaskOnLaunch="true" 一切正常。但是有一个错误,只有在手机关机并且应用程序首先使用小部件启动时才会发生。 I
实际上我的要求是我想将动态文件加载到像图像一样的网页中。视频,音频等,它来自 Assets 或应用程序自己的文件目录,这不是问题。 我尝试使用以下两种方式。 方式一 这是我的 html 文件在 ass
我正在触发一个 DatePickerDialog,在 api 22 (Android 5.1) 之前它一直在工作并显示良好,我在上面设置混合和最大日期(最小 = 当前日期,最大 = 从当前日期开始的
我有一个 ListView ,我在其中将标题 View 添加到该列表。一切都很好,但是当滚动列表 headerview 也随着列表移动时,所以我想避免 headerview 滚动,我的意思是当我列表到
虽然我在android上做过一些app,但我还是一头雾水。是否可以使用 SDK 4.0 中的功能,并在 android 2.1 或更低版本上运行该应用程序? 我尝试了你们提到的方法,但出现错误 - F
您好,我正在开发小型 android 应用程序,我想在其中显示带有一些元素的简单 gridview。它工作正常。唯一的问题是即使有空间,它也总是只显示两列。它平均将屏幕分成 2 列并仅显示两个元素。如
我正在使用 Android 2.3.3 API 构建一个应用程序。我需要识别方向的变化并执行一些操作。所以我在 Android Manifest 中添加了以下内容, android:configCha
我正在尝试在“点击”包含特定 MIME 类型的 nfc 标签时开始一项 Activity 。我制作了一个 mime 类型为“text/plain”的标签,并将其添加到 list 中:
我可以将一些数据保存到文件中 val byteArrayOutputStream = ByteArrayOutputStream() byteArrayOutputStream.wri
我正在尝试解析一个包含复杂阿拉伯字母的 XML 文件.. 当我在 android 2.3.7 上测试时,并不是所有的阿拉伯字母都被支持,仍然有一些复杂的显示为方 block .. 但是在 androi
我需要编写一个方法来确定设备是平板电脑还是手机。我不需要根据这个显示不同的用户界面。我只需要有关设备的信息,以便将来我可以将其发送到指标。 在互联网上,我找到了很多方法来确定设备是否是平板电脑。我已经
我正在玩文字转语音,让我的测试应用程序更有趣。它适用于模拟器,但不适用于我的手机,因为我的默认语言环境不是英语。 但是,文本是英文的,所以 tts 当然应该使用英文。据我所知,我可以实现一个自动安装,
我正在使用 MVVM 和整洁的架构编写应用程序。在其中一个屏幕上,我需要使用 pagination 实现 RecyclerView。我将使用库 Paging3。 Android 开发者推荐在存储库层使
这个问题在这里已经有了答案: I lost my .keystore file? (12 个回答) 4年前关闭。 当我以前的操作系统损坏并安装新的(7 月 3 日)时,以前的 android_key_
我正在使用 MVVM 和整洁的架构编写应用程序。在其中一个屏幕上,我需要使用 pagination 实现 RecyclerView。我将使用库 Paging3。 Android 开发者推荐在存储库层使
在我的 v27\style.xml 中,我有以下代码来设置白色导航栏: @color/colorPrimary @color/colorPrimaryDark @color/
我想通过发送电子邮件 startActivity(Intent.createChooser(new Intent(android.content.Intent.ACTION_SEND))) 我知道要将
我实现了一个自定义 ListView ,它看起来像 Twitter 时间线。 adapter = new MyClickableListAdapter(this, R.layout.timeline,
我有一个显示启动画面的自定义对话框; mSplashDialog = new Dialog(MyActivity.this,R.layout.splash); mSplashDialog.setCon
我是一名优秀的程序员,十分优秀!