我是嵌入式程序员,也是安卓新手
开发板通过 USB 发送了新消息,我编写了 java 代码来接受该消息并将其显示在 android 设备上。但是应用程序崩溃了,这里是 LogCat
D/UsbDeviceManager( 163): entering USB accessory mode: UsbAccessory[mManufacturer=Embedded Artists AB, mModel=AOA Board - Nodes, mDescription=Demo - AOA Nodes, mVersion=1.0, mUri=http://www.embeddedartists.com/_aoa/Demo_AOA_Nodes.apk, mSerial=N/A]
I/ActivityManager( 163): START {flg=0x10000000 cmp=com.android.systemui/.usb.UsbConfirmActivity (has extras)} from pid 163
I/ActivityManager( 163): Displayed com.android.systemui/.usb.UsbConfirmActivity: +71ms
I/ActivityManager( 163): START {act=android.hardware.usb.action.USB_ACCESSORY_ATTACHED flg=0x10000000 cmp=com.embeddedartists.aoa.nodes/.MainActivity (has extras)} from pid 315
I/EA AOA CAN(30663): onResume
I/EA AOA (30663): Receiver.run
I/EA AOA (30663): Recv Node Add: id=144, capLen=7
I/EA AOA (30663): Recv Node id=144, CapId= 16, data=2650
I/ActivityManager( 163): Displayed com.embeddedartists.aoa.nodes/.MainActivity: +97ms
D/OpenGLRenderer( 315): Flushing caches (mode 0)
I/EA AOA (30663): Recv Node id=144, CapId= 32, data=227
I/EA AOA (30663): Recv Node id=144, CapId= 48, data=0
D/OpenGLRenderer( 315): Flushing caches (mode 1)
I/EA AOA (30663): Recv Node id=144, CapId= 32, data=245
I/EA AOA (30663): Recv Node id=144, CapId= 96, data=245
D/AndroidRuntime(30663): Shutting down VM
W/dalvikvm(30663): threadid=1: thread exiting with uncaught exception (group=0x40a471f8)
E/AndroidRuntime(30663): FATAL EXCEPTION: main
E/AndroidRuntime(30663): java.lang.NullPointerException
E/AndroidRuntime(30663): at com.embeddedartists.aoa.nodes.NodeView$1.handleMessage(NodeView.java:171)
E/AndroidRuntime(30663): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(30663): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(30663): at android.app.ActivityThread.main(ActivityThread.java:4424)
E/AndroidRuntime(30663): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(30663): at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(30663): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
E/AndroidRuntime(30663): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
E/AndroidRuntime(30663): at dalvik.system.NativeStart.main(Native Method)
W/ActivityManager( 163): Force finishing activity com.embeddedartists.aoa.nodes/.MainActivity
D/dalvikvm( 163): GC_FOR_ALLOC freed 401K, 24% free 12582K/16391K, paused 54ms
W/ActivityManager( 163): Activity pause timeout for ActivityRecord{4134eaf0 com.embeddedartists.aoa.nodes/.MainActivity}
I/EA AOA (30663): Recv Node id=144, CapId= 32, data=222
I/EA AOA (30663): Recv Node id=144, CapId= 96, data=222
I/EA AOA (30663): Recv Node id=144, CapId= 32, data=233
I/EA AOA (30663): Recv Node id=144, CapId= 96, data=233
I/Process (30663): Sending signal. PID: 30663 SIG: 9
W/InputDispatcher( 163): channel '41356ab0 com.embeddedartists.aoa.nodes/com.embeddedartists.aoa.nodes.MainActivity (server)' ~ Consumer closed input channel or an error occurred. events=0x8
E/InputDispatcher( 163): channel '41356ab0 com.embeddedartists.aoa.nodes/com.embeddedartists.aoa.nodes.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
W/InputDispatcher( 163): Attempted to unregister already unregistered input channel '41356ab0 com.embeddedartists.aoa.nodes/com.embeddedartists.aoa.nodes.MainActivity (server)'
I/ActivityManager( 163): Process com.embeddedartists.aoa.nodes (pid 30663) has died.
I/WindowManager( 163): WIN DEATH: Window{410e8e00 com.embeddedartists.aoa.nodes/com.embeddedartists.aoa.nodes.MainActivity paused=false}
W/ActivityManager( 163): Force removing ActivityRecord{4109b628 com.embeddedartists.aoa.nodes/.MainActivity}: app died, no saved state
I/WindowManager( 163): WIN DEATH: Window{41356ab0 com.embeddedartists.aoa.nodes/com.embeddedartists.aoa.nodes.MainActivity paused=false}
I/WindowManager( 163): WINDOW DIED Window{41356ab0 com.embeddedartists.aoa.nodes/com.embeddedartists.aoa.nodes.MainActivity paused=false}
W/InputManagerService( 163): Got RemoteException sending setActive(false) notification to pid 30663 uid 10012
D/UsbDeviceManager( 163): exited USB accessory mode
D/MtpService(25247): addStorageLocked 65537 /mnt/sdcard
D/MtpService(25247): starting MTP server in MTP mode
D/MtpService(25247): addStorageLocked 65537 /mnt/sdcard
D/dalvikvm( 315): GC_CONCURRENT freed 332K, 58% free 8215K/19271K, paused 6ms+5ms
我从 LogCat 中发现,NodeView.java 中的 Handler 导致了异常。在第 171 行,它从 Node.java 调用 getValue()。您可以在下面找到这两个 java 文件。
case Node.DEV_ACCL_X:
val = Integer.toString(v);
break;
这些是我添加到正常工作的预先存在的代码库中的行。我明白问题是什么。我看到新消息正在从 USB(开发板)的另一端正确发送我还在应用程序中看到新消息,就在它崩溃 I/EA AOA (30663) 之前:Recv Node id=144, CapId = 96,数据 = 245
那么为什么会有 NullPointerException 呢?哪位高手能指出错误吗?我在解释 LogCat 时也可能是错误的,如果是这样,请指出这一点,以便我可以分享适当的代码。
提前致谢!
#####更新### 完整代码节点视图.java
/*****************************************************************************
*
* Copyright(C) 2011, Embedded Artists AB
* All rights reserved.
*
******************************************************************************
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* Embedded Artists AB assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. Embedded Artists AB
* reserves the right to make changes in the software without
* notification. Embedded Artists AB also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
*****************************************************************************/
package com.embeddedartists.aoa.nodes;
import java.util.HashMap;
import java.util.Map;
import com.embeddedartists.aoa.nodes.R;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class NodeView extends LinearLayout implements Node.OnValueChangeListener {
/**************************************************************************
* Private variables
*************************************************************************/
private TextView nodeIdView;
private Node node;
private Map<Integer, TextView> values;
private static final int VALUE_UPDATED = 0;
/**************************************************************************
* Constructor
*************************************************************************/
/**
* Create a NodeView
* @param context context
* @param node node associated with this view
*/
public NodeView(Context context, Node node) {
super(context);
this.node = node;
this.setOrientation(VERTICAL);
values = new HashMap<Integer, TextView>();
node.addOnValueChangeListener(this);
nodeIdView = new TextView(context);
nodeIdView.setTextSize(24);
nodeIdView.setText("Node: " + node.getNodeId());
addView(nodeIdView, new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
LinearLayout capLayout = new LinearLayout(context);
capLayout.setOrientation(HORIZONTAL);
addView(capLayout, new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
int[] caps = node.getCapabilities();
for (int i = 0; i < caps.length; i++) {
LinearLayout vl = new LinearLayout(context);
vl.setOrientation(HORIZONTAL);
vl.setMinimumWidth(110);
ImageView iv = getImageView(context, caps[i]);
if (iv == null) continue;
iv.setPadding(0, 0, 10, 5);
vl.addView(iv, new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
TextView tv = new TextView(context);
tv.setText("" + node.getValue(caps[i]));
vl.addView(tv, new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
// Mapping capability with the TextView that holds its value.
// A limitation with using the capability type as key is
// that a node can only have one capability of each type
values.put(Integer.valueOf(caps[i]), tv);
capLayout.addView(vl, new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
}
/**************************************************************************
* Public methods
*************************************************************************/
/**
* Get Node associated with this NodeView
* @return
*/
public Node getNode() {
return this.node;
}
/**
* OnValueChangeListener
*/
public void onValueChange(int capId) {
Message m = Message.obtain(handler, VALUE_UPDATED);
m.arg1 = capId;
handler.sendMessage(m);
}
/**************************************************************************
* Private methods
*************************************************************************/
/**
* Get ImageView given a capability
* @param context
* @param capability capability ID
* @return ImageView
*/
private ImageView getImageView(Context context, int capability) {
ImageView iv = null;
switch (capability) {
case Node.DEV_TEMP:
iv = new ImageView(context);
iv.setImageResource(R.drawable.temperature);
break;
case Node.DEV_LIGHT:
iv = new ImageView(context);
iv.setImageResource(R.drawable.lightbulb);
break;
case Node.DEV_BTN:
iv = new ImageView(context);
iv.setImageResource(R.drawable.button);
break;
}
return iv;
}
private final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
case VALUE_UPDATED:
TextView tv = values.get(msg.arg1);
tv.setText(node.getValue(msg.arg1));
break;
}
}
};
}
节点.java
/*****************************************************************************
*
* Copyright(C) 2011, Embedded Artists AB
* All rights reserved.
*
******************************************************************************
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* Embedded Artists AB assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. Embedded Artists AB
* reserves the right to make changes in the software without
* notification. Embedded Artists AB also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
*****************************************************************************/
package com.embeddedartists.aoa.nodes;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class Node {
/**************************************************************************
* Public constants
*************************************************************************/
public static final int DEV_TEMP = (0x01 << 4);
public static final int DEV_LIGHT = (0x02 << 4);
public static final int DEV_BTN = (0x03 << 4);
public static final int DEV_RGB = (0x04 << 4);
public static final int DEV_LED = (0x05 << 4);
public static final int DEV_ACCL_X = (0x06 << 4);
// public static final int DEV_ACCL_Y = (0x07 << 4);
// public static final int DEV_ACCL_Z = (0x08 << 4);
/**************************************************************************
* Private variables
*************************************************************************/
private int nodeId;
private Map<Integer, Integer> values;
private int[] capabilities;
private AccessoryControl accessoryControl;
private ArrayList<OnValueChangeListener> listeners;
/**************************************************************************
* Public interface
*************************************************************************/
public interface OnValueChangeListener {
public void onValueChange(int capId);
}
/**************************************************************************
* Constructor
*************************************************************************/
/**
* Create a new Node
*
* @param nodeId the unique ID of the Node
* @param capabilites node capabilities is an array with capability IDs
* DEV_TEMP, DEV_LIGHT, ...
*/
public Node (int nodeId, int[] capabilites, AccessoryControl accessoryControl) {
this.nodeId = nodeId;
this.capabilities = capabilites;
this.accessoryControl = accessoryControl;
listeners = new ArrayList<OnValueChangeListener>();
values = new HashMap<Integer, Integer>();
for (int i = 0; i < capabilities.length; i++) {
values.put(Integer.valueOf(capabilites[i]), 0);
}
}
/**************************************************************************
* Public methods
*************************************************************************/
/**
* Get Node ID
* @return the node ID
*/
public int getNodeId() {
return nodeId;
}
/**
* Get Node capabilities
* @return node capabilities
*/
public int[] getCapabilities() {
return capabilities;
}
/**
* Add value change listener
* @param l listener to add
*/
public void addOnValueChangeListener(OnValueChangeListener l) {
listeners.add(l);
}
/**
* Remove value change listener
* @param l listener to remove
*/
public void removeOnValueChangeListener(OnValueChangeListener l) {
listeners.remove(l);
}
/**
* Update the value of a capability in this node object
*
* @param capId capability ID
* @param value value to set
*/
public void setValue(int capId, int value) {
values.put(Integer.valueOf(capId), Integer.valueOf(value));
for (OnValueChangeListener l : listeners) {
l.onValueChange(capId);
}
}
/**
* Get the value of a specific capability
* @param capId capability ID
* @return the value of the capability
*/
public String getValue(int capId) {
String val = "";
int v = values.get(Integer.valueOf(capId));
switch (capId) {
case Node.DEV_TEMP:
val = Double.toString( ((double)v)/100 );
break;
case Node.DEV_LIGHT:
val = Integer.toString(v);
break;
case Node.DEV_BTN:
val = Integer.toString(v);
break;
case Node.DEV_ACCL_X:
val = Integer.toString(v);
break;
/* case Node.DEV_ACCL_Y:
val = Integer.toString(v);
break;
case Node.DEV_ACCL_Z:
val = Integer.toString(v);
break; */
}
return val;
}
/**
* Set the RGB LED on the node. A message will be sent
* to the attached accessory
*/
private void setRgb(int led, boolean on) {
byte[] data = new byte[5];
data[0] = AccessoryControl.MESSAGE_OUT_SET_VALUE;
data[1] = (byte)this.nodeId;
data[2] = DEV_RGB;
data[3] = (byte)led;
data[4] = (byte)(on ? 1 : 0);
accessoryControl.writeCommand(data);
}
/**
* Set Red LED
* @param on true if LED should be turned on
*/
public void setRedLed(boolean on) {
setRgb(AccessoryControl.MESSAGE_RGB_VAL_RED, on);
}
/**
* Set Blue LED
* @param on true if LED should be turned on
*/
public void setBlueLed(boolean on) {
setRgb(AccessoryControl.MESSAGE_RGB_VAL_BLUE, on);
}
/**
* Set Green LED
* @param on true if LED should be turned on
*/
public void setGreenLed(boolean on) {
setRgb(AccessoryControl.MESSAGE_RGB_VAL_GREEN, on);
}
/**
* Set LED state. A message will be sent to the Accessory
*
* @param on true if the LED should be turned on
*/
public void setLed(boolean on) {
byte[] data = new byte[5];
data[0] = AccessoryControl.MESSAGE_OUT_SET_VALUE;
data[1] = (byte)this.nodeId;
data[2] = DEV_LED;
data[3] = 0;
data[4] = (byte)(on ? 1 : 0);
accessoryControl.writeCommand(data);
}
}
AccessoryControl.java(节点正在接收器中构建)
/*****************************************************************************
*
* Copyright(C) 2011, Embedded Artists AB
* All rights reserved.
*
******************************************************************************
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* Embedded Artists AB assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. Embedded Artists AB
* reserves the right to make changes in the software without
* notification. Embedded Artists AB also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
*****************************************************************************/
package com.embeddedartists.aoa.nodes;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import com.android.future.usb.UsbAccessory;
import com.android.future.usb.UsbManager;
public class AccessoryControl {
public static final String ACTION_USB_PERMISSION =
"com.embeddedartists.aoa.nodes.MainActivity.action.USB_PERMISSION";
/*
* Message indexes for messages sent from the Accessory
*/
public static final byte MESSAGE_IN_NODE_ADD = 0;
public static final byte MESSAGE_IN_NODE_REMOVE = 1;
public static final byte MESSAGE_IN_NODE_VALUE = 2;
/*
* Message indexes for messages sent to the Accessory
*/
public static final byte MESSAGE_OUT_SET_VALUE = 10;
/*
* Special messages to/from the accessory
*/
/**
* Sent to the accessory to indicate that the application is
* ready to receive data.
*/
private static final byte MESSAGE_CONNECT = 98;
/**
* Sent to the accessory to indicate that the application is
* closing. The accessory acks the message using the same
* ID/index.
*/
private static final byte MESSAGE_DISCONNECT = 99;
/*
*
*/
public static final int MESSAGE_RGB_VAL_RED = 0x01;
public static final int MESSAGE_RGB_VAL_BLUE = 0x02;
public static final int MESSAGE_RGB_VAL_GREEN = 0x04;
/** Manufacturer string expected from the Accessory */
private static final String ACC_MANUF = "Embedded Artists AB";
/** Model string expected from the Accessory */
private static final String ACC_MODEL = "AOA Board - Nodes";
/** Tag used for logging */
private static final String TAG = "EA AOA";
public enum OpenStatus {
CONNECTED, REQUESTING_PERMISSION, UNKNOWN_ACCESSORY, NO_ACCESSORY, NO_PARCEL
}
private boolean permissionRequested = false;
private boolean isOpen = false;
private UsbManager usbManager;
private Context context;
private ParcelFileDescriptor parcelFileDescriptor;
private FileOutputStream accOutputStream;
private Receiver receiver;
private NodeList nodeList;
private static AccessoryControl instance;
/**
* Private constructor
*/
private AccessoryControl() {
nodeList = NodeList.getInstance();
}
/**
* Get instance of AccecssoryControl
* @return instance
*/
public static AccessoryControl getInstance() {
if (instance == null) {
instance = new AccessoryControl();
}
return instance;
}
/**
* Initialize with context
*
* @param context
*/
public void init(Context context) {
this.context = context;
usbManager = UsbManager.getInstance(context);
}
/**
* Open the accessory and establish a connection. This method will
* check if there is any accessory connected to the device, request
* permissions if necessary and then establish input and output
* streams to/from the accessory.
*
* @return status of the Open call.
*/
public OpenStatus open() {
if (isOpen) {
return OpenStatus.CONNECTED;
}
UsbAccessory[] accList = usbManager.getAccessoryList();
if (accList != null && accList.length > 0) {
if (usbManager.hasPermission(accList[0])) {
return open(accList[0]);
}
else if (!permissionRequested) {
PendingIntent permissionIntent = PendingIntent.getBroadcast(
context, 0, new Intent(ACTION_USB_PERMISSION), 0);
Log.i(TAG, "Requesting USB permission");
usbManager.requestPermission(accList[0], permissionIntent);
permissionRequested = true;
return OpenStatus.REQUESTING_PERMISSION;
}
}
return OpenStatus.NO_ACCESSORY;
}
/**
* Open an accessory. This method should be called if an accessory
* object has already been obtained. The method will establish the
* connection and start receiver thread.
*
* @param accessory an instance of UsbAccessory
* @return status of the Open call
*/
public OpenStatus open(UsbAccessory accessory) {
if (isOpen) {
return OpenStatus.CONNECTED;
}
// check if it is a known and supported accessory
if (!ACC_MANUF.equals(accessory.getManufacturer())
|| !ACC_MODEL.equals(accessory.getModel())) {
Log.i(TAG, "Unknown accessory: " + accessory.getManufacturer()
+ ", " + accessory.getModel());
return OpenStatus.UNKNOWN_ACCESSORY;
}
parcelFileDescriptor = usbManager.openAccessory(accessory);
if (parcelFileDescriptor != null) {
byte[] data = new byte[1];
accOutputStream = new FileOutputStream(parcelFileDescriptor.getFileDescriptor());
receiver = new Receiver(new FileInputStream(parcelFileDescriptor.getFileDescriptor()));
isOpen = true;
new Thread(receiver).start();
// notify the accessory that we are now ready to receive data
data[0] = MESSAGE_CONNECT;
writeCommand(data);
return OpenStatus.CONNECTED;
}
Log.i(TAG, "Couldn't get any ParcelDescriptor");
return OpenStatus.NO_PARCEL;
}
/**
* Close the connection with the accessory.
*/
public void close() {
if (!isOpen) {
return;
}
permissionRequested = false;
isOpen = false;
try {
receiver.close();
accOutputStream.close();
parcelFileDescriptor.close();
} catch (IOException ioe) {
Log.w(TAG, "Got exception when closing", ioe);
}
}
/**
* Call this method when the application is closing. This method
* will notify the accessory that the application is about to
* be closed.
*/
public void appIsClosing() {
byte[] data = new byte[1];
if (!isOpen) {
return;
}
Log.i(TAG, "Sending Disconnect message to accessory");
data[0] = AccessoryControl.MESSAGE_DISCONNECT;
writeCommand(data);
long t = System.currentTimeMillis() + 5000;
try {
while (!receiver.done && System.currentTimeMillis() < t) {
Thread.sleep(200);
}
} catch(InterruptedException ie) {
}
}
/**
* Write/send a command to the accessory. For simplicity all messages
* are 3 bytes long; command index and two data bytes.
*
* @param cmd - command index
* @param hiVal - first data byte
* @param loVal - second data byte
*/
public void writeCommand(byte[] buffer) {
if (!isOpen) {
return;
}
try {
synchronized(accOutputStream) {
accOutputStream.write(buffer);
}
} catch(IOException ioe) {
}
}
/*
* The receiver thread. This Thread is responsible for reading
* data from the Accessory and dispatching messages to the Handler
* (UI thread)
*/
private class Receiver implements Runnable {
private FileInputStream inputStream;
private boolean done = false;
Receiver(FileInputStream inputStream) {
this.inputStream = inputStream;
}
public void run() {
int msgLen = 0;
int numRead = 0;
int pos = 0;
byte[] buffer = new byte[16384];
Log.i(TAG, "Receiver.run");
try {
while(!done) {
numRead = inputStream.read(buffer);
pos = 0;
while(pos < numRead) {
int len = numRead - pos;
switch(buffer[pos]) {
case AccessoryControl.MESSAGE_IN_NODE_ADD:
msgLen = 3;
if (len >= 3) {
int nodeId = (int) (buffer[pos+1] & 0xff);
int capLen = (int) (buffer[pos+2] & 0xff);
Log.i(TAG, "Recv Node Add: id="+nodeId+", capLen="+capLen);
msgLen += capLen;
int[] caps = new int[capLen];
int maxLen = caps.length;
if (maxLen > len-3) {
maxLen = len-3;
}
for (int i = 0; i < maxLen; i++) {
caps[i] = (int) (buffer[pos+3+i] & 0xff);
}
Node n = new Node(nodeId, caps, AccessoryControl.this);
nodeList.addNode(n);
}
pos += msgLen;
break;
case AccessoryControl.MESSAGE_IN_NODE_REMOVE:
Log.i(TAG, "Recv Node Remove: id="+(buffer[pos+1] & 0xff));
if (len >= 2) {
nodeList.removeNode((int) (buffer[pos+1] & 0xff));
}
pos += 2;
break;
case AccessoryControl.MESSAGE_IN_NODE_VALUE:
if (len >= 5) {
int nodeId = (int) (buffer[pos+1] & 0xff);
int capId = (int) (buffer[pos+2] & 0xff);
Node n = nodeList.getNodeWithId(nodeId);
if (n != null) {
Log.i(TAG, "Recv Node id="+nodeId+", CapId= "+capId+", data="+toInt(buffer[pos + 3], buffer[pos + 4]));
n.setValue(capId, toInt(buffer[pos + 3], buffer[pos + 4]));
}
}
pos += 5;
break;
case AccessoryControl.MESSAGE_DISCONNECT:
Log.i(TAG, "Received Disconnect (ACK) message from accessory");
// We want to make sure the Receive thread ends at this point
// and doesn't start reading data
done = true;
pos = numRead;
break;
default:
// invalid message (or out of sync)
Log.w(TAG, "Unknown command: " + buffer[pos]);
pos += len;
break;
}
}
}
} catch (IOException ioe) {
}
}
/**
* Close the receiver thread.
*/
public void close() {
done = true;
try {
inputStream.close();
} catch(IOException ioe) {
}
}
/** Convert two bytes to an integer */
private int toInt(byte hi, byte lo) {
return (( (int)(hi&0xff) << 8) | (int)(lo&0xff));
}
};
}
MainActivity.java(这是主文件) http://pastie.org/private/ga1skp82s3b1eeslluenw
NodeActivity.java (另一个已从原始代码库编辑的文件) http://pastie.org/private/cgcuizhdtnhg7tgsg5zcg
还有两个 java 文件,我很确定错误不是由这些文件引起的。