0

我密切关注本教程:http ://assets.en.oreilly.com/1/event/68/Building%20Android%20Accessories%20using%20the%20Open%20Accessory%20Development%20Kit%20and%20Arduino%20Presentation%201 .pdf 但是,我进行了一些修改,以便在每次更新文本时发送 ASCII 值。我仍然无法连接我的 Android 设备(是的,我有多个,从 2.2.3 到 2.2.7 版本)。我一直在屏幕日志中收到输出流为空的错误。任何帮助将不胜感激!

OpenAccessoryTest.java

package org.simonmonk.duinodroid;

import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

import com.android.future.usb.UsbAccessory;
import com.android.future.usb.UsbManager;

public class OpenAccessoryTest extends Activity implements Runnable {

    private EditText mByteField;
    private EditText mResponseField;
    private Button mSendButton;
    private static final String ACTION_USB_PERMISSION = "com.google.android.DemoKit.action.USB_PERMISSION";
    private UsbManager mUsbManager;
    private PendingIntent mPermissionIntent;
    private boolean mPermissionRequestPending;
    private UsbAccessory mAccessory;
    private ParcelFileDescriptor mFileDescriptor;
    private FileInputStream mInputStream;
    private FileOutputStream mOutputStream;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mByteField = (EditText) findViewById(R.id.streamingTextView1);
        mResponseField = (EditText) findViewById(R.id.arduinoresponse);
        mSendButton = (Button) findViewById(R.id.sendButton);
        // String valueStr = mByteField.getText().toString();
        mSendButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                sendMessageToArduino();
            }
        });
        setupAccessory();
    }

    @Override
    public Object onRetainNonConfigurationInstance() {
        if (mAccessory != null) {
            return mAccessory;
        } else {
            return super.onRetainNonConfigurationInstance();
        }
    }

    @Override
    public void onResume() {
        log("Resuming");
        super.onResume();

        if (mInputStream != null && mOutputStream != null) {
            log("Resuming: streams were not null");
            return;
        }
        log("Resuming: streams were null");
        UsbAccessory[] accessories = mUsbManager.getAccessoryList();
        UsbAccessory accessory = (accessories == null ? null : accessories[0]);
        if (accessory != null) {
            if (mUsbManager.hasPermission(accessory)) {
                openAccessory(accessory);
            } else {
                synchronized (mUsbReceiver) {
                    if (!mPermissionRequestPending) {
                        mUsbManager.requestPermission(accessory,
                                mPermissionIntent);
                        mPermissionRequestPending = true;
                    }
                }
            }
        } else {
            log("onResume:mAccessory is null");
        }
    }

    @Override
    public void onPause() {
        log("Pausing");
        super.onPause();
    }

    @Override
    public void onDestroy() {
        log("Destroying");
        unregisterReceiver(mUsbReceiver);
        super.onDestroy();
    }

    Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            ValueMsg t = (ValueMsg) msg.obj;
            log("Arduino sent: " + t.getFlag() + " " + t.getReading());
        }
    };

    private void log(String string) {
        String contents = mResponseField.getText().toString();
        mResponseField.setText(contents + "\n" + string);
    }

    private void setupAccessory() {
        log("In setupAccessory");
        mUsbManager = UsbManager.getInstance(this);
        mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(
                ACTION_USB_PERMISSION), 0);
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
        registerReceiver(mUsbReceiver, filter);
        if (getLastNonConfigurationInstance() != null) {
            mAccessory = (UsbAccessory) getLastNonConfigurationInstance();
            openAccessory(mAccessory);
        }
    }

    private void openAccessory(UsbAccessory accessory) {
        log("In openAccessory");
        mFileDescriptor = mUsbManager.openAccessory(accessory);
        if (mFileDescriptor != null) {
            mAccessory = accessory;
            FileDescriptor fd = mFileDescriptor.getFileDescriptor();
            mInputStream = new FileInputStream(fd);
            mOutputStream = new FileOutputStream(fd);
            Thread thread = new Thread(null, this, "OpenAccessoryTest");
            thread.start();
            alert("openAccessory: Accessory openned");
            log("Attached");
        } else {
            log("openAccessory: accessory open failed");
        }
    }

    private void closeAccessory() {
        log("In closeAccessory");
        try {
            if (mFileDescriptor != null) {
                mFileDescriptor.close();
            }
        } catch (IOException e) {
        } finally {
            mFileDescriptor = null;
            mAccessory = null;
        }
    }

    private int composeInt(byte hi, byte lo) {
        int val = hi & 0xff;
        val *= 256;
        val += lo & 0xff;
        return val;
    }

    @Override
    public void run() {
        int ret = 0;
        byte[] buffer = new byte[16384];
        int i;

        while (true) { // keep reading messages forever. There are prob lots of
                        // messages in the buffer, each 4 bytes
            try {
                ret = mInputStream.read(buffer);
            } catch (IOException e) {
                break;
            }

            i = 0;
            while (i < ret) {
                int len = ret - i;
                if (len >= 2) {
                    Message m = Message.obtain(mHandler);
                    int value = composeInt(buffer[i], buffer[i + 1]);
                    m.obj = new ValueMsg('a', value);
                    mHandler.sendMessage(m);
                }
                i += 2;
            }

        }
    }

    public void sendMessageToArduino() {
        String valueStr = mByteField.getText().toString();

        try {
            for (int x = 0; x < valueStr.length(); x++) {
                sendCommand((byte) valueStr.charAt(x));
                log("Sending to Arduino: " + (byte) valueStr.charAt(x));
            }

        } catch (NumberFormatException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            alert("The Byte should be a number between 0 and 255");
        }

    }

    public void sendCommand(byte value) {
        log("Sent: " + value);
        byte[] buffer = new byte[1];
        buffer[0] = value;
        if (mOutputStream != null) {
            try {
                mOutputStream.write(buffer);
            } catch (IOException e) {
                log("Send failed: " + e.getMessage());
            }
        } else {
            log("Send failed: mOutStream was null");
        }
    }

    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (ACTION_USB_PERMISSION.equals(action)) {
                synchronized (this) {
                    UsbAccessory accessory = UsbManager.getAccessory(intent);
                    if (intent.getBooleanExtra(
                            UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        openAccessory(accessory);
                    } else {
                        log("USB permission denied");
                    }
                }
            } else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
                UsbAccessory accessory = UsbManager.getAccessory(intent);
                if (accessory != null && accessory.equals(mAccessory)) {
                    log("Detached");
                    closeAccessory();
                }
            }
        }
    };

    public void alert(String message) {
        AlertDialog alertDialog = new AlertDialog.Builder(this).create();
        alertDialog.setTitle("Alert");
        alertDialog.setMessage(message);
        alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                return;
            }
        });
        alertDialog.show();
    }
}`

StreamingTextView.java

package org.simonmonk.duinodroid;

import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.widget.EditText;

public class StreamingTextView extends EditText {

    public StreamingTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public StreamingTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public StreamingTextView(Context context) {
        super(context);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        ((OpenAccessoryTest) super.getContext()).sendCommand(toAscii(event));
        return super.onKeyDown(keyCode, event);
    }

    private byte toAscii(KeyEvent event) {
        byte ch = (byte) event.getUnicodeChar();
        if (ch == 0) {
            switch(event.getKeyCode()){
            case KeyEvent.KEYCODE_DEL:
                ch = 8;
                break;
            case KeyEvent.KEYCODE_ENTER:
                ch = 10;
                break;
            }
        }
        return ch;
    }
}

主要的.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Byte 0 (decimal)" />

    <org.simonmonk.duinodroid.StreamingTextView
        android:id="@+id/streamingTextView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="StreamingTextView" >

        <requestFocus />
    </org.simonmonk.duinodroid.StreamingTextView>

    <Button
        android:id="@+id/sendButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Send to Arduino" />

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Log" />

    <EditText
        android:id="@+id/arduinoresponse"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:editable="false"
        android:lines="10" />

</LinearLayout>
4

1 回答 1

0

android 版本必须 > 到 2.2 。我认为开始使用 Google api 版本 2.3.4

于 2012-04-21T15:38:29.210 回答