I have been looking for an answer for this question for a long time and no one seemed to have an answer.
I am trying to subscribe to location updates, using Google's latest FusedLocationProviderAPI. I have followed tutorial online and it works by getting my location every now and then using intentservice triggered by requestLocationUpdates.
Moving on, I try to add pass a custom class of object "User" to my intentservice. This custom class would allow me to upload the location to my server for background location update.
The way I add the custom object is by adding bundle to the intent, which is then added to the pendingIntent that triggers the IntentService. Unfortunately, the intentservice would immediately become broken and return null as soon as the bundle is added.
Here is my code, in MainActivity where I trigger the IntentService:
@Override
public void onConnected(Bundle arg0) {
// This is for creating the intent that is used for handler class
Intent intent = new Intent(MainActivity.this, MyLocationHandler.class);
Bundle b = new Bundle();
b.putParcelable("user", user);
//intent.putExtras(b);
intent.putExtra("bundle",b);
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Then the off screen periodic update
PendingResult pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
mLocationRequest, pendingIntent);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
As you can see from the above, I would add a bundle 'b' to the intent, which is added to the pendingIntent and triggers the LocationHandler class:
public class MyLocationHandler extends IntentService {
User user;
private String TAG = this.getClass().getSimpleName();
public MyLocationHandler() {
super("MyLocationHandler");
}
@Override
protected void onHandleIntent(Intent intent) {
Bundle bundle = intent.getBundleExtra("bundle");
//Bundle bundle = intent.getExtras();
if (bundle == null) {
Log.e(TAG, "bundle is null");
} else {
bundle.setClassLoader(User.class.getClassLoader());
}
user = (User) bundle.getParcelable("user");
if (user == null) {
Log.e(TAG, "user is null");
}
if (LocationResult.hasResult(intent)) {
LocationResult locationResult = LocationResult.extractResult(intent);
Location location = locationResult.getLastLocation();
Log.i(TAG, Double.toString(location.getLatitude()) + ", " + Double.toString(location.getLongitude()));
if (user != null) {
user.updateLocation(location); // This is a method in the custom class that sends location to the server
}
} else
Log.e(TAG, "Null object returned for location API");
}
Whenever I try to add a bundle, location would return null in LocationHandler class, but if I remove the bundle, the location updates are resumed.
Attached my manifest just in case:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.example.projecttesting.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.projecttesting.permission.C2D_MESSAGE" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
<application
android:allowBackup="true"
tools:replace="icon, label"
android:icon="@drawable/ic_launcher"
android:label="SamePage"
android:theme="@style/Theme.AppCompat.Light.NoActionBar" >
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyCDY8ulp1VGKwGdaRU19G4sfuXsymZGgoY" />
<activity
android:name=".LoginActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
</activity>
<activity
android:name=".EventLocationInput"
android:windowSoftInputMode="adjustPan" />
<activity android:name=".EventPeopleInput" />
<activity android:name=".EventCreation"/>
<service android:enabled="true" android:name=".MyLocationHandler"/>
<activity android:name="com.facebook.FacebookActivity"
android:configChanges=
"keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:label="@string/app_name" />
<receiver
android:name=".GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.example.projecttesting" />
</intent-filter>
</receiver>
<service android:name=".GcmMessageHandler" />
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
</application>
</manifest>
So far I only see a similar question raised here otherwise: Android FusedLocationProviderApi: Incoming intent has no LocationResult or LocationAvailability
This has been driving me crazy. Hope someone can shred some light on this.
Thanks.