1. ホーム
  2. java

[解決済み] 適切なエンドポイントを使用したAndroidのBulkTransferから応答がない

2022-02-08 21:42:32

質問事項

バルク転送に関する多くの質問をここで見ましたが、そのほとんどは、読み取りと書き込みに間違ったインターフェースを使用しています。

private UsbManager usbManager;
private UsbDevice usbDevice;
private UsbDeviceConnection usbDeviceConnection;
private UsbInterface usbInterface;
private UsbEndpoint readEndpoint;
private UsbEndpoint writeEndpoint;
private UsbEndpoint interruptEndpoint;
private PtpSession ptpSession;

public boolean Connect(UsbManager usbManager,UsbDevice usbDevice, PtpSession ptpSession)
{
    if(usbManager == null ||usbDevice == null||ptpSession == null)
        return false;
    else
    {
        this.usbManager = usbManager;
        this.usbDevice = usbDevice;
        this.ptpSession = ptpSession;

        for (int i = 0; i < this.usbDevice.getInterfaceCount(); i++) {
            UsbInterface uintf = this.usbDevice.getInterface(i);
            if (uintf.getInterfaceClass() == UsbConstants.USB_CLASS_STILL_IMAGE) {
                Log.d(TAG, "Imaging USB interface found");
                this.usbInterface = uintf;
                break;
            }
        }
    }

    // find the wright usb endpoints
    if(usbInterface == null)
        return false;
    else
    {
        for(int i = 0; i < usbInterface.getEndpointCount();i++)
        {
            UsbEndpoint ep = usbInterface.getEndpoint(i);
            if (ep.getDirection() == UsbConstants.USB_DIR_IN) {
                if(ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)
                {

                    readEndpoint = ep;
                }
                else if(ep.getType() == UsbConstants.USB_ENDPOINT_XFER_INT)
                {
                    interruptEndpoint = ep;

                }
            } else if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
                writeEndpoint = ep;
            }
        }

        this.usbDeviceConnection = usbManager.openDevice(usbDevice);
        usbDeviceConnection.claimInterface(usbInterface,true);
    }

    if(readEndpoint == null || writeEndpoint == null ||interruptEndpoint == null)
        return false;
    return true;
}

この部分は正常に動作しているようですが、次にデータの読み取りと書き込みを行う方法が2つあります。

private boolean writeData(byte[] data)
{
    int retry = 0;
    while (usbDeviceConnection.bulkTransfer(writeEndpoint, data, data.length, 5000) != data.length)
    {
        retry++;
        if (retry > 4)
        {
            return false;
        }
    }
    return true;
}

private byte[] readData()
{
    long rStart = System.currentTimeMillis();
    byte[] mReadData = new byte[30];
    while (true) {
        int bytesCount = usbDeviceConnection.bulkTransfer(readEndpoint, mReadData, mReadData.length, 5000);
        if (bytesCount >= 0) {
            return mReadData;
        }
        else if (System.currentTimeMillis() - rStart > 5000) {
            return new byte[]{};
        } else {
            Log.e(TAG, String.format("Bulk read -1 cmd"));
        }


    }
}

私はデータを送信し、writeDataメソッドから肯定的なフィードバックを得ることができます。その後、しばらく(100msあるいは1000ms)待って、readDataを試しています。そして、私は読み取るデータを得たことがなく、フィードバックとして常に-1を得ます(5秒後にメソッドが空の配列を返すまで)。mReadData配列のサイズを他の値に変更してみましたが、今のところうまくいきません(データのサイズは30byteがPTP Protocollの典型的なResponseDataブロックの期待値です)。

私はNikon D3200からスマートフォン(Galaxy S7 with Android 6.0.1 running)のデータをオリジナルのUSB-OTGアダプタで読み取ろうとしています。私のコードが問題であることは間違いありませんが、何時間も様々なことを試してみた結果、何が問題なのか本当に分からなくなりました。

私が使用したISO15740規範へのリンクはこちらです。 ISO 15740へのリンク

もしかしたら、どなたか私の問題が何であるかおわかりになるでしょうか?

よろしくお願いします。 ドミニク

解決方法は?

次のコードは動作しません。

private boolean writeData(byte[] data)
{
    int retry = 0;
    while (usbDeviceConnection.bulkTransfer(writeEndpoint, data, data.length, 5000) != data.length)
    {
        retry++;
        if (retry > 4)
        {
            return false;
        }
    }
    return true;
}  

の代わりに、以下を使用して接続状態を確認します。

 int ret = usbDeviceConnection.bulkTransfer(writeEndpoint, data, data.length, 5000;


     if(ret < 0)
                    {
                      Log.d("TAG", "Error happened!");
                    }
                    else if(ret == 0)
                    {
                        Log.d("TAG", "No data transferred!");
                    }
                    else
                    {
                        Log.d("TAG", "success!");
                    }

( https://www.developer.android.com/studio/debug/am-logcat.html ログを記録する代わりに try {...} catch {...} ブロックまたは ログキャット ,...)

からコピーしたものです。 android usb UsbDeviceConnection.bulkTransfer は -1 を返します。

ということは、データの書き込み/読み出しができない理由は、複数の可能性があります。

  • プログラミングエラー (おそらく writeData() メソッドへの参照を知らないので usbDeviceConnection オブジェクト) のようにメソッドにパラメータとして与えてみてください。

    private UsbDeviceConnection usbDeviceConnection;
    private boolean writeData(UsbDeviceConnection  usbDeviceConnection, byte[] data) { ... }
    
    

    でメソッドを呼び出します。

     writeData(usbDeviceConnection, ...);
    
    

( http://www.programcreek.com/java-api-examples/index.php?api=android.hardware.usbUsbDeviceConnection )

についても同様です。 readData() メソッド

https://developer.android.com/reference/android/hardware/usb/UsbDeviceConnection.html