Displaying a Delayed Toast from a BroadcastReceiver
I'm trying to display a message to the user some time after an event is received by a BroadcastReceiver.
public class MyReceiver extends BroadcastReceiver {
private Timer timer = new Timer();
@Override
public void onReceive(Context context, Intent intent) {
// Display message in 10 sec.
timer.schedule(new MessageTask(context, "Test Message"), 10 * 1000);
}
private static class MessageTask extends TimerTask {
public MessageTask(Context context, String message) {
this.context = context;
this.message = message;
}
public void run() {
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
}
}
When 开发者_运维技巧I run this I get the following exception:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Is this the right way to do something like this? Should I be using something other then a Timer? And what is the right way to get a Context object in this situation?
Thank you
You might try using my Toaster class. Use it like a Thread:
new Toaster(yourContext, yourMessageResId, Toast.LENGTH_LONG).start();
Guided by the example posted by Kevin Gaudin bellow, I realize that in order to interact with the UI from a different thread, one needs to manage the Android message loop manually.
In pseudo this looks something like this:
import android.content.Context;
import android.os.Looper;
public class MyUIThread extends Thread {
public MyUIThread(Context context) {
// Probably going to need a context to do anything useful. So
// pass it in.
this.context = context;
}
public void run() {
Looper.prepare();
// Do some UI stuff, e.g. Toast.makeText
Looper.loop();
}
}
This won't work. Once your onReceive() method is complete, the phone is free to go back to sleep or do whatever it wants. You have to implement a wakelock.
精彩评论