1

AOA を使用して Linux マシンと通信する Android フォンがあります。Linux マシンは、接続を開始するように設定されており、着信データを待って、それを変更せずに電話にエコー バックします。これは、電話からのデータの小さなパケット (1024 バイト未満) に対しては正常に機能します。ただし、正確に 1024 バイトを送信すると、Android 側からは機能しているように見えますが、コンピューターはパケットを認識せず、次の小さいパケットのみを認識します。電話機が 1024 より大きいパケットを送信しようとすると、これらはコンピュータによって受信されますが、Android フォンはコンピュータからパケットを受信できなくなります。問題をさらに混乱させるのは、これは過去に機能していたにもかかわらず、電話の送受信コードの以前のバージョンにロールバックしても効果がないように見えることです。コンピュータ上のコードは変更されていません。

Android アプリは起動時に USB アクセサリをチェックし、見つかった場合はリスナーと送信スレッドを開始します。送信側スレッドは、ブロッキング キューで発信パケットを待機し、受信するとすぐに送信します。リスナー スレッドは継続的に入力ストリームからの読み取りを試みますが、データが利用可能になるまでブロックされます。これは、スレッドのセットアップと実行に使用するコードです。

private boolean openUSB(){
    mUSBManager = (UsbManager) getSystemService(Context.USB_SERVICE);
    mAccessory = mUSBManager.getAccessoryList();
    if (mAccessory != null && mAccessory.length > 0) {
        mParcelFileDescriptor = mUSBManager.openAccessory(mAccessory[0]);
        mFileDescriptor = mParcelFileDescriptor.getFileDescriptor();

        mListener = new Thread() {
            public void run() {
                listenerThread();
            }

        };
        mListener.start();

        mSender = new Thread() {
            public void run() {
                senderThread();
            }

        };
        mSender.start();
        displayText("Connected to USB accessory");

        return true;
    } else {
        displayText("No USB accessory detected"); 
        return false;
    }
}

private void listenerThread(){

    byte packet[] = new byte[SDR_PREFIX_SIZE+SDR_HEADER_SIZE+SDR_MAX_PAYLOAD+SDR_CRC_SIZE];
    FileInputStream input = new FileInputStream(mFileDescriptor);
    try {
        ByteArrayOutputStream incoming = new ByteArrayOutputStream();
        displayText("Listener Started");
        while ( mFileDescriptor != null && input != null ) {
            int read = input.read(packet,0,packet.length);

            /* data in packet gets processed */
        }
    } catch ( Exception e) {
        displayText("Listener Exception - "+e.getMessage(),true);
    }
    displayText("Listener Exited");
}

private void senderThread(){

    displayText("sender started");
    FileOutputStream output=new FileOutputStream(mFileDescriptor);

    try {
        byte data[] = mTransmitQueue.take();
        while (data != null) {
            displayText("Sending packet " + packet + ", "+data.length + " bytes");
            output.write(data);

            data = mTransmitQueue.take();
        }

    } catch ( Exception e) {
        displayText("Sender Exception - "+e.getMessage(),true);
    }
}

以前は、ファイル ストリームを作成するために使用された中間オブジェクトの一部がガベージ コレクションされていて、まだ必要であることが判明するまで、リスナーとセンダーを機能させるのに問題がありました。これらすべての中間オブジェクトをメンバー変数 (mUSBManager、mAccessory、mParcelFileDescriptor、mFileDescriptor) に保存して永続化します。この問題は似たようなものだと思いますが、前進することができませんでした。私はこの問題に頭を悩ませてきましたが、成功していません。他の人がこれの原因について何らかの洞察を持っていることを本当に願っています.

4

1 に答える 1