2013-07-23 94 views
0

在开发基于BluetoothChat示例的应用程序时出现问题,但分为2个活动。蓝牙聊天像应用程序不通信

  1. 主要有蓝牙行动()BTActivity
  2. 聊天(BTCommunication)

我已在BluetoothChatService太下列文件分,但他们不是活动:

  1. 传输:所有处理程序操作
  2. ConnectThread
  3. ConnectedThread
  4. AccpetThread

该应用程序发现解装置,开始连接它,然后崩溃。我试图找出我与蓝牙应用程序相比我做错了什么,但我没有发现问题。

07-23 10:58:43.076: D/AbsListView(17279): unregisterIRListener() is called 
07-23 10:58:43.076: D/AbsListView(17279): unregisterIRListener() is called 
07-23 10:58:43.086: D/BluetoothUtils(17279): isSocketAllowedBySecurityPolicy start : device null 
07-23 10:58:43.086: W/BluetoothAdapter(17279): getBluetoothService() called with no BluetoothManagerCallback 
07-23 10:58:43.106: E/SpannableStringBuilder(17279): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length 
07-23 10:58:43.106: E/SpannableStringBuilder(17279): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length 
07-23 10:58:43.116: D/AbsListView(17279): onDetachedFromWindow 
07-23 10:58:43.116: D/AbsListView(17279): unregisterIRListener() is called 
07-23 10:58:43.116: D/AbsListView(17279): onDetachedFromWindow 
07-23 10:58:43.116: D/AbsListView(17279): unregisterIRListener() is called 
07-23 10:58:44.527: D/AndroidRuntime(17279): Shutting down VM 
07-23 10:58:44.527: W/dalvikvm(17279): threadid=1: thread exiting with uncaught exception (group=0x41d58ac8) 
07-23 10:58:44.537: E/AndroidRuntime(17279): FATAL EXCEPTION: main 
07-23 10:58:44.537: E/AndroidRuntime(17279): java.lang.NullPointerException 
07-23 10:58:44.537: E/AndroidRuntime(17279): at com.example.btaplication.BTActivity$1.handleMessage(BTActivity.java:288) 
07-23 10:58:44.537: E/AndroidRuntime(17279): at android.os.Handler.dispatchMessage(Handler.java:99) 
07-23 10:58:44.537: E/AndroidRuntime(17279): at android.os.Looper.loop(Looper.java:137) 
07-23 10:58:44.537: E/AndroidRuntime(17279): at android.app.ActivityThread.main(ActivityThread.java:5328) 
07-23 10:58:44.537: E/AndroidRuntime(17279): at java.lang.reflect.Method.invokeNative(Native Method) 
07-23 10:58:44.537: E/AndroidRuntime(17279): at java.lang.reflect.Method.invoke(Method.java:511) 
07-23 10:58:44.537: E/AndroidRuntime(17279): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102) 
07-23 10:58:44.537: E/AndroidRuntime(17279): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869) 
07-23 10:58:44.537: E/AndroidRuntime(17279): at dalvik.system.NativeStart.main(Native Method) 
07-23 10:58:55.428: I/Process(17279): Sending signal. PID: 17279 SIG: 9 

/这里的主要活动

public class BTActivity extends Activity { 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.main); 

    final Button button1 = (Button) findViewById(R.id.boton1); 
    final Button button2 = (Button) findViewById(R.id.boton2); 
    final Button button4 = (Button) findViewById(R.id.boton4); 
    final Button button5 = (Button) findViewById(R.id.boton5); 

    button5.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      lanzarComunicacion (null); 
     } 
    }); 


    GlobalVar.mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 

    if (GlobalVar.mBluetoothAdapter == null) { 
     Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show(); 
     finish(); 
     return; 
    } 

    button2.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      LanzarBusqueda(null); 

     } 
    }); 

    button1.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      if (!GlobalVar.mBluetoothAdapter.isDiscovering()) { 

       Context context = getApplicationContext(); 
       CharSequence text = "MAKING YOUR DEVICE DISCOVERABLE"; 
       int duration = Toast.LENGTH_SHORT; 

       Toast toast = Toast.makeText(context, text, duration); 
       toast.show(); 

       Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); 
       discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); 

       startActivity(discoverableIntent); 
      } 
     } 
    }); 

    button4.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      GlobalVar.mBluetoothAdapter.disable(); 

      Context context = getApplicationContext(); 
      CharSequence text = "TURNING OFF BLUETOOTH"; 
      int duration = Toast.LENGTH_LONG; 

      Toast toast = Toast.makeText(context, text, 15); 
      toast.show(); 

     } 
    }); 
} 


