0

在基于 BluetoothChat 示例开发应用程序时遇到问题,但分为 2 个活动。

  1. 主要带蓝牙动作()BTActivity
  2. 聊天(BTCommunication)

我的 BluetoothChatService 也分为以下文件,但它们不是活动:

  1. 传输:所有 Handler 动作
  2. 连接线程
  3. 连接线程
  4. 接受线程

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

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、connect 和 connected 线程与 BleutoothChat 应用程序中的相同,但每个线程都有自己的文件。

4

1 回答 1

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

您的处理程序需要更多条件。它崩溃是因为您的 BTActivity 中有一个空指针。

两周前我确实遇到了这个问题(我试图在处理程序中更改文本视图的文本)。所以,在我的处理程序中,我只是放了:

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

即使之前定义了 mTextView。在这种情况下,您将确定您的属性已定义,并且您将避免 NPE

希望能帮助到你

于 2013-07-23T09:32:15.947 回答