0

I am trying to create one application which checks battery status every one minute and update the UI with the battery Level.

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_my);
    batteryPercent = (TextView) this.findViewById(R.id.battery);
    while (true) {
        runOnUiThread(mRunnable);
    }
}

private Runnable mRunnable = new Runnable() {
    @Override
    public void run() {
        getBatteryPercentage();

        try {
            Thread.sleep(60000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
};

`getBatteryPercentage()1 update a text view on UI.

When I call getBatteryPercentage() only once the code works fine, but when I try to run it in a loop like above, after few seconds I get Application Not Responding(ANR).

Is there any way to make the app wait for 60 seconds without getting ANR?

admdrew
  • 3,790
  • 4
  • 27
  • 39
Karthik
  • 4,950
  • 6
  • 35
  • 65
  • use a timer or an alarmmanager – tyczj Sep 02 '14 at 15:28
  • The problem is that you have `while(true)` in your `onCreate` method that block the ui – sergiomse Sep 02 '14 at 15:30
  • 1
    the problem is that you are doing it wrong ... why? because you even did not try to do some research http://developer.android.com/training/monitoring-device-state/battery-monitoring.html – Selvin Sep 02 '14 at 15:31

3 Answers3

1

You can use Handler.postDelayed for this.

Handler handler =  new Handler();

private Runnable mRunnable = new Runnable() {
@Override
    public void run() {
        getBatteryPercentage();
        handler.postDelayed(mRunnable, 60000);
    }
}

And then:

handler.postDelayed(mRunnable, 60000);
cliffroot
  • 1,839
  • 17
  • 27
1

Don't do it with Sleep. Use a CountDownTimer instead.

CountDownTimer _timer;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_my);
    batteryPercent = (TextView) this.findViewById(R.id.battery);

    _timer = new CountDownTimer(Long.MAX_VALUE, 60000) { 

         @Override 
         public void onTick(long millisUntilFinished) 
         { 
              getBatteryPercentage();
         } 


         @Override public void onFinish() {} 
    }; 
    _timer.start();

Don't forget to call _timer.cancel() before the Activity exits.

selbie
  • 100,020
  • 15
  • 103
  • 173
  • Thank you, it worked like a charm!! Before asking here, I have tried it with CountDownLatch and it did not work(may be i have done some mistake). – Karthik Sep 02 '14 at 15:44
0

if you do something in android uithread more than 5 seconds,the application will show ANR toast. you should do while loop in another thread,and use callback to refresh ui.you can do it like this:

new Thread(new Runnable(){
public void run(){
  try{
     Thread().sleep(6*1000);
     updateUI();
 }catch( Exception e){
   e.print***();
 }}}).start();

private void updateUI(){
   runOnUiThread(new Runnable(){
     getBatteryPercentage();
   });
}
UperOne
  • 195
  • 10
  • It's probably not a good idea to do the UI work on another thread. Most UI controls and Activity objects aren't thread safe. Keep the thread but use the Handler mechanism to notify the UI to invoke new code. – selbie Sep 02 '14 at 15:38