Damen Tomassi Damen Tomassi - 5 months ago 13
Android Question

How to display a toast message in only one activity?

In an application I am developing I have some code that attempts to submit information to the internet. If the connection can not be made, I pop up a toast message instructing the user to check the network connection.

Toast.makeText(getApplicationContext(), "Check network connection.", Toast.LENGTH_SHORT).show();


The problem I have is the toast message comes up no matter what the user is looking at! Even if the user is in a different app and my app is running in the background! This is not the desired behavior as I send a notification to the user if network activity fails. I only want the toast message to appear if the user is in the activity that is generating the network activity. Is there a way to do this?

If this is not possible my idea was to just put some kind of visual element in my activity - rather than display a toast message.

Thank You!

Answer

Use a dynamic BroadcastReceiver. Your background service will broadcast an Intent when something happens. All of your app's activities will register a dynamic BroadcastReceiver which will listen for these events. When such event occurs it will show a toast. When none of your activities are running nothing will happen.

Inside your service

public static final ACTION_SOMETHING = BuildConfig.APPLICATION_ID + ".ACTION_SOMETHING";

public void doSomething() {
    // ...

    // Show toast if app is running. Or let the app react however you please.
    LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(ACTION_SOMETHING));

    // ...
}

Of course you can put additional information in the Intent as extras and access them in the BroadcastReceiver.

Inside your activities

private final IntentFilter onSomethingIntentFilter = new IntentFilter(MyService.ACTION_SOMETHING);
private final BroadcastReceiver onSomething = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        // This check seems redundant but it's not. Google it.
        if (MyService.ACTION_SOMETHING.equals(intent.getAction()) {
            // Show toast here.
        }
    }
};

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

    // Start listening for events when activity is in foreground.
    LocalBroadcastManager.getInstance(this).registerReceiver(onSomething, onSomethingIntentFilter);
}

public void onPause() {
    super.onPause();

    // Stop listening as soon as activity leaves foreground.
    try {
        LocalBroadcastManager.getInstance(this).unregisterReceiver(onSomething);
    } catch (IllegalArgumentException ex) {}
}

You may want to pull this code to a common activity parent, a BaseActivity, so you don't repeat yourself.

This is a common case of Provider-Subscriber pattern. Another implementation would be an EventBus.

Comments