@Override 
public void onStart() { 
    super.onStart(); 

    if (!GlobalVar.mBluetoothAdapter.isEnabled()) { 

     Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
     startActivityForResult(enableBtIntent, GlobalVar.REQUEST_ENABLE_BT); 
    } 
    else { 
     if (GlobalVar.mTransmission == null) setupCaller(); 
    } 
} 


@Override 
public void onResume() { 
    super.onResume(); 

    if (GlobalVar.mTransmission != null) { 
     /**Only if the state is STATE_NONE, do we know that we haven't started already*/ 
     if (GlobalVar.mTransmission.getState() == GlobalVar.STATE_NONE) { 

     } 
    } 
} 


@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    switch (requestCode) { 
     case GlobalVar.REQUEST_CONNECT_DEVICE: 
      /**When DeviceListActivity returns with a device to connect*/ 
      if (resultCode == Activity.RESULT_OK) { 
       connectDevice(data); 
      } 
     case GlobalVar.REQUEST_ENABLE_BT: 
      /**When the request to enable Bluetooth returns*/ 
      if (resultCode == Activity.RESULT_OK) { 
       /**Bluetooth is now enabled, so set up a chat session*/ 
       setupCaller(); 
      } else { 
       /**User did not enable Bluetooth or an error occurred*/ 
       Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show(); 
       finish(); 
      } 
      break; 
    } 

} 


private void connectDevice(Intent data) { 
    /**Get the device MAC address*/ 
    String address = data.getExtras().getString(DeviceListDialog.EXTRA_DEVICE_ADDRESS); 
    /**Get the BluetoothDevice object*/ 
    BluetoothDevice device = GlobalVar.mBluetoothAdapter.getRemoteDevice(address); 
    /**Attempt to connect to the device*/ 
    try{ 
     GlobalVar.mTransmission.connect(device); 
    }catch(Exception ex) { 
    } 
} 


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

public void lanzarComunicacion (View view) { 
    Intent i = new Intent(this, BTCommunication.class); 
    startActivity(i); 
} 

public void LanzarBusqueda (View view) { 
    Intent serverintent = new Intent(this, DeviceListDialog.class); 
    startActivityForResult(serverintent, GlobalVar.REQUEST_CONNECT_DEVICE); 
} 


private final void setStatus(int resId) { 
    final ActionBar actionBar = getActionBar(); 
    actionBar.setSubtitle(resId); 
} 

private final void setStatus(CharSequence subTitle) { 
    final ActionBar actionBar = getActionBar(); 
    actionBar.setSubtitle(subTitle); 
} 


