2013-06-04 42 views
0

我正在开发将从温度监视器读取传入数据的应用程序。设备是非标准的,并通过USB连接到我的Android。我的应用程序在USB主机模式下工作。不幸的是,我无法通过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手册,但我的应用程序不附加设备反应,如果我与连接的设备启动应用程序它会显示一条消息“没有设备连接”。 我对Android中的USB API非常陌生。任何人都可以告诉我我做错了什么? P.S.也请告诉我是否正确使用bulkTransfer。 我将不胜感激任何帮助。

+0

你确定你的设备被认可?你的日志里有什么? – msh

+0

设备无法识别。我还测试了诺基亚5320作为USB设备的应用程序。电话显示消息“选择连接模式”。如果选择“USB驱动器”,它会在主机上显示为SDCard。但是在这个和其他模式中都没有任何反应。我的USB主机是:带有Android 4和Samsung Galaxy Nexus的中文平板电脑。我读到Galaxy Nexus被证明有正确的USB硬件。也许只需要设置一些设备功能? – Darkmike

+0

最后测试:使用nandeesh的建议,现在的应用程序可以看到诺基亚是否已经连接。热连接/断开连接没有反应。 – Darkmike

回答

1

USBManager启动一个带意向过滤器的活动android.hardware.usb.action.USB_DEVICE_ATTACHED

所以你不能使用broadcastReciever来接收这个意图。

所以尝试改变RecieverActivity

+0

我在清单中添加了android:launchMode =“singleTask”和ATTACHED/DETACHED动作和“android.permission.USB_PERMISSION”权限。在Activity中,将代码从onDeviceConnected()移动到onNewIntent()。测试显示器设备和诺基亚5320.主机可以看到诺基亚(例如USB驱动器)。还使用/不使用ProductID/VendorID筛选器进行测试。没有结果的应用程序。它可以是别的吗? – Darkmike

+1

我想你也需要添加元数据,至少是设备类 – nandeesh

+0

感谢您的建议,现在它至少可以与诺基亚一起工作。我会尽力为我的监视器设备找到合适的课程。 – Darkmike

相关问题