0

今年の夏のロボティクス試験のために、Bluetooth 経由で Android デバイスと通信するロボットを構築しています。この目的のために、私は独自の Android アプリケーションを作成しています。データの送信に問題はありませんが、データを受信できません。動作しないデータを受信するための私のコードは次のようになります。

    new Thread(new Runnable() {
        public void run(){
            byte[] buffer = new byte[1024]; //Buffer for the incoming message
            int bytes; 
            TextView afstandsTekst = (TextView)findViewById(R.id.afstandsText);
            //Listen to the InputStream
            while(true){
                try {
                    if(mmInStream.available() != 0)
                    try {
                        bytes = mmInStream.read(buffer); //Read from the InputStream. This is where the app crashes.
                    }
                    catch(IOException e){
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    break;
                }
                afstandsTekst.setText(String.valueOf(bytes));
            }
        }
    }).start();

アプリがクラッシュする

    bytes = mmInStream.read(buffer);

理由がわかりません。Android Developers の bluetooth ページ (http://developer.android.com/guide/topics/wireless/bluetooth.html#ManagingAConnection) をヘルプとして使用し、彼らとまったく同じように実行しようとしましたが、それでもクラッシュしました、これが、上に貼り付けたコードを試した理由です。また、アプリは正常に実行するとクラッシュしますが、Samsung Galaxy Nexus の Eclipse でデバッグすることを選択すると、アプリケーションはクラッシュしません。その理由はわかりません。

これはこのフォーラムへの私の最初の投稿であり、そこに誰かが答えてくれることを願っています. 前もって感謝します!

編集:コード全体は次のとおりです。

    package skole.migogjesper.hospitalsseng;

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.lang.reflect.Method;
    import java.util.Set;

    import android.app.Activity;
    import android.bluetooth.BluetoothAdapter;
    import android.bluetooth.BluetoothDevice;
    import android.bluetooth.BluetoothSocket;
    import android.bluetooth.BluetoothClass.Device;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.AdapterView.OnItemClickListener;
    import android.widget.ArrayAdapter;
    import android.widget.CheckBox;
    import android.widget.ListView;
    import android.widget.TextView;
    import android.widget.Toast;

    public class HospitalssengActivity extends Activity {
    private String address = "00:06:66:45:B8:DB";
        private static final int REQUEST_ENABLE_BT = 3;
        protected static final String EXTRA_DEVICE_ADDRESS = null;
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        public ArrayAdapter<String> mArrayAdapter;
        BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();                 //Indlæser bluetooth modulet i enheden.
        private BluetoothDevice mmDevice = mBluetoothAdapter.getRemoteDevice(address);
        private OutputStream mmOutStream;
        private InputStream mmInStream;
        private char stueDestination = '0';
        private char scannerDestination = '1';
        private char operationsstueDestination = '2';
        private char krematorieDestination = '3';
        private char xrayDestination = '4';
        private char planlagtStueDestination = 'q';
        private char planlagtScannerDestination = 'w';
        private char planlagtOperationsstueDestination = 'e';
        private char planlagtKrematorieDestination = 'r';
        private char planlagtXrayDestination = 't';
        private byte sendByte;


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    if(mBluetoothAdapter == null){ //Tjekker om bluetooth er underst¯ttet.
        Toast.makeText(HospitalssengActivity.this, "Enheden understøtter ikke bluetooth", Toast.LENGTH_LONG).show();
    }
    if(!mBluetoothAdapter.isEnabled()){ //Tjekker om bluetooth er tÊndt.
        Intent enableBtIntent = new Intent (BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
    }
    new Thread(new Runnable() {
        public void run(){
            byte[] buffer = new byte[1024]; //Buffer til den indkommende besked
            int bytes; //Bytes der kommer fra read()
            TextView afstandsTekst = (TextView)findViewById(R.id.afstandsText);
            //Lyt efter InputStream indtil der sker en exception
            while(true){
                try {
                    if(mmInStream.available() != 0)
                    try {
                        bytes = mmInStream.read(buffer); //Læs fra InputStream
                    }
                    catch(IOException e){
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    break;
                }
                //afstandsTekst.setText(String.valueOf(bytes));
            }
        }
    }).start();
}

private BluetoothSocket mmSocket;

public void Connect(BluetoothDevice device){
    BluetoothSocket tmp = null; //Dette er er et midlertidigt objekt, som senere bliver assigned til mmSocket.
    mmDevice = device;

    try { //Få en BluetoothSocket, som kan bruges til at forbinde med en BluetoothDevice
        Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
        tmp = (BluetoothSocket) m.invoke(device, 1);
    } catch(Exception e) {
        Toast.makeText(HospitalssengActivity.this, "FEJL!", Toast.LENGTH_LONG).show();
    }
    mmSocket = tmp;
    try{  //Forbind enheden gennem socket'en. Dette blokerer indtil den er succesfuld eller den fejler.
        mmSocket.connect();
    } catch (IOException connectException) {
        try{mmSocket.close();}  //Fejlet forbindelse. Luk socket'en og hop ud af metoden.
        catch(IOException closeException) {}
        return;
    }
}

public void cancel(){ //Lukker en forbindelse og lukker socket'en.
    try{mmSocket.close();}
    catch(IOException e) {}
}

public void write(byte sendByte){
    try {
        mmOutStream = mmSocket.getOutputStream();
        mmOutStream.write(sendByte);
        Toast.makeText(HospitalssengActivity.this, "Sendt", Toast.LENGTH_SHORT).show();
    }
    catch (IOException e) {}
}

public void scanKnap(View view){
    Connect(mmDevice);
}

public void afbrydKnap(View view){
    cancel();
}

public void stueKnap(View view){
    CheckBox planlagtCheck = (CheckBox) findViewById(R.id.planlagtCheck);
    if(!planlagtCheck.isChecked()){
        sendByte = (byte) stueDestination;
        write(sendByte);
    }
    if(planlagtCheck.isChecked()){
        sendByte = (byte) planlagtStueDestination;
        write(sendByte);
    }
}

public void scannerKnap(View view){
    CheckBox planlagtCheck = (CheckBox) findViewById(R.id.planlagtCheck);
    if(!planlagtCheck.isChecked()){
        sendByte = (byte) scannerDestination;
    write(sendByte);
    }
    if(planlagtCheck.isChecked()){
        sendByte = (byte) planlagtScannerDestination;
        write(sendByte);
    }
}

public void operationsstueKnap(View view){
    CheckBox planlagtCheck = (CheckBox) findViewById(R.id.planlagtCheck);
    if(!planlagtCheck.isChecked()){
        sendByte = (byte) operationsstueDestination;
        write(sendByte);
    }
    if(planlagtCheck.isChecked()){
        sendByte = (byte) planlagtOperationsstueDestination;
        write(sendByte);
    }
}

public void krematorieKnap(View view){
    CheckBox planlagtCheck = (CheckBox) findViewById(R.id.planlagtCheck);
    if(!planlagtCheck.isChecked()){
        sendByte = (byte) krematorieDestination;
        write(sendByte);
    }
    if(planlagtCheck.isChecked()){
        sendByte = (byte) planlagtKrematorieDestination;
        write(sendByte);
    }
}

public void xrayKnap(View view){
    CheckBox planlagtCheck = (CheckBox) findViewById(R.id.planlagtCheck);
    if(!planlagtCheck.isChecked()){
        sendByte = (byte) xrayDestination;
        write(sendByte);
    }
    if(planlagtCheck.isChecked()){
        sendByte = (byte) planlagtXrayDestination;
        write(sendByte);
    }
}

}

4

2 に答える 2

0

スレッドは使用しないでください。

バックグラウンドのものにはServiceを使用し、スレッドにはThreadの代わりにASyncTaskを使用します。

ヒントとして:サービスとアクティビティの間でローカルにブロードキャストできます!(そのためにAndroidサポートライブラリをインポートする必要があります(LocalBroadcastを参照)。

Androidはすでに別のOS(Linux)の上にOSを意味します。スレッド通信を自分で処理する必要はありません。Androidに任せてください。

于 2012-04-19T12:37:04.890 に答える
0

デバッガーで実行され、正常に実行されない場合、競合状態のように聞こえます。複数のスレッドで使用できると思われる唯一の変数は、mmInStream です。このスレッドの外で mmInStream に対して何をしていますか?

競合状態とは、2 つのスレッドが両方とも共有の可変状態 (この場合は mmInStream) にアクセスできる場合です。1 つのスレッドが勝利して 1 つの結果が表示される場合もあれば、別のスレッドが勝利して別の結果が表示される場合もあります。これらはデバッグが非常に難しい場合があります。

スレッドを作成した場所にコードを投稿できますか?

投稿したコードを見ると、mmInstream が初期化されている場所がわかりません。これにより、報告されたようにヌルポインター例外が発生しますが、デバッガーでも発生します(そのスレッドが実行されなかった場合を除く)。

于 2012-04-17T14:56:46.910 に答える