私のアプリは Bluetooth 接続を使用してロボットをリモート制御していますが、非常に奇妙な致命的エラーが発生するため、ロボットに書き込む (ロボットにバイトを送信する) ことができません。
これは、Bluetooth 接続を処理する Application クラスです。複数のアクティビティが接続を使用するため (一度に 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 が発生しました。
この新しい問題に対して私が考えることができる唯一の解決策は、ユーザーが間違ったデバイスを選択した場合に、私の電話が正当なロボットとして私のデバイスを認識できるように、タイムアウト スレッドを作成してから、ある種の「ハンドシェイク」を作成することです。