2013-06-04 17 views
0

Я разрабатываю приложение, которое будет считывать входящие данные из монитора температуры. Устройство нестандартно и подключено к моему 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. Буду признателен за любую помощь.

+0

Вы уверены, что устройство распознается? Что в вашем журнале? – msh

+0

Устройство не распознается. Я также тестировал приложение с Nokia 5320 в качестве устройства USB. Телефон показывает сообщение «Выберите режим подключения». Если выбрать «Usb Drive», он отображается на хосте в виде SDCard. Но ни в этом, ни в других режимах нет реакции от приложения. Мои USB-хосты: китайский планшет с Android 4 и Samsung Galaxy Nexus. Я читал, что у Galaxy Nexus есть правильное USB-оборудование. Может быть, вам просто нужно настроить некоторые функции устройства? – Darkmike

+0

Последнее тестирование: совет nandeesh, и теперь приложение может видеть Nokia, если оно уже подключено. Отсутствует реакция на горячее соединение/разъединение. – Darkmike

ответ

1

USBManager начинает деятельность с фильтра намерений android.hardware.usb.action.USB_DEVICE_ATTACHED.

Таким образом, вы не можете использовать broadcastReciever, чтобы получить это намерение.

Так попробуйте изменить Reciever к Activity

+0

Я добавил android: launchMode = "singleTask" и ATTACHED/DETACHED действия для активности и "android.permission.USB_PERMISSION" к разрешениям в манифесте. В Activity перемещен код из onDeviceConnected() в onNewIntent(). Протестировано с помощью монитора и Nokia 5320. Хост может видеть Nokia (например, USB-накопитель). Также тестируется с/без фильтра ProductID/VendorID. Никакого результата из приложения. Это может быть что-то еще? – Darkmike

+1

Я думаю, вам нужно добавить метаданные тоже, по крайней мере класс устройства – nandeesh

+0

Спасибо за совет, теперь он отлично работает, по крайней мере, с Nokia. Я попытаюсь найти подходящий класс для своего монитора. – Darkmike

Смежные вопросы