BroadcastReceiver onReceive 方法没有被调用?

BroadcastReceiver onReceive method not called?

我有一项服务 运行,我在其中获取位置更新。服务returns定位成功。但在那之后,我试图将位置广播给任何可能正在收听的 activity。我已经在我的 activity 中注册了接收器,但由于某种原因 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);
}

在我的 activity 方法中,我正在注册 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();
    }
};

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

我也没有将 activity 扩展到 BroadcastReceiver,因为 activity 已经扩展到 FragmentActivity

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

我设法解决了这个问题。我将 post 我的发现和将来遇到此问题的其他人的答案。我可能在这里简化了很多概念,但为了理解这个特定问题,我会尽量准确地理解我的理解。

答案:

问题是我没有使用相同的 Context 发送广播和接收广播。我的意思是,这就是我在 Manifest 文件

中声明我的服务的方式
<service
        android:name=".GoogleFusedLocationApiService"
        android:process=":google_fused_location_api_service"/>

android:process 属性意味着此服务将 运行 在与应用 运行 正在运行的进程不同的进程上。因此,当我调用时,super.registerReceiver(mMessageReceiver, intentFilter); 是从 Activity 的上下文中调用的,而当我调用 broadcaster = LocalBroadcastManager.getInstance(this); broadcaster.sendBroadcast(intent); 时,sendBroadcast 是从服务的上下文中调用的它有一个不同的过程 运行ning 。所以你看我是从不同的上下文注册接收器并从不同的上下文发送广播。

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

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

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

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

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