/** 
* The Handler that gets information back from the Transmission 
*/ 
private final Handler mHandler = new Handler() { 
    @Override 
    public void handleMessage(Message msg) { 
     switch (msg.what) { 
      case GlobalVar.MESSAGE_STATE_CHANGE: 
       switch (msg.arg1) { 
        case GlobalVar.STATE_CONNECTED: 
         setStatus(getString(R.string.title_connected_to, GlobalVar.mConnectedDeviceName)); 
         GlobalVar.mConversationArrayAdapter.clear(); 
         break; 
        case GlobalVar.STATE_CONNECTING: 
         setStatus(R.string.title_connecting); 
         break; 
        case GlobalVar.STATE_LISTEN: 
        case GlobalVar.STATE_NONE: 
         setStatus(R.string.title_not_connected); 
         break; 
       } 
       break; 
      case GlobalVar.MESSAGE_WRITE: 
       byte[] writeBuf = (byte[]) msg.obj; 
       /**construct a string from the buffer*/ 
       String writeMessage = new String(writeBuf); 
       GlobalVar.mConversationArrayAdapter.add("Me: " + writeMessage); 
       break; 
      case GlobalVar.MESSAGE_READ: 
       byte[] readBuf = (byte[]) msg.obj; 
       /**construct a string from the valid bytes in the buffer*/ 
       String readMessage = new String(readBuf, 0, msg.arg1); 
       GlobalVar.mConversationArrayAdapter.add(GlobalVar.mConnectedDeviceName+": " + readMessage); 
       break; 
      case GlobalVar.MESSAGE_DEVICE_NAME: 
       /**save the connected device's name*/ 
       GlobalVar.mConnectedDeviceName = msg.getData().getString(GlobalVar.DEVICE_NAME); 
       Toast.makeText(getApplicationContext(), "Connected to " + GlobalVar.mConnectedDeviceName, Toast.LENGTH_SHORT).show(); 
       break; 
      case GlobalVar.MESSAGE_TOAST: 
       Toast.makeText(getApplicationContext(), msg.getData().getString(GlobalVar.TOAST), Toast.LENGTH_SHORT).show(); 
       break; 
     } 
    } 
}; 

public void setupCaller() { 
    /**Initialize the Transmission to perform bluetooth connections*/ 
    GlobalVar.mTransmission = new Transmission(this, mHandler); 
} 

}

/在聊天活性起着

public class BTCommunication extends Activity { 


@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    /**Set up the window layout*/ 
    setContentView(R.layout.chat); 

    /**Start the Bluetooth chat services*/ 
    GlobalVar.mTransmission.start(); 
    setupChat(); //PROBAMOS A LLAMAR AQUI\\ 
} 



public void setupChat() { 
    /**Initialize the array adapter for the conversation thread*/ 
    GlobalVar.mConversationArrayAdapter = new ArrayAdapter<String>(this, R.layout.message); 
    GlobalVar.mConversationView = (ListView) findViewById(R.id.in); 
    GlobalVar.mConversationView.setAdapter(GlobalVar.mConversationArrayAdapter); 

    /**Initialize the compose field with a listener for the return key*/ 
    GlobalVar.mOutEditText = (EditText) findViewById(R.id.edit_text_out); 
    GlobalVar.mOutEditText.setOnEditorActionListener(mWriteListener); 

    /**Initialize the send button with a listener that for click events*/ 
    GlobalVar.mSendButton = (Button) findViewById(R.id.button_send); 
    GlobalVar.mSendButton.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      /**Send a message using content of the edit text widget*/ 
      TextView view = (TextView) findViewById(R.id.edit_text_out); 
      String message = view.getText().toString(); 
      sendMessage(message); 
     } 
    }); 

    /**Initialize the Transmission to perform bluetooth connections*/ 
    //Done it in BTActivity in the function "setupCaller()"\\ 


    /**Initialize the buffer for outgoing messages*/ 
    GlobalVar.mOutStringBuffer = new StringBuffer(""); 
} 



@Override 
public void onDestroy() { 
    super.onDestroy(); 
    /**Stop the Bluetooth chat services*/ 
    if (GlobalVar.mTransmission != null) GlobalVar.mTransmission.stop(); 
} 


/** 
* Sends a message. 
* @param message A string of text to send. 
*/ 
public void sendMessage(String message) { 
    /**Check that we're actually connected before trying anything*/ 
    if (GlobalVar.mTransmission.getState() != GlobalVar.STATE_CONNECTED) { 
     Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show(); 
     return; 
    } 

    /**Check that there's actually something to send*/ 
    if (message.length() > 0) { 
     /**Get the message bytes and tell the BluetoothChatService to write*/ 
     byte[] send = message.getBytes(); 
     GlobalVar.mTransmission.write(send); 

     /**Reset out string buffer to zero and clear the edit text field*/ 
     GlobalVar.mOutStringBuffer.setLength(0); 
     GlobalVar. mOutEditText.setText(GlobalVar.mOutStringBuffer); 
    } 
} 

