FusedLocationProvider using intentservice for background location update: location update does not work when pendingintent has a bundle added

旧街凉风 提交于 2020-01-01 07:04:31

问题


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.


回答1:


As suggested I will post my answer here. It is not exactly solving the problem that I had, but I managed to make it work by using SharedPreferenceManager to store what I needed in another activity and retrieved it in the Handler class. Not the most elegant solution but effectiveness nonetheless. This may be a workaround if what you need is small in size and does not change often.



来源:https://stackoverflow.com/questions/34157038/fusedlocationprovider-using-intentservice-for-background-location-update-locati

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!