0

我是嵌入式程序员,也是安卓新手

开发板通过 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 文件,我很确定错误不是由这些文件引起的。

4

1 回答 1

0

我看不到new Node(int nodeId, int[] capabilites, AccessoryControl accessoryControl);任何地方,我认为您需要先构造它,然后才能从值中获取任何东西,因为其中没有值。

于 2012-07-19T23:58:59.730 回答