BroadcastReceiver onReceive方法没有被调用?

时间:2017-12-30 13:23:36

标签: java android broadcastreceiver broadcast android-broadcastreceiver

我正在运行一项服务,我正在获取位置更新。该服务成功返回该位置。但之后我试图将该位置广播到任何可能正在收听的活动。我已在我的活动中注册了接收器,但由于某种原因未调用onReceive方法。 以下是我服务中onLocationChanged方法内的代码。

@Override
public void onLocationChanged(Location location) {
    Intent intent = new Intent();
    intent.setAction("LocationBroadcast");
    double lat = location.getLatitude();
    double lng = location.getLongitude();
    intent.putExtra("lat", lat);
    intent.putExtra("lng", lng);
    //I am initializing the broadcaster object in onCreate method of my service but I am putting it here for simplicity
    broadcaster = LocalBroadcastManager.getInstance(this);
    //This Toast successfully shows my coordinates so I know the problem is not with this method
    Toast.makeText(GoogleFusedLocationApiService.this, ""+lat+", "+lng+"", Toast.LENGTH_SHORT).show();
    broadcaster.sendBroadcast(intent);
}

在我的onCreate方法活动中,我正在注册LocationBroadcast

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    ...
    IntentFilter intentFilter = new IntentFilter("LocationBroadcast");
    super.registerReceiver(mMessageReceiver, intentFilter);
    startService(new Intent(MyApp.getAppContext(), GoogleFusedLocationApiService.class));
}

我已经尝试了this.registerReceiver(mMessageReceiver, intentFilter);LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, intentFilter);,但都没有效果。

这是我的mMessageReceiver定义的

public BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        double lat = intent.getDoubleExtra("lat", 0);
        double lng = intent.getDoubleExtra("lng", 0);
        // This Toast never shows and neither can I debug this method at all
        // so for now the only conclusion is the broadcast is not being received
        Toast.makeText(MyApp.getAppContext(), "Cordinates are "+lat+", "+lng+"", Toast.LENGTH_SHORT).show();
    }
};

此外,经过一些研究后,我可能认为有些细节很重要。我没有在receiver中声明manifest,因为我读到你只是在收到广播时希望你的应用程序启动但我只希望我的应用程序在它已经运行时做出反应。只要服务发送广播,就不会启动。

我还没有将活动扩展到BroadcastReceiver,因为活动已经延长到FragmentActivity

应用程序不会崩溃,并且onLocationChanged位于注册BroadcastReceiver后正在启动的服务内部,因此在注册BroadcastReceiver之前不会调用onLocationChanged

1 个答案:

答案 0 :(得分:1)

我设法解决了这个问题。我会发布我的发现和答案,以便将来面对这个问题。我可能在这里愚弄了很多概念,但为了理解这个具体的问题,我会尽量做到最好的理解。

答案:

问题在于我没有发送广播并使用相同的Context接收广播。我的意思是,这就是我在Manifest文件中声明我的服务的方式

<service
        android:name=".GoogleFusedLocationApiService"
        android:process=":google_fused_location_api_service"/>

android:process属性意味着此服务将在与运行应用程序的进程不同的进程上运行。因此,当我打电话时,super.registerReceiver(mMessageReceiver, intentFilter);从活动的上下文中调用它,当我在这里调用broadcaster = LocalBroadcastManager.getInstance(this); broadcaster.sendBroadcast(intent);sendBroadcast从具有不同服务的上下文中调用为它运行的进程。所以你看到我从不同的上下文注册接收器并从不同的上下文发送广播。

LocalBroadcastManager仅在从同一进程(即上下文)发送和接收广播时起作用。所以在这种情况下,由于我的服务和我的app / activity正在运行或是单独的进程,即上下文我无法使用LocalBroadcastManager。我需要使用全球广播,并确保我正在注册广播并从相同的上下文发送广播。

现在,因为我有一个静态的app应用程序,我可以在任何地方使用,只需调用MyApp.getAppContext(),如果我注册广播接收器并发送,你可以从this answer学习如何做使用此上下文进行广播,这意味着两者都是从MyApp.getAppContext()的相同上下文完成的,现在我开始成功接收广播。

总而言之,如果您有单独的服务流程,请使用MyApp.getAppContext().registerReceiver()MyApp.getAppContext().sendBroadcast()

如果您的服务具有相同的处理流程,或者在Manifest文件中的服务标签中没有android:process属性,则可以使用LocalBroadcastManager.getInstance(this).registerReceiver()LocalBroadcastManager.getInstance(this).sendBroadcast()

您仍然可以在此处使用MyApp.getAppContext,但在第二种情况下,使用LocalBroadcastManager是最佳做法和正确的做法。