我正在开发将从温度监视器读取传入数据的应用程序。设备是非标准的,通过 USB 连接到我的 Android。我的应用程序在 USB 主机模式下工作。不幸的是,我无法通过 ProductID、VendorID 等过滤连接的设备,因此我正在处理 USB 设备的每个附加/分离。我已经在清单中声明了接收者:
<receiver
android:name=".USBReceiver"
android:enabled="true" >
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
</intent-filter>
</receiver>
这里是它的实现:
public class USBReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
MainActivity ac = MainActivity.currentInstance();
UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
boolean applicationRunning = (ac!=null) && !ac.isConnected();
if(applicationRunning) {
ac.onDeviceConnected(device);
}
} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
if(ac!=null) {
ac.onDeviceDisconnected(device);
}
}
}
}
用于附加/分离的处理程序在 MainActivity 中实现:
public class MainActivity extends Activity {
private static final int TIMEOUT = 0;
private UsbManager mManager;
private UsbDevice mDevice;
private UsbDeviceConnection mConnection;
private UsbInterface mInterface;
private UsbEndpoint mEndpoint;
private ReadThread mReadThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mManager = (UsbManager) getSystemService(Context.USB_SERVICE);
final HashMap<String, UsbDevice> mDeviceList = mManager.getDeviceList();
if(!mDeviceList.isEmpty()) {
final String[] deviceNames = new String[mDeviceList.size()];
Iterator<UsbDevice> deviceIterator = mDeviceList.values().iterator();
int i=0;
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Choose a device");
while(deviceIterator.hasNext()){
UsbDevice device = deviceIterator.next();
deviceNames[i]=device.getDeviceName();
i++;
}
builder.setItems(deviceNames, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mDevice = mDeviceList.get(deviceNames[which]);
saveDeviceSettings();
}
}).create().show();
}
if(mDevice==null){
mName.setText("");
Toast.makeText(this, "No device connected", Toast.LENGTH_SHORT).show();
}
}
public void onDeviceConnected(final UsbDevice device) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
String title = "Use device \""+device.getDeviceName()+"\"?";
builder.setTitle(title)
.setPositiveButton("Use", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mDevice = device;
saveDeviceSettings(); //save productID&vendorID to preferences
openConnection(); //open USBConnection
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).create().show();
}
public void onDeviceDisconnected(UsbDevice device) {
int vID = device.getVendorId(),
pID = device.getProductId();
if(vID==mApp.getSettings().getVendorID()&&pID==mApp.getSettings().getProductID()) {
Toast.makeText(this, "Device disconnected!", Toast.LENGTH_SHORT).show();
if(mReadThread!=null&&mReadThread.isAlive()){
mReadThread.interrupt();
}
mName.setText("");
}
}
private void openConnection() {
mConnection = mManager.openDevice(mDevice);
mInterface = mDevice.getInterface(0);
mConnection.claimInterface(mInterface, true);
for(int i=0;i<mInterface.getEndpointCount(); i++) {
if(mInterface.getEndpoint(i).getType()==UsbConstants.USB_ENDPOINT_XFER_BULK
&& mInterface.getEndpoint(i).getDirection()==UsbConstants.USB_DIR_IN) {
mEndpoint = mInterface.getEndpoint(i);
break;
}
}
if(mConnection!=null && mEndpoint!=null) {
mReadThread = new ReadThread();
mReadThread.start();
}
}
private class ReadThread extends Thread {
@Override
public void run() {
while(true) {
if(isInterrupted()){
return;
}
int i = 64;
byte[] inputArray = new byte[i];
for(int j=0;j<i;j++) inputArray[j]=0;
mConnection.bulkTransfer(mEndpoint, inputArray, i, TIMEOUT);
MainActivity.this.onDataReceived(inputArray);
}
}
}
}
我根据 Android 手册做了所有事情,但我的应用程序对设备连接没有反应,如果我使用连接的设备启动应用程序,它会显示一条消息“未连接设备”。我对 Android 中的 USB API 很陌生。谁能告诉我我做错了什么?PS也请告诉我是否正确使用bulkTransfer。我将不胜感激任何帮助。