Я разрабатываю приложение, которое будет считывать входящие данные из монитора температуры. Устройство нестандартно и подключено к моему Android через USB. Мое приложение работает в режиме USB Host. К сожалению, я не могу фильтровать подключенные устройства с помощью ProductID, VendorID и т. Д., Поэтому я обрабатываю каждое подключение/отсоединение USB-устройства. Я объявил приемник в манифесте:Приложение не видит 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, но мое приложение не реагирует на прикрепление устройства, и если я запустил приложение с подключенным устройством, он отобразит мне сообщение «Нет подключенного устройства». Я совершенно новый для USB API в Android. Может кто-нибудь, пожалуйста, скажите мне, что я делаю неправильно? P.S. также, пожалуйста, сообщите, правильно ли я использую bulkTransfer. Буду признателен за любую помощь.
Вы уверены, что устройство распознается? Что в вашем журнале? – msh
Устройство не распознается. Я также тестировал приложение с Nokia 5320 в качестве устройства USB. Телефон показывает сообщение «Выберите режим подключения». Если выбрать «Usb Drive», он отображается на хосте в виде SDCard. Но ни в этом, ни в других режимах нет реакции от приложения. Мои USB-хосты: китайский планшет с Android 4 и Samsung Galaxy Nexus. Я читал, что у Galaxy Nexus есть правильное USB-оборудование. Может быть, вам просто нужно настроить некоторые функции устройства? – Darkmike
Последнее тестирование: совет nandeesh, и теперь приложение может видеть Nokia, если оно уже подключено. Отсутствует реакция на горячее соединение/разъединение. – Darkmike