2013-02-05 69 views
1

我试图改进一个实际的代码,使用Arduino(电子微控制器)与Android手机进行蓝牙连接。我可以接收和发送数据到微控制器,但蓝牙需要在启动应用程序之前打开,否则它将挂起并关闭。我确实检查了一个蓝牙适配器,并要求用户改变蓝牙状态,如果它处于OFF状态,但看起来程序继续并且在获得用户选择结果之前尝试建立连接。我希望有一些帮助可以找到解决方案,以阻止我的程序,直到用户输入他们的选择或甚至获得更好的解决方案。Android和蓝牙挂起(startActivityForResult)

我想说,我还是新来的Android编程,我没看过Android的活动流程图。

我可以提供logcat的,但我检查它,它明确指出,我想使用蓝牙即使尚未启用它...

这里是我的代码:

我想感谢谁这可能会使我指向正确的方向

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.activity_main); 

    btnOn = (Button) findViewById(R.id.btnOn);     // button LED ON 
    btnOff = (Button) findViewById(R.id.btnOff);    // button LED OFF 
    txtArduino = (TextView) findViewById(R.id.txtArduino);  // for display the received data from the Arduino 

    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();  // get Bluetooth adapter 
    checkBTState(); 

    h = new Handler() { 
     public void handleMessage(android.os.Message msg) { 
      switch (msg.what) { 
      case RECIEVE_MESSAGE:             // if receive massage 
       byte[] readBuf = (byte[]) msg.obj; 
       String strIncom = new String(readBuf, 0, msg.arg1);     // create string from bytes array 
       sb.append(strIncom);            // append string 
       int endOfLineIndex = sb.indexOf("\r\n");       // determine the end-of-line 
       if (endOfLineIndex > 0) {           // if end-of-line, 
        sbprint = sb.substring(0, endOfLineIndex);    // extract string 
        sb.delete(0, sb.length());          // and clear 
        txtArduino.setText("Data from Arduino: " + sbprint); 
        Log.e(TAG, "Arduino"+sbprint); 

       //Test string value  
        if(sbprint.matches("-?\\d+(\\.\\d+)?")) { 
         try{ 

         Float sensorReading = Float.parseFloat(sbprint); 
         Log.e(TAG, "Sensor value"+sensorReading); 
         }catch(NumberFormatException e){ 
          Log.e(TAG, "No int format sorry",e); 

         } 
        } 
        if(sbprint.matches("test")){ 

         Log.e(TAG, "garbage"); 
        } 

        /////// 

        btnOff.setEnabled(true); 
        btnOn.setEnabled(true); 
       } 
       //Log.d(TAG, "...String:"+ sb.toString() + "Byte:" + msg.arg1 + "..."); 
       break; 
      } 
     }; 
    }; 





public void onResume() { 
    super.onResume(); 

    Log.d(TAG, "...onResume - try connect..."); 

    // Set up a pointer to the remote node using it's address. 
    BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); 

    // Two things are needed to make a connection: 
    // A MAC address, which we got above. 
    // A Service ID or UUID. In this case we are using the 
    //  UUID for SPP. 

    try { 
     btSocket = createBluetoothSocket(device); 
    } catch (IOException e) { 
     errorExit("Fatal Error", "In onResume() and socket create failed: " + e.getMessage() + "."); 
    } 

    /*try { 
     btSocket = device.createRfcommSocketToServiceRecord(MY_UUID); 
    } catch (IOException e) { 
     errorExit("Fatal Error", "In onResume() and socket create failed: " + e.getMessage() + "."); 
    }*/ 

    // Discovery is resource intensive. Make sure it isn't going on 
    // when you attempt to connect and pass your message. 
    mBluetoothAdapter.cancelDiscovery(); 


    // Establish the connection. This will block until it connects. 
    Log.d(TAG, "...Connecting..."); 
    try { 
     btSocket.connect(); 
     Log.d(TAG, "....Connection ok..."); 
    } catch (IOException e) { 
     try { 
     btSocket.close(); 
     } catch (IOException e2) { 
     errorExit("Fatal Error", "In onResume() and unable to close socket during connection failure" + e2.getMessage() + "."); 
     } 
    } 

    // Create a data stream so we can talk to server. 
    Log.d(TAG, "...Create Socket..."); 

    mConnectedThread = new ConnectedThread(btSocket); 
    mConnectedThread.start(); 
} 

回答

1

您在onResume中拥有所有代码。 onResume将在活动启动时被调用,因此它几乎立即执行。我没有看到任何应该延迟它的代码。如果你不想尝试连接直到用户选择了一些东西,那么所有的连接代码都应该放在按钮的点击处理器或类似的东西中。

+0

也许我的问题是严格的公式,因为我想要退出或连接时,用户选择BluetoothAdapter.ACTION_REQUEST_ENABLE意图的东西。我不想要连接的特定按钮。我试图使用onActivityResult,但我可能没有正确使用它,因为它不工作。 – Mathieu660

0

除了@ GabeSechan的所有代码在onResume()是的评论,你也是其中根据this documentation调用蓝牙connect()在主要活动线程被阻塞的调用和“应始终在单独的线程中执行来自主要活动线程“。

+0

只是一个关于线程的澄清......如果我使用另一个线程,我可以在onResume()中调用它吗? – Mathieu660

+0

我正在学习这一点。我们需要阅读http://developer.android.com/guide/components/processes-and-threads.html,以了解在后台线程中处理长时间运行和阻塞任务的最佳方式。 – HeatfanJohn