【问题标题】:BroadcastReceiver in activity2 not receiving broadcast sent by service started in activity1活动 2 中的 BroadcastReceiver 未接收活动 1 中启动的服务发送的广播
【发布时间】:2017-11-02 07:12:39
【问题描述】:

更新(2017 年 11 月 1 日):我能够在此处链接的 MCV 示例中重现该错误: locationServiceMCV github repo

似乎只有当我第二次导航到活动时才检索到该位置。所以,我猜这个问题与生命周期有关?

我有一项服务可以获取用户的位置并在意图中广播纬度和经度:

服务

@Override
public void onConnected(@Nullable Bundle bundle) {
    Log.d("personal", "got into onConnected");

    Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    if (location == null) {
        Log.d("personal", "location null");
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    } else {
        Log.d("personal", "location not null");
        handleNewLocation(location);
    }
}

private void handleNewLocation(Location location) {
    Log.d("personal", "got to handleNewLocation");
    currentLatitude = location.getLatitude();
    currentLongitude = location.getLongitude();
    Log.d("personal", "lat from handleNewLocation is " + currentLatitude.toString());
    Log.d("personal", "long from handleNewLocation is " + currentLongitude.toString());
    if (currentLatitude != null && currentLongitude != null) {
        setUpGeoFire();
        sendToActivity(currentLatitude, currentLongitude);
    }
}

public void sendToActivity(Double currentLatitude, Double currentLongitude){
    Log.d("personal", "got to sendToActivity");
    Intent intent = new Intent("locationServiceUpdates");
    intent.putExtra("ServiceLatitudeUpdate", currentLatitude.toString());
    intent.putExtra("ServiceLongitudeUpdate", currentLongitude.toString());
    if(serviceContext != null){
        LocalBroadcastManager.getInstance(serviceContext).sendBroadcast(intent);
        Log.d("personal", "broadcast launched from the location service");
        Toast.makeText(this, "broadcast launched from the location service", Toast.LENGTH_SHORT).show();
    } else{
        Log.d("personal", "didn't broadcast the location updates because serviceContext is null");
    }
}

我在mainActivity中成功注册了一个BroadcastReceiver,获取位置信息就好了:

主要活动

//Start location service//
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_FINE_LOCATION);
        return;
    }
    startLocationService();
    BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // Get extra data included in the Intent
            currenLatitude = Double.parseDouble(intent.getStringExtra("ServiceLatitudeUpdate"));
            currentLongitude = Double.parseDouble(intent.getStringExtra("ServiceLongitudeUpdate"));
            Log.d("personal", "onReceive of broadcast receiver reached");
            Log.d("personal", "onReceive lat is " + currenLatitude.toString());
            Log.d("personal", "onReceive long is " + currentLongitude.toString());
            ArrayList<String> children = new ArrayList<>();
            children.add(userId + "_current");
            setUpFirebaseAdapter(children);
        }
    };
    IntentFilter intentFilter = new IntentFilter("locationServiceUpdates");
    LocalBroadcastManager.getInstance(MainActivity.this).registerReceiver(mMessageReceiver, intentFilter);

我还有另一个活动,NewSwarmReportActivity,它也需要接收位置广播。我希望即使在应用程序关闭时也能在后台保持服务处于活动状态,所以这就是清单中的样子:

清单:

<service
        android:name=".services.LocationService"
        android:enabled="true"
        android:exported="true">
</service>

我不确定是否必须在第二个活动中再次启动位置服务(我猜/希望不会,特别是因为我没有代码可以在我的第一个活动中故意关闭该服务)。但无论哪种方式,在 NewSwarmReportActivity 中注册一个 BroadcastReceiver 似乎都不起作用:

NewSwarmReportActivity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_new_swarm_report);

    ButterKnife.bind(this);
    ...

    getSharedPreferences();
    Log.d("personal", "newSwarm userName is " + userName);
    Log.d("personal", "newSwarm userId is " + userId);

    startLocationService(); //Don't think I should do this.
    IntentFilter intentFilter = new IntentFilter("locationServiceUpdates");

    BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // Get extra data included in the Intent
            currenLatitude = Double.parseDouble(intent.getStringExtra("ServiceLatitudeUpdate"));
            currentLongitude = Double.parseDouble(intent.getStringExtra("ServiceLongitudeUpdate"));
            Log.d("personal", "onReceive in NewSwarmReportActivity of broadcast receiver reached");
            Log.d("personal", "onReceive in NewSwarmReportActivity lat is " + currenLatitude.toString());
            Log.d("personal", "onReceive in NewSwarmReportActivity long is " + currentLongitude.toString());
            if (userId != null && userName != null && currenLatitude != 0.0 && currentLongitude != 0.0) {
                progressBar.setVisibility(View.GONE);
                reportSwarmButton.setVisibility(View.VISIBLE);
                addImageButton.setVisibility(View.VISIBLE);
            } else {
                Log.d("newSwarm", "either location or user info is null!");
            }
        }
    };
    LocalBroadcastManager.getInstance(NewSwarmReportActivity.this).registerReceiver(mMessageReceiver, intentFilter);

}

我希望你能原谅我的新鲜感。 onReceive 似乎从未在 NewSwarmReportActivity 中被调用。我不太明白为什么不。非常感谢任何帮助。

这是我模块的 gradle 文件:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "fisherdynamic.locationservicemcv"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    compile 'com.google.android.gms:play-services-location:10.0.1'
}

【问题讨论】:

  • 什么时候注销接收器?建议在活动生命周期的某些过渡期间取消注册。见this doc。您的活动是否可能已暂停/停止/销毁并且接收方已取消注册或上下文不再有效?
  • @Cheticamp,mMessageReceiver 在主活动中注册,但永远不会取消注册。我最初是故意这样做的。你认为它泄漏了接收器,这是问题的一部分吗?泄漏会干扰第二个活动中广播接收器的新声明是否有意义?
  • 您至少应该在主要活动的onDestroy() 中取消注册接收器以避免泄漏,但我认为这不是您的问题。我假设您正在使您的 swarm 活动在期待广播之前执行其onCreate()。 MCVE 将加快来自社区的回答。
  • 感谢@Cheticamp 的建议!我链接到底部的 MCVE github repo。
  • 您为什么希望在您的 Swarm 活动中获得广播?服务启动一次,位置获取一次,通知一次。之后,只有在位置发生变化时,您才会收到更新。您在 Swarm 活动时是否在移动?此外,您需要收听位置更新。我在您的位置服务中没有看到位置更新侦听器。尝试使用您的 locationupdate 请求注册 LocationListener。

标签: android service broadcastreceiver android-broadcast


【解决方案1】:

试试这个代码发送广播到活动表单服务,

        Intent intent = new Intent(getPackageName());
        intent.putExtra(LOCATION_UPDATED, location);
        sendBroadcast(intent);

在我的活动中,这里是接收广播的代码,

private BroadcastReceiver broadcastReceiver;

注册接收器,

broadcastReceiver = createBroadcastReceiver();
registerReceiver(broadcastReceiver, new IntentFilter(getPackageName()));


private BroadcastReceiver createBroadcastReceiver() {
        return new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {

                if (intent.hasExtra(LocationService.LOCATION_UPDATED)) {
                    //Log.e(TAG, "##--Location Updated--##");
                    Bundle b = intent.getExtras();
                    if (b != null) {
                        mCurrentLocation = (Location) b.get(LocationService.LOCATION_UPDATED);
                    }
                }

        }
     };
}

【讨论】:

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