/**The action listener for the EditText widget, to listen for the return key*/ 
private final TextView.OnEditorActionListener mWriteListener = new TextView.OnEditorActionListener() { 
    @Override 
    public boolean onEditorAction(TextView view, int actionId, KeyEvent event) { 
     /**If the action is a key-up event on the return key, send the message*/ 
     if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP) { 
      String message = view.getText().toString(); 
      sendMessage(message); 
     } 
     return true; 
    } 
}; 

}

/唐皇文件:

public class Transmission { 

/** 
* Constructor. Prepares a new session. 
* @param context The UI Activity Context 
* @param handler A Handler to send messages back to the UI Activity 
*/ 
public Transmission(Context context, Handler handler) { 
    GlobalVar.mAdapter = BluetoothAdapter.getDefaultAdapter(); 
    GlobalVar.mState = GlobalVar.STATE_NONE; 
    GlobalVar.mHandler = handler; 
} 

/** 
* Set the current state of the connection 
* @param state An integer defining the current connection state 
*/ 
public synchronized void setState(int state) { 
    GlobalVar.mState = state; 

    /**Give the new state to the Handler so the UI Activity can update*/ 
    GlobalVar.mHandler.obtainMessage(GlobalVar.MESSAGE_STATE_CHANGE, state, -1).sendToTarget(); 
} 

/** 
* Return the current connection state. 
*/ 
public synchronized int getState() { 
    return GlobalVar.mState; 
} 

/** 
* Start the chat service. Specifically start AcceptThread to begin a 
* session in listening (server) mode. Called by the Activity onResume() 
*/ 
public synchronized void start() { 
    /**Cancel any thread attempting to make a connection*/ 
    if (GlobalVar.mConnectThread != null) {GlobalVar.mConnectThread.cancel(); GlobalVar.mConnectThread = null;} 

    /**Cancel any thread currently running a connection*/ 
    if (GlobalVar.mConnectedThread != null) {GlobalVar.mConnectedThread.cancel(); GlobalVar.mConnectedThread = null;} 

    setState(GlobalVar.STATE_LISTEN); 

    /**Start the thread to listen on a BluetoothServerSocket*/ 
    if (GlobalVar.mAcceptThread == null) { 
     GlobalVar.mAcceptThread = new AcceptThread(); 
     GlobalVar.mAcceptThread.start(); 
    } 
} 

/** 
* Start the ConnectThread to initiate a connection to a remote device. 
* @param device The BluetoothDevice to connect 
*/ 
public synchronized void connect(BluetoothDevice device) { 
    /**Cancel any thread attempting to make a connection*/ 
    if (GlobalVar.mState == GlobalVar.STATE_CONNECTING) { 
     if (GlobalVar.mConnectThread != null) {GlobalVar.mConnectThread.cancel(); GlobalVar.mConnectThread = null;} 
    } 

    /**Cancel any thread currently running a connection*/ 
    if (GlobalVar.mConnectedThread != null) {GlobalVar.mConnectedThread.cancel(); GlobalVar.mConnectedThread = null;} 

    /**Start the thread to connect with the given device*/ 
    GlobalVar.mConnectThread = new ConnectThread(device); 
    GlobalVar.mConnectThread.start(); 
    setState(GlobalVar.STATE_CONNECTING); 
} 

/** 
* Start the ConnectedThread to begin managing a Bluetooth connection 
* @param socket The BluetoothSocket on which the connection was made 
* @param device The BluetoothDevice that has been connected 
*/ 
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) { 
    /**Cancel the thread that completed the connection*/ 
    if (GlobalVar.mConnectThread != null) {GlobalVar.mConnectThread.cancel(); GlobalVar.mConnectThread = null;} 

    /**Cancel any thread currently running a connection*/ 
    if (GlobalVar.mConnectedThread != null) {GlobalVar.mConnectedThread.cancel(); GlobalVar.mConnectedThread = null;} 

    /**Cancel the accept thread because we only want to connect to one device*/ 
    if (GlobalVar.mAcceptThread != null) { 
     GlobalVar.mAcceptThread.cancel(); 
     GlobalVar.mAcceptThread = null; 
    } 

    /**Start the thread to manage the connection and perform transmissions*/ 
    GlobalVar.mConnectedThread = new ConnectedThread(socket); 
    GlobalVar.mConnectedThread.start(); 

    /**Send the name of the connected device back to the UI Activity*/ 
    Message msg = GlobalVar.mHandler.obtainMessage(GlobalVar.MESSAGE_DEVICE_NAME); 
    Bundle bundle = new Bundle(); 
    bundle.putString(GlobalVar.DEVICE_NAME, device.getName()); 
    msg.setData(bundle); 
    GlobalVar.mHandler.sendMessage(msg); 

    setState(GlobalVar.STATE_CONNECTED); 
} 

