【问题标题】:Application does not see USB-device应用程序看不到 USB 设备
【发布时间】:2013-05-30 23:03:25
【问题描述】:

我正在开发将从温度监视器读取传入数据的应用程序。设备是非标准的,通过 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 很陌生。谁能告诉我我做错了什么? 附言还请告诉我是否正确使用了 bulkTransfer。 我将不胜感激。

【问题讨论】:

  • 您确定您的设备已被识别吗?你的日志里有什么?
  • 设备无法识别。我还测试了诺基亚 5320 作为 USB 设备的应用程序。手机显示消息“选择连接模式”。如果选择“Usb Drive”,它在主机上显示为 SDCard。但无论是在这种模式下还是在其他模式下,应用程序都没有反应。我的 USB 主机是:装有 Android 4 和三星 Galaxy Nexus 的中国平板电脑。我读到 Galaxy Nexus 被证明具有正确的 USB 硬件。也许只需要设置一些设备功能?
  • 上次测试:使用了 nandeesh 的建议,现在应用程序可以看到已连接的诺基亚。热连接/断开没有反应。

标签: android connection usb device


【解决方案1】:

USBManager 使用意图过滤器android.hardware.usb.action.USB_DEVICE_ATTACHED 启动一个活动。

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

所以尝试将Reciever 更改为Activity

【讨论】:

  • 我将 android:launchMode="singleTask" 和 ATTACHED/DETACHED 操作添加到活动中,并将“android.permission.USB_PERMISSION”添加到清单中的权限。在 Activity 中,将代码从 onDeviceConnected() 移至 onNewIntent()。使用显示器设备和诺基亚 5320 进行测试。主机可以看到诺基亚(例如 USB 驱动器)。还使用/不使用 ProductID/VendorID 过滤器进行了测试。应用程序没有结果。可以是别的吗?
  • 我猜你也需要添加元数据,至少设备类
  • 感谢您的建议,现在至少在诺基亚上运行良好。我会尝试为我的监控设备找到合适的类。
猜你喜欢
  • 2017-04-09
  • 1970-01-01
  • 2015-01-18
  • 2021-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多