1

I am writing an Android App that it will send a message through BLE (Bluetooth Low Energy) to another device, and the device will response a ACK/NACK message. The BLE service that I use will make the communication act like a normal UART communication.

I implemented the communication between the two devices in a AsyncTask, because the communication involve many send/receive loops. I can send the message and receive the message, the problem is that after I sent the message, I need to wait at least a period of time (a timeout) to receive the response. During this waiting time, I need to check if I received the valid response repeatedly, and after the timeout, I need to stop the waiting. I know we can make the AsyncTask sleep, so the sleep time is the timeout. However it would be not efficient that I can only check the message after a full sleep time, such as 3s.

How to do that?

Below is my AsyncTask:

public class configTask extends AsyncTask<String, Integer, Integer> {
    @Override
    protected Integer doInBackground(String... message) {

        // Using StringBuilder here just to show the example, 
        // I will add more string here in real situation
        final StringBuilder sb = new StringBuilder(20);
        sb.append("A test message\r");
        sb.trimToSize();
        try {
            byte[] tx_data = String.valueOf(sb).getBytes("UTF-8");

            // This line will send out the packet through a BLE serivce,
            // "mService" is the BLE service that I have initialize in the
            // MainActivity.
            mService.writeRXCharacteristic(tx_data);
        }
        catch (UnsupportedEncodingException e){
            Log.d(TAG, "Encode StringBuilder to byte[] get UnsupportedEncodingException");
        }

        // After sent out the packet, I need to check whether received
        // a valid response here. The receive and parse routine is 
        // implemented in the MainActivity, once the BLE service received a 
        // packet, it will parse it and set a flag to indicate a packet
        // is received.

        // And then other send/receive routines...

        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
    }

    @Override
    protected void onPostExecute(Integer result) {
        super.onPostExecute(result);
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }
}
eepty
  • 716
  • 3
  • 10
  • 28
  • For me it doesn't look like a good usage for `AsyncTask`. More like for a bound service running on it's own thread. – tynn Jun 29 '16 at 08:38
  • I am new to Android. The BLE communication is implemented as a service. In my MainActivity, I implemented a BroadcastReceiver which can get the message received from the BLE service, and it parse the message once it is received. In such case, is that starting another service would be better? – eepty Jun 29 '16 at 10:36

2 Answers2

0

Questions in some way the same Set timeout function with AsyncTask [Android].

You should implement cancel mechanics in doInBackground and call AsyncTask.cancel() by timeout [like that](https://developer.android.com/reference/android/os/Handler.html#postDelayed(java.lang.Runnable, long))

final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
      @Override
      public void run() {
        AsyncTask.cancel();
      }
    }, 1);

In your case did you consider a service?

Community
  • 1
  • 1
Maxim G
  • 1,479
  • 1
  • 15
  • 23
  • But I do not want to just implement a timeout, I need to check whether a BLE message is received during the waiting time. Your code seems just to cancel the AsyncTask after 1ms. – eepty Jun 29 '16 at 10:38
  • I showed how you can implement timeout (watchdog), result should be checked in `doInBackground()` and when you receive do smth in `onPostExecute()`. Still consider to use service. – Maxim G Jun 29 '16 at 11:09
0

You may do something like following

numBytes = 0;
for(int i=0; i<300; i++){
    numBytes += mService.read(bytes, .....) //Not sure about signature of your read method so just putting variables generally used.

    //TODO - copy your bytes to main buffer here

    if(numBytes == requiredBytes)
        break
    else
        Thread.Sleep(10);
}
chejaras
  • 862
  • 5
  • 10