0

对于今年夏天的机器人考试,我正在构建一个机器人,我想通过蓝牙与 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 使用蓝牙页面寻求帮助(http://developer.android.com/guide/topics/wireless/bluetooth.html#ManagingAConnection),并尝试完全按照他们的方式进行操作,但仍然崩溃,这就是为什么我现在尝试了上面粘贴的代码。此外,即使应用程序在正常运行时崩溃,当我选择在三星 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 用于后台内容,对于线程使用 ASyncTask 而不是 Thread!

提示:您可以在服务和活动之间进行本地广播!(您必须为此导入 android 支持库(请参阅 LocalBroadcast)。

Android 已经意味着操作系统位于另一个操作系统(Linux)之上。您不需要自己处理线程通信,让 Android 来处理!

于 2012-04-19T12:37:04.890 回答
0

如果它在调试器中运行而不是通常听起来像一个竞争条件。似乎在多个线程中可用的唯一变量是 mmInStream。你在这个线程之外对 mmInStream 做了什么?

竞争条件是两个线程都可以访问共享的可变状态(在本例中为 mmInStream)。有时一个线程获胜,您会看到一个结果,而另一次另一个线程获胜,您会看到另一个结果。这些东西可能很难调试。

您可以在创建线程的位置发布代码吗?

查看您发布的代码,我看不到 mmInstream 的初始化位置。这将导致您报告的空指针异常,但它也会在调试器中发生(除非该线程从未运行)。

于 2012-04-17T14:56:46.910 回答