如何在 BroadcastReceiver 中添加 Snackbars?
Posted
技术标签:
【中文标题】如何在 BroadcastReceiver 中添加 Snackbars?【英文标题】:How to add Snackbars in a BroadcastReceiver? 【发布时间】:2015-10-04 09:03:57 【问题描述】:Snackbars 通过在屏幕底部显示一条简短消息来提供有关操作的轻量级反馈。 Snackbars 可以包含一个动作。
android 还提供了 toast,主要用于系统消息传递。 Toasts 类似于小吃店,但不包含动作并且不能从屏幕上滑出。
我的问题
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();
是否可以在BroadcastReceiver
中显示Snackbar
,例如Toast
?
【问题讨论】:
带有反馈的BroadcastReceiver根本没有任何意义......接收器应该在onRecive结束后立即结束它的悲惨生活......在主线程上调用onRecive......这意味着如果你没有完成它它不会刷新用户界面...以正常方式执行...在 onRecive 显示通知中(这将作为您的反馈) 是否可以在我的代码中放置 snakbar 而不是 toast.. 【参考方案1】:是否可以像 Toast 一样在 BroadcastReceiver 中显示 snakbar?
由活动或片段注册的BroadcastReceiver
,通过registerReceiver()
,可以要求活动或片段显示一个snackbar。
清单注册的BroadcastReceiver
没有用户界面,因此它没有地方显示快餐栏。它可以做的是在进程内事件总线上发布一个事件(例如,LocalBroadcastManager
、greenrobot 的 EventBus、Square 的 Otto),让您在前台的任何 UI 都知道收到了广播。如果 UI 层收到消息,则该活动或片段可以显示一个快餐栏。如果未获取事件总线事件,您或许可以将Notification
显示为备用,如果合适的话。
【讨论】:
【参考方案2】:正如@CommonsWare 先生所说,BroadcastReceiver
和 Activity/Fragment
之间必须有一些传递机制,其中附加了 UI。
我曾尝试在此处添加interface
:
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);
在显示 SnackBar 的 Activity 或 Fragment 中实现 DoSomethingInterface
。确保您需要添加 CoordinatorLayout
以显示 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();
【讨论】:
public void registerReceiver(DoSomethingReceiver receiver) this.callback1 = receiver; ...是 DoSomethingReceiver 还是 DoSomethingInterface 是DoSomethingInterface
尝试在空对象引用上调用接口方法“void DoSomethingInterface.passText(java.lang.String)”
这意味着回调未从 UI(活动端)注册。请检查并确保您从 UI 代码的起点调用mReceiver.registerReceiver(this);
。我添加了 Null 检查并登录以上代码..请检查..
TestReceiver mReceiver = new TestReceiver (); mReceiver.registerReceiver(this);从 UI 获取回调尚未注册..【参考方案3】:
我的工作代码....
public abstract class TestReceiver extends BroadcastReceiver
@Override
public void onReceive(final Context context, final Intent intent)
onNetworkChange();
protected abstract void onNetworkChange();
在主要活动中
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();
;
【讨论】:
【参考方案4】:我有一个变通方法,没有在所有活动onCreate()
方法中对小吃栏进行编码。
我们可以使用应用程序类来调用BroadcastReciever
。
如下代码。
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.
现在我们也可以使用我们的 BroadcastReceiver 类来显示snackbar了
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();
要隐藏快餐栏,我们需要检查连接状态。所以BroadcastReceiver注册在Manifest
<receiver android:name="your.package.name.InternetConnectionInformation">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
这工作正常并经过测试。希望对大家有所帮助。
【讨论】:
优雅的解决方案,它缺少 registerActivityLifecycleCallbacks(this);在 onCreate以上是关于如何在 BroadcastReceiver 中添加 Snackbars?的主要内容,如果未能解决你的问题,请参考以下文章
UE4中添加Android BroadcastReceiver
如何将BroadcastReceiver中的信息传到Activity中
如何从 BroadcastReceiver 在 Activity 中发送和保存字符串消息
在启动时触发BroadcastReceiver的应用程序崩溃