0

我有一个我想通过蓝牙控制的机器人。我在蓝牙插座上写信要求机器人移动,如果机器人成功读取我的消息,它会向我发送一个信号,说“我读到你了!”。问题是机器人需要 3 秒才能做出响应。我的理想情况是这样的

public class Robot {

    private boolean lastMsgWasRead;

    public boolean askMeWalk(){

    lastMsgWasRead=false;
    writeToBluetooth("Walk");

    // somehow wait 3 seconds at least.

    if (lastMsgWasRead){
        return true; // sucessful walk
    }else{
        return false; // the robot didn't hear you 
    }

    }

}

现在这是我的问题:有什么我可以使用的:

  • 以某种方式至少等待 3 秒。

我已经阅读过postDelayed, timer, and ScheduledExecutorService等等...

但它们都没有真正帮助我找到对我来说非常重要的返回值。如果我想使用 postDelayed 左右,我无法设置返回值,因为它们在独立线程上运行。

我尝试了 Thread.sleep(3000),但我意识到它在停止主线程时确实会产生任何影响 - 因此处理程序在此期间没有更改更新 lastMsgWasRead 值3000ms.

任何想法??

4

2 回答 2

0

所以你可以做一些混合的事情。3秒是很长的时间。所以你永远不会真的希望你的主线程等待那么久。也许是这样的。

public class AwesomeActivity extends Activity implements Handler.Callback {


 private Handler handler;
 private AsyncTask<?,?,?> task;

 public void onCreate(Bundle b) {
    handler = new Handler(this);
    // Send your data to the robot via an async task
    // Have the async task and listen for the data in the background
    task = new TalkAndListen() {
        public void onPostExecute(String response) {
             // The postExecute() method joins back to the main thread
             // and cancels the async callback you fired off earlier on success
             handler.removeMessages(0);
             // Yay success!
        }
    }.execute("Walk");

   handler.sendEmptyMessageDelayed(0, 3000);
 }

 public boolean handleMessage(Message message) {

    if (message.what == 0) {
       // Sad Trombone, kill off the async thread, 3 secs has passed
       task.cancel(true);
    }
 }

 private static class TalkAndListen extends AsyncTask<String, Void, String> {
   // This is done on a background thread  
   public String doInBackground(String... words) {
       for (String word : words) {
          writeToBluetooth(word);
       }
       return readFromBluetooth();
   }
   // This is the string returned from doInBackground() passed to the main thread
   public void onPostExecute(String responseSignal) {

   }
  }
 }
于 2014-02-01T07:10:02.607 回答
0

我前段时间创建了 I 类来帮助解决这种情况,你可以在这里看到。它允许您发送数据并异步等待它。例如,您将以这种方式使用它:

BluetoothHelper mBluetoothHelper = new BluetoothHelper(this, "bluetoothDeviceName", false, null);
mBluetoothHelper.setConnectionDialog(true);   // Shows a dialog while connecting
mBluetoothHelper.connect(true);               // Connect to Bluetooth device

因此,以这种方式连接到蓝牙设备,现在要接收您需要实现的数据OnNewBluetoothDataReceivedListener

mBluetoothHelper.setOnNewBluetoothDataReceived(this);

// Called when you receive data from Bluetooth
@Override
public boolean onNewBluetoothDataReceivedListener(InputStream mBTIn, OutputStream mBTOut) {

}

所以你不需要等待任何东西,当你接收到数据时它会被异步调用。发送数据:

mBluetoothHelper.write(data);

您将必须实现String使用此方法编写的方法。所以你需要

  • OnNewBluetoothDataReceivedListener.java
  • 蓝牙助手.java
  • 您还需要在布局中DeviceList.java使用device_list.xml和在strings.xml
<string name="scanning">                  Scanning…&lt;/string>
<string name="select_device">             Select device</string>
<string name="none_paired">                   No paired devices</string>
<string name="none_found">                    No devices were found</string>
<string name="title_paired_devices">      Paired devices</string>
<string name="title_other_devices">           Other available devices</string>
<string name="button_scan">                   Scan</string>

并在AndroidManifest.xml

      <activity android:name=".DeviceListActivity"
              android:label="@string/select_device"
              android:theme="@android:style/Theme.Holo.Dialog"
              android:configChanges="orientation|keyboardHidden" >
      </activity>

您需要这个,因为当您扫描以连接到蓝牙设备时,它会向您显示可用设备的列表,BluetoothHelper.java如果您不想要它,您可以对其进行修改。

于 2014-02-01T07:11:37.743 回答