2

I am working on an Android Application which have an one activity class and service class. In service, Continuous bulk data (1090 bytes) will be received every 10 milliseconds. I need to update the text view continuously with these bulk data. What is recommended way to update Text view from a continuous background service?

Service Class

public class RecepService extends Service {

public static Handler mHandler;
StringBuilder hexstring;

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onCreate() {
    super.onCreate();

    init();
}

private void init() {

    mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 0x123) {

                byte[] readBuf = (byte[]) msg.obj;
                int readBuflen = msg.arg1;

                // here will receive 1090 bytes of data 
                // every 10 milliseconds
                Receivepatientattributes(readBuf,readBuflen);
            }
        }
    };
}

public void Receivepatientattributes(byte[] readBuf, int len) {

    String total_data = "";
    total_data = bytetohex(readBuf, len);
    MainActivity.recep.setText(MainActivity.recep.getText().toString() + "\t" +
            "" + total_data );
}

String bytetohex(byte[] txt, int len) {

    String p="";
    byte[] text = new byte[len];
    text = txt;

    hexstring = new StringBuilder();
    for (int j = 0; j < len; j++) {

        String hex= Integer.toHexString(0xFF & txt[j]);

        if (hex.length()==1) {
            hexstring.append("0");
        }

        hexstring.append(hex+" ");

    }

    p=p+hexstring.toString();
    return p;
}

@Override
public void onDestroy() {
    super.onDestroy();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    return START_STICKY;
}
}
Shishram
  • 1,514
  • 11
  • 20
Arya
  • 1,729
  • 3
  • 17
  • 35

4 Answers4

1

User LocalBroadcastManager

public void Receivepatientattributes(byte[] readBuf, int len) {
    String total_data = "";
    total_data = bytetohex(readBuf, len);

    Intent intent = new Intent("update-text");
    // add data
    intent.putExtra("message", total_data);
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}

In MainActivity

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

  // Register mMessageReceiver to receive messages.
  LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
      new IntentFilter("update-text"));
}

private boolean mCanBeUpdated = true;
private static final int ONE_SEC = 1000; //ms
private static final int RECEPTION_SPEED = 10; //ms
private static final int CYCLES = (int) (ONE_SEC / RECEPTION_SPEED);
private int mCurrentCycle = -1;
private String mMsgCache = "";

// handler for received Intents for the "update-text" event 
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        // Extract data included in the Intent
        String message = intent.getStringExtra("message");
        Log.d("receiver", "Got message: " + message);

        mMsgCache = mMsgCache + "\t" + message;

        if (mCanBeUpdated) {
            // No problem updating UI here, refer --> http://stackoverflow.com/a/5676888/1008278
            final Handler handler = new Handler(context.getMainLooper());
            handler.post(new Runnable() {
                @Override
                public void run() {
                    MainActivity.recep.append(mMsgCache);
                    mMsgCache = "";
                }
            });

            mCanBeUpdated = false;
        } else if (mCurrentCycle >= CYCLES) {
            mCurrentCycle = -1;
            mCanBeUpdated = true;
        } else {
            mCurrentCycle++;
        }
    }
};

@Override
protected void onPause() {
  // Unregister since the activity is not visible
  LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
  super.onPause();
} 

Reference

VenomVendor
  • 15,064
  • 13
  • 65
  • 96
  • But my UI gets hung after some time while update value to text view – Arya Oct 31 '15 at 06:45
  • 10 milliseconds is too fast. You should consider updating textview after every 1 second. Or Instead to setting text every time, you can append new text to existing text. Check my EDIT. – VenomVendor Nov 01 '15 at 17:41
  • Actually data reception part is from the ECG WIFI module. so we can't reduce the time. If I reduce the time it will lose data. – Arya Nov 02 '15 at 04:59
  • @Arya You can cache locallly in a variable --> after (1000/10) cycles Update --> Clear cache & redo. – VenomVendor Nov 02 '15 at 07:06
1

If you want to use Schedule and timer task then you can See My Answer

To solve current issue follow this bellow instructions. Suppose your activity has a Broadcast Receiver

private BroadcastReceiver mReceiver;

Then you override methods onResume() where your broadcast receiver will be registered and also onPause() where will your receiver be unregistered:

@Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();

        IntentFilter intentFilter = new IntentFilter(
                "android.intent.action.MAIN");

        mReceiver = new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {
                //extract your message from intent
                String msg_for_me = intent.getStringExtra("YOUR_MESSAGE");
                //log your message value
                Log.i("MyTag", msg_for_me);

            }
        };
        //registering your receiver
        this.registerReceiver(mReceiver, intentFilter);
    }

    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        //unregister your receiver
        this.unregisterReceiver(this.mReceiver);
    }

Here the broadcast receiver is filtered via android.intent.action.MAIN and from Service the message will BroadCast using this filter

Now your Method Receivepatientattributes will like this :

public void Receivepatientattributes(byte[] readBuf, int len) {

    String total_data = "";
    total_data = bytetohex(readBuf, len);

    Intent i = new Intent("android.intent.action.MAIN").putExtra("YOUR_MESSAGE",  total_data);
    this.sendBroadcast(i);

}

Thats it. :)

Community
  • 1
  • 1
Md. Sajedul Karim
  • 6,749
  • 3
  • 61
  • 87
0

You can use Timer for Continously updating your textview.

Set value in preferences every time when your service is running with the latest value.

Now in Timer get that value from preferences and update your TextView with that value.

Here is some code :

class UpdateTimeTask extends TimerTask {
   public void run() {

   textview.setText("updated value");
   }
}

Set in onCreate ();

    Timer timer = new Timer();
    UpdateTimeTask  UpdateTimeTask = new UpdateTimeTask ();
    timer.schedule(UpdateTimeTask, 1000);
Arya
  • 1,729
  • 3
  • 17
  • 35
KishuDroid
  • 5,411
  • 4
  • 30
  • 47
0

Use handler beacuse A Handler allows communicating back with UI thread from other background thread.

boolean handlerStop = false;

    void handleHandler(){
        Handler handler =new Handler();
        final Runnable r = new Runnable() {
            public void run() {
                handler.postDelayed(this, 30000);
                if(!handlerStop) {
                    updateTextView() //update your text with other thread like asyncronous thread
                }
            }
        };
        handler.postDelayed(r, 0000);
    }

    @Override
    public void onResume() {
        super.onResume();
        handlerStop=false;
        handleHandler();
    }

    @Override
    public void onPause() {
        super.onPause();
        handlerStop=true;
        handleHandler();
    }

    @Override
    public void onStop() {
        super.onStop();
        handlerStop=true;
        handleHandler();
    }