2012-07-19 53 views
0

我是一个嵌入式程序员,一个新手的接收处理程序的Android空指针异常的USB附件

有通过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是导致异常。在第171行,它从Node.java调用getValue()。在下面你可以找到两个java文件。

case Node.DEV_ACCL_X: 
val = Integer.toString(v); 
break; 

这些是我已经添加到预先存在的代码库,这是正常工作的行。 我明白问题是什么。我看到新消息正在从USB的另一端正确发送(开发板),我也在应用中看到新消息,就在它崩溃之前 I/EA AOA(30663):Recv节点ID = 144, CapId = 96,data = 245

那么为什么会出现NullPointerException呢?任何专家都可以指出错误吗? 我也可能在解释LogCat时出错,如果有的话请指出,以便我可以分享适当的代码。

在此先感谢!

##### 更新 ###完成代码

NodeView.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;          
     } 
    } 

};  


} 

Node.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文件,而且我敢肯定(已经从原来的基本代码编辑另一个文件)错误不是由于这些文件。

+1

在你的NodeView中,哪行是171? – FoamyGuy 2012-07-19 23:34:47

+0

林猜测它的'tv.setText(node.getValue(msg.arg1));' – FabianCook 2012-07-19 23:53:00

+0

是的,我保证它是它的handleMessage所以是的...你真的创建节点?就像你在调用构造函数一样,只有我可以看到可能为空的值是散列值散列图 – FabianCook 2012-07-19 23:57:18

回答

0

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

+0

我正在构建另一个文件中的节点,我将复制粘贴整个代码。我再次道歉! – user1539284 2012-07-20 15:47:34