0

我正在开发将从温度监视器读取传入数据的应用程序。设备是非标准的,通过 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。我将不胜感激任何帮助。

4

1 回答 1

1

USBManager 启动一个带有意图过滤器的 Activity android.hardware.usb.action.USB_DEVICE_ATTACHED

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

所以尝试更改RecieverActivity

于 2013-06-04T14:10:28.693 回答