How to add Snackbars in a BroadcastReceiver?
W

4

5

Snackbars provide lightweight feedback about an operation by showing a brief message at the bottom of the screen. Snackbars can contain an action.

Android also provides a toast, primarily used for system messaging. Toasts are similar to snackbars but do not contain actions and cannot be swiped off screen.

My question

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class TestReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(final Context context, final Intent intent) {
        Toast.makeText(context, "status", Toast.LENGTH_LONG).show();
    }
}

Is it posible to show a Snackbar in a BroadcastReceiver like Toast?

Wedged answered 15/7, 2015 at 10:54 Comment(2)
BroadcastReceiver with feedback makes no sens at all ... reciver should ends its miserable life right after onRecive end ... onRecive is called on main thread ... it means that if you do not finish it it would not refresh the UI ... do it in normal way ... in onRecive show notification(which would act as your feedback)Dexamethasone
is it posible to place snakbar instead of toast in my code..Wedged
W
5

my working code....

public abstract  class TestReceiver  extends BroadcastReceiver {
    @Override   
    public void onReceive(final Context context, final Intent intent) {
        onNetworkChange();
    } 

    protected abstract void onNetworkChange();
}

in mainactivity

public class MainActivity extends Activity  {

    public void onCreate() {
        ...  mReceiver = new TestReceiver () {
            @Override
            protected void onNetworkChange() {
            snackbar = Snackbar.make(Clayout, "Please check your internet connection and try again", Snackbar.LENGTH_SHORT);
            snackbar.setAction("X", snackbarClickListener);snackbar.setActionTextColor(Color.GREEN);
            ColoredSnackbar coloredsnakbar=new ColoredSnackbar();
            coloredsnakbar.confirm(snackbar).show();
            }
        };      
    }
}
Wedged answered 21/7, 2015 at 6:28 Comment(0)
S
7

is it posible to show snakbars in BroadcastReceiver like Toast?

A BroadcastReceiver registered by an activity or fragment, via registerReceiver(), could ask the activity or fragment to show a snackbar.

A manifest-registered BroadcastReceiver has no UI, and hence it has no place to show a snackbar. What it could do is post an event on an in-process event bus (e.g., LocalBroadcastManager, greenrobot's EventBus, Square's Otto), to let whatever UI of yours that is in the foreground know that a broadcast was received. If the UI layer receives the message, that activity or fragment can show a snackbar. If the event bus event was not picked up, you can perhaps show a Notification as a fallback, if appropriate.

Scribner answered 15/7, 2015 at 11:16 Comment(0)
W
5

my working code....

public abstract  class TestReceiver  extends BroadcastReceiver {
    @Override   
    public void onReceive(final Context context, final Intent intent) {
        onNetworkChange();
    } 

    protected abstract void onNetworkChange();
}

in mainactivity

public class MainActivity extends Activity  {

    public void onCreate() {
        ...  mReceiver = new TestReceiver () {
            @Override
            protected void onNetworkChange() {
            snackbar = Snackbar.make(Clayout, "Please check your internet connection and try again", Snackbar.LENGTH_SHORT);
            snackbar.setAction("X", snackbarClickListener);snackbar.setActionTextColor(Color.GREEN);
            ColoredSnackbar coloredsnakbar=new ColoredSnackbar();
            coloredsnakbar.confirm(snackbar).show();
            }
        };      
    }
}
Wedged answered 21/7, 2015 at 6:28 Comment(0)
S
3

As @CommonsWare sir told, there has to be some passing mechanism between BroadcastReceiver and Activity/Fragment where UI is attached.

I have tried to add interface for example here :

public class TestReceiver extends BroadcastReceiver {

    private DoSomethingInterface callback1;

    public TestReceiver() {
    }

    @Override
    public void onReceive(final Context context, final Intent intent) {
        // pass content text to show in SnackBar
        if(callback1 != null) {
            callback1.passText("status");
        } else {
            Log.e("log","callback from UI is not registered yet..");
        }
    }