/** 
* Stop all threads 
*/ 
public synchronized void stop() { 

    if (GlobalVar.mConnectThread != null) { 
     GlobalVar.mConnectThread.cancel(); 
     GlobalVar.mConnectThread = null; 
    } 

    if (GlobalVar.mConnectedThread != null) { 
     GlobalVar.mConnectedThread.cancel(); 
     GlobalVar.mConnectedThread = null; 
    } 

    if (GlobalVar.mAcceptThread != null) { 
     GlobalVar.mAcceptThread.cancel(); 
     GlobalVar.mAcceptThread = null; 
    } 

    setState(GlobalVar.STATE_NONE); 
} 

/** 
* Write to the ConnectedThread in an unsynchronized manner 
* @param out The bytes to write 
* @see ConnectedThread#write(byte[]) 
*/ 
public void write(byte[] out) { 
    /**Create temporary object*/ 
    ConnectedThread r; 
    /**Synchronize a copy of the ConnectedThread*/ 
    synchronized (this) { 
     if (GlobalVar.mState != GlobalVar.STATE_CONNECTED) return; 
     r = GlobalVar.mConnectedThread; 
    } 
    /**Perform the write unsynchronized*/ 
    r.write(out); 
} 

/** 
* Indicate that the connection attempt failed and notify the UI Activity. 
*/ 
public void connectionFailed() { 
    /**Send a failure message back to the Activity*/ 
    Message msg = GlobalVar.mHandler.obtainMessage(GlobalVar.MESSAGE_TOAST); 
    Bundle bundle = new Bundle(); 
    bundle.putString(GlobalVar.TOAST, "Unable to connect device"); 
    msg.setData(bundle); 
    GlobalVar.mHandler.sendMessage(msg); 

    /**tart the service over to restart listening mode*/ 
    Transmission.this.start(); 
} 

/** 
* Indicate that the connection was lost and notify the UI Activity. 
*/ 
public void connectionLost() { 
    /**Send a failure message back to the Activity*/ 
    Message msg = GlobalVar.mHandler.obtainMessage(GlobalVar.MESSAGE_TOAST); 
    Bundle bundle = new Bundle(); 
    bundle.putString(GlobalVar.TOAST, "Device connection was lost"); 
    msg.setData(bundle); 
    GlobalVar.mHandler.sendMessage(msg); 

    /**Start the service over to restart listening mode*/ 
    Transmission.this.start(); 
} 

}

/Accept(接受),连接和连接线程一样BleutoothChat应用程序,但每一个都有它自己的文件。

回答

1
07-23 10:58:44.537: E/AndroidRuntime(17279): at com.example.btaplication.BTActivity$1.handleMessage(BTActivity.java:288) 

在Handler中需要更多的条件。它崩溃,因为你的BTActivity中有一个空指针。

2个星期前我正好遇到了这个问题(我试图在Handler中更改textview的文本)。所以,在我的Handler中,我只是说:

if(mTextView == null) {mTextView = (TextView) findViewById(R.id.tv)} 

即使mTextView被定义之前。在这种情况下,你一定会认为你的属性定义,你会避免NPE

希望它可以帮助

+0

OK,所以...我怎么能在我的代码做到这一点?我已经把Handler定义为'private final Handler mHandler = new Handler(){',并且这个警告:Tnis Handler类应该是静态的或者可能发生泄漏。 – masmic

+0

在全局变量文件中,我已经声明它为“public static mhandler” – masmic

+0

嗯,我不知道你在BTActivity的第288行上做了什么。你可以粘贴它吗? –

相关问题