0

I want to make a service (background operation) in Android to track the location of a device every now and then and store it on SharedPreference or send it to my server when location changes. I came accross this code from Get current location name of user without using gps or internet but by using Network_Provider in android and Android Developers - Getting the Last Known Location.

This is the code:

public class MainActivity extends AppCompatActivity implements
ConnectionCallbacks, OnConnectionFailedListener {

    protected static final String TAG = "MainActivity";

    /**
    * Provides the entry point to Google Play services.
    */
    protected GoogleApiClient mGoogleApiClient;

    /**
    * Represents a geographical location.
    */
    protected Location mLastLocation;

    protected String mLatitudeLabel;
    protected String mLongitudeLabel;
    protected TextView mLatitudeText;
    protected TextView mLongitudeText;



    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);

        mLatitudeLabel = getResources().getString(R.string.latitude_label);
        mLongitudeLabel = getResources().getString(R.string.longitude_label);
        mLatitudeText = (TextView) findViewById((R.id.latitude_text));
        mLongitudeText = (TextView) findViewById((R.id.longitude_text));

        buildGoogleApiClient();
    }

    /**
    * Builds a GoogleApiClient. Uses the addApi() method to request the LocationServices API.
    */
    protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
        .addConnectionCallbacks(this)
        .addOnConnectionFailedListener(this)
        .addApi(LocationServices.API)
        .build();
    }

    @Override
    protected void onStart() {
        super.onStart();
        mGoogleApiClient.connect();
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (mGoogleApiClient.isConnected()) {
            mGoogleApiClient.disconnect();
        }
    }

    /**
    * Runs when a GoogleApiClient object successfully connects.
    */
    @Override
    public void onConnected(Bundle connectionHint) {
        // Provides a simple way of getting a device's location and is well suited for
        // applications that do not require a fine-grained location and that do not need location
        // updates. Gets the best and most recent location currently available, which may be null
        // in rare cases when a location is not available.
        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if (mLastLocation != null) {
            Log.e("Location", "not null");
            makeUseOfNewLocation(mLastLocation);
            } else {
            Toast.makeText(this, R.string.no_location_detected, Toast.LENGTH_LONG).show();
            // should request new one
            // location should be enabled
            Log.i(TAG,
            "No location data previously acquired.. should request!");

            Toast.makeText(this,
            "Requesting location data ..",
            Toast.LENGTH_SHORT).show();

            LocationRequest locationRequest = LocationRequest.create();
            locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            locationRequest.setInterval(5000);

            PendingResult<Status> result = LocationServices.FusedLocationApi
            .requestLocationUpdates(mGoogleApiClient,
            locationRequest,
            new LocationListener() {

                @Override
                public void onLocationChanged(Location location) {
                    Log.e("Location", "not null");
                    makeUseOfNewLocation(location);
                }
            });
            // TODO: use result to retrieve more info
            Toast.makeText(this, result.toString(),Toast.LENGTH_LONG);
        }
    }

    @Override
    public void onConnectionFailed(ConnectionResult result) {
        // Refer to the javadoc for ConnectionResult to see what error codes might be returned in
        // onConnectionFailed.
        Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
    }


    @Override
    public void onConnectionSuspended(int cause) {
        // The connection to Google Play services was lost for some reason. We call connect() to
        // attempt to re-establish the connection.
        Log.i(TAG, "Connection suspended");
        mGoogleApiClient.connect();
    }
    private void makeUseOfNewLocation(Location location) {
        // do your stuff here
        mLatitudeText.setText(String.format("%s: %f", mLatitudeLabel,
        location.getLatitude()));
        mLongitudeText.setText(String.format("%s: %f", mLongitudeLabel,
        location.getLongitude()));
    }
}

My question is can this code be a Service by just extending Service on this class. Will this work and be able to track the device's location every now and then on the background

Community
  • 1
  • 1
Jaye
  • 132
  • 1
  • 10

1 Answers1

0

As per Google's documentation, you will need to use a PendingIntent in onConnected to make sure you have a background service running even when the app is off the screen.

https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderApi

public abstract PendingResult requestLocationUpdates (GoogleApiClient client, LocationRequest request, PendingIntent callbackIntent)

Requests location updates with a callback on the specified PendingIntent.

This method is suited for the background use cases, more specifically for receiving location updates, even when the app has been killed by the system. In order to do so, use a PendingIntent for a started service. For foreground use cases, the LocationListener version of the method is recommended, see requestLocationUpdates(GoogleApiClient, LocationRequest, LocationListener).

My previous method is create an intent which is included in your pendingIntent, then indicates in the intent to pass from your current activity to a Handler class. In the handler class which extends the IntentService, you will be able to get whatever location information in the onHandle method.

You can take a look at one of my previous questions for reference: FusedLocationProvider using intentservice for background location update: location update does not work when pendingintent has a bundle added

Community
  • 1
  • 1
Steph
  • 21
  • 1
  • 6