简体   繁体   中英

Send data over USB to Android app

I have a Java application sending bytes over USB to an Android Device, the issue is it doesn't appear to read any bytes on the Android side

Here's how the information is sent

private static void writeAndRead() throws LibUsbException {
    String question = "Hello Android I'll be your host today, how are you?";

    byte[] questionBuffer = question.getBytes();
    ByteBuffer questionData = BufferUtils.allocateByteBuffer(questionBuffer.length);
    IntBuffer transferred = IntBuffer.allocate(1);

    int result = 0;
    System.out.println("Sending question: " + question);
    System.out.println("Length of buffer: " + questionBuffer.length);
    result = LibUsb.bulkTransfer(handle, END_POINT_OUT_ACC, questionData, transferred, 5000);

    if(result < 0) {
        throw new LibUsbException("Bulk write error!", result);
    }
}

This method seems to complete without throwing an exception and it reports it's sent a buffer length of 51.

On the Android side I have the following

public class MainActivity extends AppCompatActivity  {

    private static final String TAG = "MainActivity";

    private UsbManager manager;
    private UsbAccessory accessory;
    private ParcelFileDescriptor accessoryFileDescriptor;
    private FileInputStream accessoryInput;
    private FileOutputStream accessoryOutput;

    private String question = "";
    private TextView questionTV;

    Runnable updateUI = new Runnable() {
        @Override
        public void run() {
            questionTV.append(question);
        }
    };

    Runnable readQuestionTask = new Runnable() {
        @Override
        public void run() {

            byte[] buffer = new byte[51];
            int ret;

            try {
                ret = accessoryInput.read(buffer);
                Log.d(TAG, "Read: " +ret);
                if (ret == 51) {
                    String msg = new String(buffer);
                    question += " Question: " + msg;
                } else {
                    question += " Read error";
                }
                Log.d(TAG, question);

            } catch (IOException e) {
                Log.e(TAG, "Read error ", e);
                question += " Read error";
            }

            questionTV.post(updateUI);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        questionTV = (TextView) findViewById(R.id.hello_world);
        questionTV.setMovementMethod(new ScrollingMovementMethod());

        Intent intent = getIntent();
        manager = (UsbManager) getSystemService(Context.USB_SERVICE);
        accessory = intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
        if(accessory == null) {
            questionTV.append("Not started by the accessory itself"
                    + System.getProperty("line.separator"));
            return;
        }

        Log.d(TAG, accessory.toString());
        accessoryFileDescriptor = manager.openAccessory(accessory);
        Log.d(TAG, "File Descriptor " +accessoryFileDescriptor.toString());
        if (accessoryFileDescriptor != null) {
            FileDescriptor fd = accessoryFileDescriptor.getFileDescriptor();
            accessoryInput = new FileInputStream(fd);
            accessoryOutput = new FileOutputStream(fd);
        }
        new Thread(readQuestionTask).start();

    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

}

The following section of code

        try {
            ret = accessoryInput.read(buffer);
            Log.d(TAG, "Read: " +ret);
            if (ret == 51) {
                String msg = new String(buffer);
                question += " Question: " + msg;
            } else {
                question += " Read error";
            }
            Log.d(TAG, question);

        } catch (IOException e) {
            Log.e(TAG, "Read error ", e);
            question += " Read error";
        }

Reports in the console the contents of the question String as being

09-18 09:58:30.084  26198-26221/com.example.paulstatham.testusb D/MainActivity﹕ Read: 51
09-18 09:58:30.084  26198-26221/com.example.paulstatham.testusb D/MainActivity﹕ Question: ������������������������������������������������������������������������������������������������������

The activity itself just shows it as "Question: "

I'm assuming these strange characters are just the default byte value when byte array was first assigned byte[] buffer = new byte[51];

Unfortunately the nature of the app makes it very difficult to debug.

Any suggestions as to why ret = accessoryInput.read(buffer); doesn't appear to read anything?

EDIT: Actually it is reading something as accessoryInput.read(buffer); will block until there is input, and it's not blocking.

So why is the byte[] filled with garbage?

I thought it might have something to do with the fact that a ByteBuffer is sent

LibUsb.bulkTransfer(handle, END_POINT_OUT_ACC, questionData, transferred, 5000);

But I tried converting it in Android

ByteBuffer buf = ByteBuffer.wrap(buffer);
String msg = new String(buf.array());
question += " Question: " + msg;

And it gave me the same garbage characters

Yet again answering my own question, the issue was here

String question = "Hello Android I'll be your host today, how are you?";

byte[] questionBuffer = question.getBytes();
ByteBuffer questionData = BufferUtils.allocateByteBuffer(questionBuffer.length);
IntBuffer transferred = IntBuffer.allocate(1);

I never actually put the byte[] in to the ByteBuffer

questionData.put(questionBuffer) solves the issue!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM