1

我的应用程序使用蓝牙连接来远程控制机器人,但我无法写入它(向机器人发送字节),因为我遇到了一个非常奇怪的致命错误。

这是我处理蓝牙连接的应用程序类,我需要把它放在那里,因为多个活动使用该连接(当时只有一个)。代码取自 BluetoothChat 示例。

public class BluetoothRemoteControlApp extends Application {
    // . . .

    private class ConnectThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final BluetoothDevice mmDevice;

        // . . .

        public void run() {
            try {
                // blocking function, error is here
                mmSocket.connect();
            } catch (IOException e) {
                try {
                    mmSocket.close();
                } catch (IOException e2) {
                    e2.printStackTrace();
                }
                connectionFailed();
                return;
            }

            synchronized (BluetoothRemoteControlApp.this) {
                mConnectThread = null;
            }

            // start connected thread
            connected(mmSocket, mmDevice);
        }
    }

    private class ConnectedThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;

        // . . .

        public void write(byte[] buffer) {
            try {
                mmOutStream.write(buffer);
                communicationHandler.obtainMessage(BT_WRITE, -1, -1, buffer).sendToTarget();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void write(String data) {
        byte[] out = data.getBytes();
        // Create temporary object
        ConnectedThread r;
        // Synchronize a copy of the ConnectedThread
        synchronized (this) {
            r = mConnectedThread;
        }
        // Perform the write unsynchronized
        // This is where my app fails (commenting here makes my app run)
        r.write(out);
    }

    // . . .
}

具体来说,我的应用程序在函数r.write(out);内部失败。write(String data)我从另一个使用手机加速度计的活动中调用它,如下所示:

public class AccelerometerControl extends Activity implements SensorEventListener {
    BluetoothRemoteControlApp appState;

    // . . .

    protected void onCreate(Bundle savedInstanceState) {
        // . . .

        appState = (BluetoothRemoteControlApp) getApplicationContext();
    }

    public void onSensorChanged(SensorEvent event) {
        // . . .

        // send data to robot
        appState.write("s,"+wheelLeft+","+wheelRight);
    }
}

我得到的错误日志是这样的:

08-16 21:33:39.471: E/AndroidRuntime(13644): FATAL EXCEPTION: main
08-16 21:33:39.471: E/AndroidRuntime(13644): java.lang.NullPointerException
08-16 21:33:39.471: E/AndroidRuntime(13644):    at com.bluetooth.BluetoothRemoteControlApp.write(BluetoothRemoteControlApp.java:212)
08-16 21:33:39.471: E/AndroidRuntime(13644):    at com.bluetooth.activities.AccelerometerControl.onSensorChanged(AccelerometerControl.java:170)
08-16 21:33:39.471: E/AndroidRuntime(13644):    at android.hardware.SensorManager$ListenerDelegate$1.handleMessage(SensorManager.java:580)
08-16 21:33:39.471: E/AndroidRuntime(13644):    at android.os.Handler.dispatchMessage(Handler.java:99)
08-16 21:33:39.471: E/AndroidRuntime(13644):    at android.os.Looper.loop(Looper.java:137)
08-16 21:33:39.471: E/AndroidRuntime(13644):    at android.app.ActivityThread.main(ActivityThread.java:4424)
08-16 21:33:39.471: E/AndroidRuntime(13644):    at java.lang.reflect.Method.invokeNative(Native Method)
08-16 21:33:39.471: E/AndroidRuntime(13644):    at java.lang.reflect.Method.invoke(Method.java:511)
08-16 21:33:39.471: E/AndroidRuntime(13644):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
08-16 21:33:39.471: E/AndroidRuntime(13644):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
08-16 21:33:39.471: E/AndroidRuntime(13644):    at dalvik.system.NativeStart.main(Native Method)

我不明白出了什么问题, NullPointerException 很酷,但对我没有多大帮助。第 212 行是该r.write(out);行。

编辑

问题是内部ConnectThread没有mmSocket.connect();进一步(它是一个阻塞函数)。我的连接没有建立,但也没有失败,因此mConnectedThread从未创建。尝试写入null对象时出现 NullPointerException。

对于这个新问题,我能想到的唯一解决方案是创建一个超时线程,然后进行某种“握手”,以便我的手机将我的设备识别为合法机器人,以防用户选择了错误的设备。

4

0 回答 0