我正在编写USB驱动程序作为Android OS设备和Windows计算机之间的中间层。我正在使用HiKey 960开发板作为android设备。微型USB连接主板和计算机。我正在使用android附件库实现AOA协议,并且在Android Studio IDE中。当前,我的logcat充满了NullPointerExceptions和其他错误。我也不确定所采用的方法。我应该使用外部库(例如libusb)还是只能使用android类保护附件USB连接?可以使用UsbDeviceConnection类建立附件USB连接吗?将开发板连接到计算机后,如何将总线/通信控制准确地移交给计算机?
快速代码概述: 我通过常规方式获得了UsbManager,UsbAccessory和HashMap。该应用程序的清单包含一个意图过滤器,该过滤器可检测USB设备附件并向用户请求启动许可。 onCreate()方法打开一个工作线程。 run()方法打开一个连接,确保附件模式已打开并在android设备中受支持,找到适当的端点,最后尝试进行批量传输。
测试详细信息: 通过USB将开发板连接到笔记本电脑后,我运行该应用程序,然后单击显示在“连接的设备”下的开发板。
MainActivity.java:
package com.example.aoaconnect;
//imports here
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("onCreate","Began");
Thread worker = new Thread(new USBConnection(this, this.getIntent()));
worker.start();
}
class USBConnection implements Runnable {
private Context context;
private UsbManager manager;
private UsbAccessory accessory;
private HashMap<String, UsbDevice> devices;
private UsbInterface inface;
private UsbEndpoint outEp;
private UsbEndpoint inEp;
private UsbDeviceConnection connection;
private byte[] controlBuffer;
private byte[] outBuffer;
private byte[] inBuffer;
private USBConnection(Context context, Intent intent) {
this.context = context;
manager = (UsbManager) this.context.getSystemService(Context.USB_SERVICE);
accessory = intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
devices = manager.getDeviceList();
inface = null;
outEp = null;
inEp = null;
connection = null;
controlBuffer = new byte[64];
outBuffer = new byte[64];
inBuffer = new byte[64];
}
public void run() {
//everything is null for some reason? this jvm is real nihilist
for(String s : devices.keySet())
Log.d("Hashmap Test", devices.get(s).toString());
UsbDevice deviceAccessory = devices.get(UsbManager.EXTRA_ACCESSORY);
connection = manager.openDevice(deviceAccessory);
//check accessory mode support
boolean accessoryMode = false;
int counter = 0;
while (!accessoryMode && counter < 2) {
counter++;
if (((deviceAccessory.getVendorId() == 0x18D1) && (deviceAccessory.getProductId() == 0x2D00 || deviceAccessory.getProductId() == 0x2D01)))
accessoryMode = true;
else {
//attempt to start in usb mode
if (deviceAccessory.getDeviceProtocol() > 0)
connection.controlTransfer(64, 52, 0, Integer.parseInt(accessory.getSerial()), controlBuffer, controlBuffer.length, 5000);
connection.controlTransfer(64, 53, 0, 0, null, 0, 5000);
}
}
//bulk interface and endpoints
for (int i = 0; i < deviceAccessory.getInterfaceCount(); i++) {
UsbInterface infaceTemp = deviceAccessory.getInterface(i);
if (infaceTemp.getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA && infaceTemp.getEndpointCount() > 0) {
for (int j = 0; j < infaceTemp.getEndpointCount(); j++) {
UsbEndpoint epTemp = infaceTemp.getEndpoint(j);
if (epTemp.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (epTemp.getDirection() == UsbConstants.USB_DIR_OUT)
outEp = epTemp;
else
inEp = epTemp;
}
}
}
if (outEp != null && inEp != null) {
inface = infaceTemp;
break;
}
}
boolean infaceClaimed = connection.claimInterface(inface, true);
if (infaceClaimed)
Log.d("Inface Claim: ", "Success");
else
Log.d("Inface Claim: ", "Error");
//bulk transfer 1: android device -> host
int bulkStatusOut = connection.bulkTransfer(outEp, outBuffer, outBuffer.length, 5000);
if (bulkStatusOut > 0)
Log.d("Bulk Transfer Out: ", "successful");
//bulk transfer 2: host -> android device
int bulkStatusIn = connection.bulkTransfer(inEp, inBuffer, inBuffer.length, 5000);
if (bulkStatusIn > 0)
Log.d("Bulk Transfer In: ", "successful");
//terminate connection
BroadcastReceiver usbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (accessory != null && action.equals(UsbManager.ACTION_USB_ACCESSORY_DETACHED)) {
connection.releaseInterface(inface);
connection.close();
}
}
};
}//end run()
}//end USBConnection
}//end MainActivity
严重的Logcat错误
由NoClassNotDefFoundError和ClassNotFoundException引起的UnhandledKeyEventListener
Rejecting re-init on previously-failed class java.lang.Class<androidx.core.view.ViewCompat$OnUnhandledKeyEventListenerWrapper>: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/view/View$OnUnhandledKeyEventListener;
//standard logcat messages in between
Caused by: java.lang.ClassNotFoundException: Didn't find class "android.view.View$OnUnhandledKeyEventListener" on path: DexPathList[[zip file "/data/app/com.example.aoaconnect-1/base.apk"],nativeLibraryDirectories=[/data/app/com.example.aoaconnect-1/lib/arm64, /system/lib64, /system/vendor/lib64]]
NullPointerExceptions
D/onCreate: Began
E/UsbManager: exception in UsbManager.openDevice
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.hardware.usb.UsbDevice.getDeviceName()' on a null object reference
at android.hardware.usb.UsbManager.openDevice(UsbManager.java:337)
at com.example.aoaconnect.MainActivity$USBConnection.run(MainActivity.java:67)
at java.lang.Thread.run(Thread.java:764)
E/AndroidRuntime: FATAL EXCEPTION: Thread-2
Process: com.example.aoaconnect, PID: 3546
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.hardware.usb.UsbDevice.getVendorId()' on a null object reference
at com.example.aoaconnect.MainActivity$USBConnection.run(MainActivity.java:73)
at java.lang.Thread.run(Thread.java:764)