【问题标题】:BroadcastReceiver not trigger from ActionBarDrawerToggleBroadcastReceiver 不会从 ActionBarDrawerToggle 触发
【发布时间】:2017-10-31 14:50:22
【问题描述】:

我尝试通知我的 Fragment 抽屉已打开或关闭,以停止更新 UI。我决定发送一个广播,抽屉开始打开和关闭。

但是,片段中的接收器永远不会被触发。我不明白为什么,因为我使用了很多次广播。

主要活动:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) {
            @Override
            public void onDrawerStateChanged(int newState) {
                super.onDrawerStateChanged(newState);
                if (newState == DrawerLayout.STATE_SETTLING) {

                    if (!drawer.isDrawerOpen(GravityCompat.START)) {
                        // Start opening
                        Log.d(TAG, "start opening");
                        Intent i = new Intent();
                        i.setAction(getResources().getString(R.string.DrawerAction));
                        i.putExtra(getResources().getString(R.string.drawer_extra), true);
                        getApplicationContext().sendBroadcast(i);
                    }
                    else {
                        // start closing
                        Log.d(TAG, "start closing");
                        Intent i = new Intent();
                        i.setAction(getResources().getString(R.string.DrawerAction));
                        i.putExtra(getResources().getString(R.string.drawer_extra), false);
                        getApplicationContext().sendBroadcast(i);
                    }
                }
            }
        };
        drawer.setDrawerListener(toggle);
        toggle.syncState(); 

片段:

private class DrawerReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d(TAG, "onreceiver drawer");
            if (intent != null) {
                Log.d(TAG, "intetn not null");
                if (intent.getAction().equals(context.getResources().getString(R.string.DrawerAction))) {
                    Log.d(TAG, "drawer action ok");
                    boolean isOpen = intent.getBooleanExtra(context.getResources().getString(R.string.drawer_extra), false);
                    Log.d(TAG, "isdraweropen in watchfrag : "+isOpen);
                    // If drawer open, stop update UI, stop recording
                    if (isOpen) {
                        updateUI = false;
                    } else {
                        updateUI = true;
                    }
                }
            }
        }
    }

@Override
    public void onStart() {
        super.onStart();
        getActivity().registerReceiver(drawerReceiver, new IntentFilter(getResources().getString(R.string.drawer_filter)));

    }

    @Override
    public void onStop() {
        super.onStop();

        getActivity().unregisterReceiver(drawerReceiver);
    }


 @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        drawerReceiver = new DrawerReceiver();
    }

谢谢大家。

【问题讨论】:

  • IntentFilter 的操作 - getResources().getString(R.string.drawer_filter) -(很可能)与您在 Intents - getResources().getString(R.string.DrawerAction) 上设置的操作不匹配。此外,您可以考虑改用LocalBroadcastManager,或其他一些本地事件总线实现。
  • @MikeM。 Okayyyyyy 我真的很蠢啊啊啊!谢谢你。您可以将此作为答案发布,以便我为您的帖子投票 :) 但是,我不明白为什么不显示 Log.d(TAG, "onreceiver drawer");... 广播可以被所有 android 系统检索,仅支持 if (intent.getAction().equals(context.getResources().getString(R.string.DrawerAction)))检测的意图是我正在寻找的那个。我对吗 ?如果你能解释为什么日志没有被触发,那就太棒了!
  • 我认为这就是它的工作方式。所以(intent.getAction().equals(context.getResources().getString(‌​R.string.DrawerActio‌​n))) 有点多余不是吗?
  • 对于动态注册接收器,是的,检查动作有点多余,因为这是接收器可以被定位的唯一方法。不过,我不确定您为什么没有看到该日志。其他一切都按预期工作吗?您的 logcat 上是否有某种过滤器可以将其过滤掉?
  • 感谢您的帮助,愚蠢的错误,但很高兴您在这里 :)

标签: android android-fragments broadcastreceiver navigation-drawer


【解决方案1】:

您在IntentFilter 上使用的操作似乎是为了注册接收方:

new IntentFilter(getResources().getString(R.string.drawer_filter))

与您正在广播的Intents 上的操作不匹配:

i.setAction(getResources().getString(R.string.DrawerAction))

Strings 的这些操作必须相等,您的接收器才能获得这些广播。


此外,您可以考虑使用 LocalBroadcastManager(在 v4 支持库中提供)在您的应用本地广播。它使用相同的IntentBroadcastReceiver 设置,但它比在Context 上发送广播要快得多。如果您决定走这条路,请务必注册接收器并在LocalBroadcastManager 上发送广播。

当然,任何其他事件总线实现也可以在这里工作,但是如果您没有在应用程序中的其他任何事情上使用这种模式,这可能会有点过头了。 LocalBroadcastManager 非常轻量级,因为它使用了框架中已有的组件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-06
    • 1970-01-01
    • 2015-10-11
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多