【问题标题】:Unable to receive broadcast from Service无法接收来自服务的广播
【发布时间】:2015-02-26 14:37:45
【问题描述】:

我遇到的问题是关于从 android 库项目中的服务接收广播。

为什么我无法接收广播?是否与单独的 android 库项目中的所有服务/接口逻辑有关?

这是来自服务的广播

    broadcastReceivedMessage("THE TOPIC", "THE MESSAGE");

这是服务中的方法

    private void broadcastReceivedMessage(final String topic, final String message) {
/*      handler.post(new Runnable() {
            @Override
            public void run() {*/
                Intent broadcastIntent = new Intent(CALLBACK_ACTION);
                broadcastIntent.setAction(ON_MESSAGE_RECEIVED);
                broadcastIntent.putExtra(TOPIC_STR, topic);
                broadcastIntent.putExtra(MESSAGE_STR, message);
                sendBroadcast(broadcastIntent);
/*          }
        });*/

    }

在一个实现许多接口的类中,这是我注册监听特定意图过滤器的地方。

  @Override
  public void connect(String address, int port) {
    IntentFilter filter = new IntentFilter(MQTTService2.CALLBACK_ACTION);
    LocalBroadcastManager.getInstance(getContext()).registerReceiver(serviceActionReceiver, filter);
    Bundle args = new Bundle();
    args.putString(MQTTService2.BROKER_ADDR_STR, address);
    args.putInt(MQTTService2.BROKER_PORT_INT, port);
    startService(MQTTService2.ACTION_CONNECT, args);
  }

在我希望从接口接收回调并获取我的广播的 Activity 中

  MQTTEventHandler mHandler = new MQTTEventHandler() {

  @Override
  public void onStatusChanged(CommunicatorStatus status, String message) {
    // TODO Auto-generated method stub
    Log.e("onStatusChanged", "----------------Status Changed------------");
    Log.e("STATUS: ", status.toString());
    Log.e("MESSAGE: ", message);
    Log.e("onStatusChanged", "--------------------------------------------");

  }

  @Override
  public void onMessageReceived(String topic, String message) {
    // TODO Auto-generated method stub
    Log.e("onMessageReceived", "----------------Message Received------------");
    Log.e("TOPIC: ", topic);
    Log.e("MESSAGE: ", message);
    Log.e("onMessageReceived", "--------------------------------------------");

  }

  @Override
  public void onException(String message) {
    // TODO Auto-generated method stub

  }
};

mComm.addEventHandler(mHandler);

广播接收器

class ServiceActionReceiver extends BroadcastReceiver {



    @Override
    public void onReceive(Context context, Intent intent) {

      String action = intent.getAction();
      if (action.equals(MQTTService2.ON_EXCEPTION)) {
        Bundle extras = intent.getExtras();
        if (extras != null && extras.containsKey(MQTTService2.MESSAGE_STR))
          fireOnException(extras.getString(MQTTService2.MESSAGE_STR));
      } else if (action.equals(MQTTService2.ON_MESSAGE_RECEIVED)) {
        Bundle extras = intent.getExtras();
        if (extras != null && extras.containsKey(MQTTService2.MESSAGE_STR)
            && extras.containsKey(MQTTService2.TOPIC_STR))
          fireOnMessageReceived(extras.getString(MQTTService2.TOPIC_STR),
              extras.getString(MQTTService2.MESSAGE_STR));

      } else if (action.equals(MQTTService2.ON_STATUS_CHANGED)) {
        Bundle extras = intent.getExtras();
        if (extras.containsKey(MQTTService2.STATUS_CODE)) {
          MQTTService2.MQTTConnectionStatus status =
              MQTTConnectionStatus.parseCode(extras.getString(MQTTService2.STATUS_CODE));
          switch (status) {
            case CONNECTED:
              fireOnStatusChanged(CommunicatorStatus.DISCONNECTED,
                  extras.getString(MQTTService2.MESSAGE_STR, ""));
              break;
            case CONNECTING:
              break;
            case INITIAL:
              break;
            case NOTCONNECTED_DATADISABLED:
            case NOTCONNECTED_UNKNOWNREASON:
            case NOTCONNECTED_USERDISCONNECT:
            case NOTCONNECTED_WAITINGFORINTERNET:
              fireOnStatusChanged(CommunicatorStatus.DISCONNECTED,
                  extras.getString(MQTTService2.MESSAGE_STR, ""));
              break;
            default:
              break;

          }
        }

      }
    }
  }

根据特定意图过滤器调用的方法(onMessageReceived)

      private void fireOnMessageReceived(String topic, String message) {
    for (MQTTEventHandler eventHandler : handlers) {
      eventHandler.onMessageReceived(topic, message);
    }
/*    for (Iterator<MQTTEventHandler> it = handlers.iterator(); it.hasNext();) {
      it.next().onMessageReceived(topic, message);
    }*/
  }

【问题讨论】:

  • 您的服务是否在单独的进程中运行?
  • 我不是 100% 确定,我通过调用 startService 来启动服务,最终它是用 START_STICKY 启动的,但我从来没有把它放在单独的线程或任何东西中。
  • 您是否在清单的&lt;service&gt; 条目中指定了process 属性?
  • 我在 Manifest 中声明了服务。它只在应用程序项目中声明,而不是库项目。调用 connect() 时我能够成功访问服务
  • 完美。你帮了大忙。如果您想发布答案,我会接受,否则我将发布已实施的解决方案。

标签: java android android-intent service broadcastreceiver


【解决方案1】:

似乎以下原因导致从您的 Service 广播的 Intent 与 BroadcastReceiver 上设置的 IntentFilter 不匹配。

Intent broadcastIntent = new Intent(CALLBACK_ACTION);
broadcastIntent.setAction(ON_MESSAGE_RECEIVED);

IntentFilter 是为CALLBACK_ACTION 设置的,并且 Intent 正在使用相同的操作进行实例化,但上面的第二行是将 Intent 的操作重置为ON_MESSAGE_RECEIVED,导致它不再匹配 BroadcastReceiver 上的过滤器.

一种可能的解决方案是向 IntentFilter 添加多个操作,并在接收器的 onReceive() 方法中检查传递的操作以确定如何处理广播。

例如:

IntentFilter filter = new IntentFilter(MQTTService2.ACTION_MESSAGE_RECEIVED);
filter.addAction(MQTTService2.ACTION_OTHER);

然后,在onReceive() 方法中:

@Override
public void onReceive(Context context, Intent intent)
{
    String action = intent.getAction();

    if(action.equals(ACTION_MESSAGE_RECEIVED)) {
        ...
    }
    else if(action.equals(ACTION_OTHER)) {
        ...
    }
    ...
}

然后,您将使用所需的操作实例化广播 Intent,然后删除 setAction() 调用:

Intent broadcastIntent = new Intent(MQTTService2.ACTION_MESSAGE_RECEIVED);
...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多