2012-04-17 57 views
0

对于我今年夏天的机器人考试,我正在构建一个机器人,我想通过蓝牙与Android设备进行通信。为此,我正在编写自己的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),并试图像一样和他们一样,但是仍然崩溃,这就是为什么我现在尝试了我上面粘贴的代码。 另外,即使应用程序在正常运行时崩溃,当我选择在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); 
    } 
} 

}

+0

发布例外 – Ran 2012-04-17 13:42:37

+0

嗨@Ran感谢您的回复!Eclipse中LogCat窗口的输出如下,在崩溃后: 04-17 16:29:20.559:W/dalvikvm(13854):threadid = 11:线程退出与未捕获的异常(组= 0x40a341f8) 04 - 17 16:29:20.559:E/AndroidRuntime(13854):致命例外:线程 - 1635年 04 - 17日16:29:20。559:E/AndroidRuntime(13854):java.lang.NullPointerException 04-17 16:29:20.559:E/AndroidRuntime(13854):\t at skole.migogjesper.hospitalsseng.HospitalssengActivity $ 1.run(HospitalssengActivity.java:71) 04-17 16:29:20.559:E/AndroidRuntime(13854):\t at java.lang.Thread.run(Thread.java:856) – WuPtI 2012-04-17 14:32:04

回答

0

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

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

你可以在你创建线程的地方发布代码吗?

看着你发布的代码,我看不到mmInstream在哪里初始化。这会导致一个空指针异常像你报告的,但它也会发生在调试器(除非该线程从未运行)。

+0

究竟是一种竞争条件@JonStrayer?我对编程相当陌生,并且希望学习:-)实际上,除了创建它之外,我没有在这个线程之外对mmInStream做任何事情:private InputStream mmInStream; – WuPtI 2012-04-17 15:02:45

+0

好的,我会尝试发布整个代码@JonStrayer。 – WuPtI 2012-04-19 07:00:28

0

你不应该使用线程。

使用服务的背景东西,和线程使用ASyncTask而不是线程!

作为提示:您可以在本地服务和活动之间在本地广播! (你要导入Android的支持库为(见LocalBroadcast)。

的Android已经意味着OS上的另一个OS(Linux)的顶部。你并不需要处理线程通信自己,让Android为采取照顾!

+0

正如我在之前的一个评论中所说的,我不是一个非常有经验的程序员,也不是一个Android(这是我的第一个“真正的”Android应用程序),所以我基本上只是配合Google的文档和一些我以前的经历。我会如何创建一些能够不断用您建议的@Radu方法监听传入的蓝牙通信? – WuPtI 2012-04-19 15:55:54

+0

很难解释所有这些,但你需要有一个服务(它始终在后台运行 - 你可以开始阅读)。然后,在该服务中,监视蓝牙连接的状态。如果断开连接,请启动侦听连接的ASyncTask以及尝试建立新连接的A​​SyncTask。如果连接,启动ASyncTask读取传入数据并写入传出数据。所有这些之间的沟通可以通过很多方式完成。我用LocalBroadcast来做。再次,阅读所有这些类的Android文档。 – Radu 2012-04-20 13:24:59

+0

嗯好吧,我可能会试着去研究它,但它听起来像是需要对应用程序进行几乎完全的重写,而我很遗憾没有时间。不过,谢谢你的回答@Radu! – WuPtI 2012-04-20 16:05:41

相关问题