    public void registerReceiver(DoSomethingInterface receiver) {
         this.callback1 = receiver;
    }

    public interface DoSomethingInterface {
        public void passText(String text);
    }
}

Implement the DoSomethingInterface in your Activity or Fragment where you are showing SnackBar. Make sure that you need to add CoordinatorLayout for displaying SnakeBar :

public class MainActivity extends Activity implements DoSomethingInterface {

public void onCreate() {
    ...
    // pass reference to interface from onCreate()
    BroadcastReceiver mReceiver = new TestReceiver();
    mReceiver.registerReceiver(this);
    ...
}

    @Override
    public void passText(String text) {
        Snackbar.make(<reference to your coordinator layout>, "text", Snackbar.LENGTH_LONG)
                    .setAction("Ok", <listener>)
                    .setActionTextColor(Color.GREEN)
                    .show();
Stpierre answered 15/7, 2015 at 11:51 Comment(0)
C
1

I have a work around, without coding the snackbar in all the activities onCreate() method.

We can use the application class to call the BroadcastReciever. As below code.

public class MyApplication extends Application implements Application.ActivityLifecycleCallbacks {
    public static Activity appactivity;
@Override
    public void onCreate() {
        super.onCreate();
        registerActivityLifecycleCallbacks(this);
}
@Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
    }

    @Override
    public void onActivityStarted(Activity activity) {

    }

    @Override
    public void onActivityResumed(Activity activity) {
        appactivity = activity;//here we get the activity
        Intent i = new Intent(this, InternetConnectionInformation.class);
        sendBroadcast(i);//here we are calling the broadcastreceiver to check connection state.
    }
}

Now we can use our BroadcastReceiver class to show snackbar as well

public class InternetConnectionInformation extends BroadcastReceiver{
    static Snackbar snackbar; //make it as global
    @Override
    public void onReceive(Context context, Intent intent) {
        ConnectivityManager connectivityManager
                = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();

        if (activeNetworkInfo == null || !activeNetworkInfo.isConnected()) {
                InternetConnectionInformation.snack(null, 0, "Network Connection failed.",context.getApplicationContext());
        }else{
            InternetConnectionInformation.hideSnackbar();
        }
    }




    public static void snack (HashMap<String,View.OnClickListener> actions,int priority,String message,Context context) {
     if(MyApplication.appactivity != null){
            snackbar = Snackbar.make(MyApplication.appactivity.findViewById(android.R.id.content), message, Snackbar.LENGTH_INDEFINITE);//MyApplication.appactivity from Application class.
            if (actions != null) {
                Iterator iterator = actions.entrySet().iterator();
                snackbar.setDuration(Snackbar.LENGTH_INDEFINITE);
                while (iterator.hasNext()) {
                    Map.Entry pair = (Map.Entry) iterator.next();
                    snackbar.setAction((String) pair.getKey(), (View.OnClickListener) pair.getValue());
                    iterator.remove(); // avoids a ConcurrentModificationException
                }
            }
            switch (priority) {
                case 0:
                    snackbar.getView().setBackgroundColor(context.getResources().getColor(R.color.accentPink));
                    break;
                case 1:
                    snackbar.getView().setBackgroundColor(Color.parseColor("#66ccff"));
                    break;
                case 2:
                    snackbar.getView().setBackgroundColor(Color.parseColor("#66ff33"));
                    break;
            }
            snackbar.show();
           }
        }
        private static void hideSnackbar(){
            if(snackbar !=null && snackbar.isShown()){
                snackbar.dismiss();
            }
        }
    }

To hide the snackbar we need to check the connectivity state. So the BroadcastReceiver is registered in the Manifest

<receiver android:name="your.package.name.InternetConnectionInformation">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
        </receiver>

This works fine and is tested. Hope it will help some.

Cant answered 26/4, 2016 at 6:59 Comment(1)
elegant solution, it's missing registerActivityLifecycleCallbacks(this); in the onCreateKoons

© 2022 - 2024 — McMap. All rights reserved.