UPDATE (1 Nov, 2017): I was able to reproduce the error in an MCV example linked herein: locationServiceMCV github repo
It seems that the location is retrieved only when I navigate to the activity the second time. So, I'm guessing that the issue has something to do with lifecycles?
I have a service that gets the user's location and broadcasts the latitude and longitude in an intent:
Service
@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");
}
}
I've successfully registered a BroadcastReceiver in my mainActivity, which gets the location information just fine:
Main Activity
//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);
I have another activity, NewSwarmReportActivity, that also needs to receive the location broadcast. I'm hoping to keep the service active in the background even when the app gets closed, so this is what it looks like in the manifest:
manifest:
<service
android:name=".services.LocationService"
android:enabled="true"
android:exported="true">
</service>
I'm not sure whether I have to start the location service again in the second activity (I'm guessing/hoping not, especially since I have no code to shut down the service in my first activity on purpose). But either way, registering a BroadcastReceiver in the NewSwarmReportActivity doesn't seem to be working:
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);
}
I hope you'll forgive my newness. onReceive
never seems to get called in NewSwarmReportActivity. I can't quite figure out why not. Any help is much appreciated.
Here's my module's gradle file:
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'
}