1

Am trying yo use a TimerTask() with a Handler() associated with a postDelayed to update my notification running the method task every 1sec but I seem to be hitting a wall implementing it properly from the looks of things. Here is a sample from my code:

 Timer timer = new Timer();
    TimerTask task = new TimerTask(){

            @Override
            public void run() {
                updateNotificationUi();
            }
        };

        timer.scheduleAtFixedRate(task, 0, 1000);
}

Then updateNotificationUi() method code:

private void updateNotificationUi() {

    new Handler().postDelayed(new Runnable(){

        @Override
        public void run() {

            if(isRunning) {

  mNotificationBuilder.setContentTitle("Text").setContentText("This value here updates every 1 sec").setSmallIcon(R.drawable.ic_launcher);

 mNotifyManager.notify(notificationID, mNotificationBuilder.build());


            }
        }

    }, 1000);
}

The error I get when running my app is 12-22 07:37:20.556: E/AndroidRuntime(6555): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() Any suggestions on how to fix this issue?

CodeZero
  • 179
  • 2
  • 15

3 Answers3

1

try calling your handler like this: (googling a little bit more could have helped)

    new Handler(Looper.getMainLooper()).postDelayed(new Runnable(){

        @Override
        public void run() {

            if(isRunning) {

  mNotificationBuilder.setContentTitle("Text").setContentText("This value here updates every 1 sec").setSmallIcon(R.drawable.ic_launcher);

 mNotifyManager.notify(notificationID, mNotificationBuilder.build());


            }
        }

    }, 1000);
1

You can't build mNotificationBuilder inside a thread without using the UI thread. same goes for AlertDialogs.

Refer to this post.

Community
  • 1
  • 1
Kyle Emmanuel
  • 2,193
  • 1
  • 15
  • 22
1

Yep, there is a more elegant solution

You could define a Handler and a Runnable as global variables like this (notice the "postDelayed" inside the runnable):

Handler myHandler;

Runnable runnable = new Runnable(){

    @Override
    public void run() {

        if(isRunning) {

           mNotificationBuilder.setContentTitle("Text").setContentText("This value here updates every 1 sec").setSmallIcon(R.drawable.ic_launcher);

           mNotifyManager.notify(notificationID, mNotificationBuilder.build());

           myHandler.postDelayed(runnable, 1000);
        }
    }

};

...

And then in your method start the loop:

private void updateNotificationUi() {

    myHandler = new Handler();

    myHandler.postDelayed(runnable, 1000);
}

Probably you will need a stop condition too, maybe a boolean flag arroung "postDelayed" inside runnable. Something like this:

if(shouldContinueLooping){
    myHandler.postDelayed(runnable, 1000);
}
jDur
  • 1,481
  • 9
  • 10