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 は、インテント filter を使用してアクティビティを開始しますandroid.hardware.usb.action.USB_DEVICE_ATTACHED

broadcastReciever したがって、 aを使用してこのインテントを受け取ることはできません。

だから、に変更してみてRecieverくださいActivity

于 2013-06-04T14:10:28.693 に答える