Google Fused API Background Location Update with Retrofit

Step by step guide to develop a simple android application to upload the user’s location to the server via Background Intent Service using Retrofit Networking library.

 

 

Hello,

 

We will work on this with  Google’s Fused Location API and Retrofit. I will show you how to continuously update your device’s location via background service.

 

 

 

Download the APK file here to test the live map.

 

Close the app After you press the Start Background location Service button.  You can make sure the app is working in the background. if it is not working in the behind the scene let me know.

 

Download the source code from my git repo

 

How to check your location in live map

 

 

You can check the live map view from https://appsgit.com/mapsync

To check live url download the apk file from here and install it in your device. You should provide your name/email in the activity textfield in order to show it on the google map view.

 

 

Setup New Android Project

 

 

 

Setup the necessary libraries

add the following code snippets in your app module  build.gradle file.

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:26+'
    testCompile 'junit:junit:4.12'

    compile 'com.android.support:design:26+'
    compile 'com.google.android.gms:play-services-location:10.2.4'

    compile 'com.google.code.gson:gson:2.8.2'
    compile 'com.squareup.retrofit2:converter-gson:2.3.0'

    compile 'com.squareup.okhttp3:logging-interceptor:3.8.0'
}

 

did you notice that i have added Interceptor library as well. It will help us to see the extra logging of the web service request and response.

 

Implement Google’s Location’s classes.

 

i have implemented following interfaces in MainActivity.java

  1. GoogleApiClient.ConnectionCallbacks
  2. GoogleApiClient.OnConnectionFailedListener
  3. SharedPreferences.OnSharedPreferenceChangeListener

 

GoogleApiClient.ConnectionCallbacks

The onConnected() and onConnectionSuspended() methods will be called, after the google client connected or suspended.

 

GoogleApiClient.OnConnectionFailedListener

The onConnectionFailed() method will be called, after the google client failed.

 

SharedPreferences.OnSharedPreferenceChangeListener

onSharedPreferenceChanged() will be called whenever we make changes (saved/updated) in shared preferences.

 

 

Copy the following MainActivity.java class 

 

 
package com.appsgit.locationupdate.retrofit;

import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.support.design.widget.Snackbar;
import android.Manifest;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;



public class MainActivity extends FragmentActivity implements GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener,
        SharedPreferences.OnSharedPreferenceChangeListener {

    private static final String TAG = MainActivity.class.getSimpleName();
    private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;


    private static final long UPDATE_INTERVAL = 10 * 1000;

    private static final long FASTEST_UPDATE_INTERVAL = UPDATE_INTERVAL / 2;

    private static final long MAX_WAIT_TIME = UPDATE_INTERVAL * 2;

    private LocationRequest mLocationRequest;

    private GoogleApiClient mGoogleApiClient;

    // UI Widgets.
    private Button mRequestUpdatesButton;
    private Button mRemoveUpdatesButton;
    private TextView mLocationUpdatesResultView;

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

        mRequestUpdatesButton = (Button) findViewById(R.id.request_updates_button);
        mRemoveUpdatesButton = (Button) findViewById(R.id.remove_updates_button);
        mLocationUpdatesResultView = (TextView) findViewById(R.id.location_updates_result);

        // Check if the user revoked runtime permissions.
        if (!checkPermissions()) {
            requestPermissions();
        }

        buildGoogleApiClient();
    }

    @Override
    protected void onStart() {
        super.onStart();
        PreferenceManager.getDefaultSharedPreferences(this)
                .registerOnSharedPreferenceChangeListener(this);
    }


    @Override
    protected void onResume() {
        super.onResume();
        updateButtonsState(LocationRequestHelper.getRequesting(this));
        updateTextField();
    }

    @Override
    protected void onStop() {
        PreferenceManager.getDefaultSharedPreferences(this)
                .unregisterOnSharedPreferenceChangeListener(this);
        super.onStop();
    }

    public void updateTextField() {
        try {

            String backGroundEnabled = "";

            if (LocationRequestHelper.getRequesting(this)) {
                backGroundEnabled = "Background Enabled. \n";
            } else {
                backGroundEnabled = "Background Disabled. \n";
            }

            String filterName = "";

            if (!LocationRequestHelper.getFilterName(this).equals("")) {
                filterName = "FilterName :- " + LocationRequestHelper.getFilterName(this) + "\n\n";
                TextView filterNameView = findViewById(R.id.filterName);
                filterNameView.setText(LocationRequestHelper.getFilterName(this));
            } else {
                filterName = "No Filter Name SAved.!\n\n";
            }

            mLocationUpdatesResultView.setText(filterName + backGroundEnabled + LocationResultHelper.getSavedLocationResult(this));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void saveFilterName(View view) {
        try {
            TextView filterNameView = findViewById(R.id.filterName);
            if (!filterNameView.getText().toString().trim().equals("")) {
                LocationRequestHelper.setFilterName(this, filterNameView.getText().toString());
                Toast.makeText(this, "Saved successfully.!", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "Not Saved.!", Toast.LENGTH_SHORT).show();
            }
            updateTextField();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Sets up the location request. Android has two location request settings:
     * {@code ACCESS_COARSE_LOCATION} and {@code ACCESS_FINE_LOCATION}. These settings control
     * the accuracy of the current location. This sample uses ACCESS_FINE_LOCATION, as defined in
     * the AndroidManifest.xml.
     * <p/>
     * When the ACCESS_FINE_LOCATION setting is specified, combined with a fast update
     * interval (5 seconds), the Fused Location Provider API returns location updates that are
     * accurate to within a few feet.
     * <p/>
     * These settings are appropriate for mapping applications that show real-time location
     * updates.
     */
    private void createLocationRequest() {
        mLocationRequest = new LocationRequest();

        mLocationRequest.setInterval(UPDATE_INTERVAL);

        // Sets the fastest rate for active location updates. This interval is exact, and your
        // application will never receive updates faster than this value.
        mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);

        // Sets the maximum time when batched location updates are delivered. Updates may be
        // delivered sooner than this interval.
        mLocationRequest.setMaxWaitTime(MAX_WAIT_TIME);
    }

    /**
     * Builds {@link GoogleApiClient}, enabling automatic lifecycle management using
     * {@link GoogleApiClient.Builder#enableAutoManage(android.support.v4.app.FragmentActivity,
     * int, GoogleApiClient.OnConnectionFailedListener)}. I.e., GoogleApiClient connects in
     * {@link AppCompatActivity#onStart}, or if onStart() has already happened, it connects
     * immediately, and disconnects automatically in {@link AppCompatActivity#onStop}.
     */
    private void buildGoogleApiClient() {
        if (mGoogleApiClient != null) {
            return;
        }
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .enableAutoManage(this, this)
                .addApi(LocationServices.API)
                .build();
        createLocationRequest();
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        Log.i(TAG, "GoogleApiClient connected");
    }

    private PendingIntent getPendingIntent() {

        Intent intent = new Intent(this, LocationUpdatesIntentService.class);
        intent.setAction(LocationUpdatesIntentService.ACTION_PROCESS_UPDATES);
        return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        /* if you are target is Android "o" then you should enable broadcast receiver.
        Intent intent = new Intent(this, LocationUpdatesBroadcastReceiver.class);
        intent.setAction(LocationUpdatesBroadcastReceiver.ACTION_PROCESS_UPDATES);
        return PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);*/
    }

    @Override
    public void onConnectionSuspended(int i) {
        final String text = "Connection suspended";
        Log.w(TAG, text + ": Error code: " + i);
        showSnackbar("Connection suspended");
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        final String text = "Exception while connecting to Google Play services";
        Log.w(TAG, text + ": " + connectionResult.getErrorMessage());
        showSnackbar(text);
    }

    /**
     * Shows a {@link Snackbar} using {@code text}.
     *
     * @param text The Snackbar text.
     */
    private void showSnackbar(final String text) {
        View container = findViewById(R.id.activity_main);
        if (container != null) {
            Snackbar.make(container, text, Snackbar.LENGTH_LONG).show();
        }
    }

    /**
     * Return the current state of the permissions needed.
     */
    private boolean checkPermissions() {
        int permissionState = ActivityCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION);
        return permissionState == PackageManager.PERMISSION_GRANTED;
    }

    private void requestPermissions() {
        boolean shouldProvideRationale =
                ActivityCompat.shouldShowRequestPermissionRationale(this,
                        Manifest.permission.ACCESS_FINE_LOCATION);

        // Provide an additional rationale to the user. This would happen if the user denied the
        // request previously, but didn't check the "Don't ask again" checkbox.
        if (shouldProvideRationale) {
            Log.i(TAG, "Displaying permission rationale to provide additional context.");
            Snackbar.make(
                    findViewById(R.id.activity_main),
                    R.string.permission_rationale,
                    Snackbar.LENGTH_INDEFINITE)
                    .setAction(R.string.ok, new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            // Request permission
                            ActivityCompat.requestPermissions(MainActivity.this,
                                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                    REQUEST_PERMISSIONS_REQUEST_CODE);
                        }
                    })
                    .show();
        } else {
            Log.i(TAG, "Requesting permission");
            // Request permission. It's possible this can be auto answered if device policy
            // sets the permission in a given state or the user denied the permission
            // previously and checked "Never ask again".
            ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    REQUEST_PERMISSIONS_REQUEST_CODE);
        }
    }

    /**
     * Callback received when a permissions request has been completed.
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        Log.i(TAG, "onRequestPermissionResult");
        if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
            if (grantResults.length <= 0) {
                // If user interaction was interrupted, the permission request is cancelled and you
                // receive empty arrays.
                Log.i(TAG, "User interaction was cancelled.");
            } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission was granted. Kick off the process of building and connecting
                // GoogleApiClient.
                buildGoogleApiClient();
            } else {
                // Permission denied.
                // Notify the user via a SnackBar that they have rejected a core permission for the
                // app, which makes the Activity useless. In a real app, core permissions would
                // typically be best requested during a welcome-screen flow.

                // Additionally, it is important to remember that a permission might have been
                // rejected without asking the user for permission (device policy or "Never ask
                // again" prompts). Therefore, a user interface affordance is typically implemented
                // when permissions are denied. Otherwise, your app could appear unresponsive to
                // touches or interactions which have required permissions.
                Snackbar.make(
                        findViewById(R.id.activity_main),
                        R.string.permission_denied_explanation,
                        Snackbar.LENGTH_INDEFINITE)
                        .setAction(R.string.settings, new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                // Build intent that displays the App settings screen.
                                Intent intent = new Intent();
                                intent.setAction(
                                        Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                Uri uri = Uri.fromParts("package",
                                        BuildConfig.APPLICATION_ID, null);
                                intent.setData(uri);
                                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                startActivity(intent);
                            }
                        })
                        .show();
            }
        }
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
        if (s.equals(LocationResultHelper.KEY_LOCATION_UPDATES_RESULT)) {
            updateTextField();
        } else if (s.equals(LocationRequestHelper.KEY_LOCATION_UPDATES_REQUESTED)) {
            updateButtonsState(LocationRequestHelper.getRequesting(this));
            updateTextField();
        } else if (s.equals(LocationRequestHelper.KEY_FILTER_NAME_UPDATED)) {
            String filterName = LocationRequestHelper.getFilterName(this);
        }
    }

    /**
     * Handles the Request Updates button and requests start of location updates.
     */
    public void requestLocationUpdates(View view) {
        try {
            //stop and re-start the location update..
            removeLocationUpdates(null);

            if (LocationRequestHelper.getFilterName(this).equals("")) {

                AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
                alertDialog.setTitle("Alert");
                alertDialog.setMessage("You should type Name/Email if you want to start the background task.");
                alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.dismiss();
                            }
                        });
                alertDialog.show();

                return;
            }
            Log.d(TAG, "requestLocationUpdates: Started to update location...!");
            LocationRequestHelper.setRequesting(this, true);
            LocationServices.FusedLocationApi.requestLocationUpdates(
                    mGoogleApiClient, mLocationRequest, getPendingIntent());
        } catch (SecurityException e) {
           LocationRequestHelper.setRequesting(this, false);
            e.printStackTrace();
        }
    }

    /**
     * Handles the Remove Updates button, and requests removal of location updates.
     */
    public void removeLocationUpdates(View view) {
        Log.i(TAG, "Removing location updates");
        LocationRequestHelper.setRequesting(this, false);
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,
                getPendingIntent());
    }

    /**
     * Ensures that only one button is enabled at any time. The Start Updates button is enabled
     * if the user is not requesting location updates. The Stop Updates button is enabled if the
     * user is requesting location updates.
     */
    private void updateButtonsState(boolean requestingLocationUpdates) {
        if (requestingLocationUpdates) {
            mRequestUpdatesButton.setEnabled(false);
            mRemoveUpdatesButton.setEnabled(true);
        } else {
            mRequestUpdatesButton.setEnabled(true);
            mRemoveUpdatesButton.setEnabled(false);
        }
    }
}

 

Copy the activity_main.xml

 

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.appsgit.locationupdate.retrofit.MainActivity">


    <TextView
        android:id="@+id/using_batched_location_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="@dimen/default_margin"
        android:text="@string/text_location_updates"
        android:autoLink="all"
        android:textSize="15sp" />

    <TextView
        android:id="@+id/using_batched_location_view2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="@dimen/default_margin"
        android:text="@string/text_location_updates2"
        android:autoLink="all"
        android:textSize="15sp" />

    <TextView
        android:id="@+id/using_batched_location_view3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="@dimen/default_margin"
        android:text="@string/text_location_updates3"
        android:autoLink="all"
        android:textSize="15sp" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:weightSum="3"
        android:layout_margin="10dp">

        <EditText
            android:id="@+id/filterName"
            android:layout_width="0dp"
            android:layout_weight="2"
            android:layout_height="60dp"
            android:hint="Type your name/email to filter in MapView."/>
        <Button
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="40dp"
            android:padding="5dp"
            android:background="@color/colorAccent"
            android:foreground="?selectableItemBackground"
            android:text="Save Name"
            android:onClick="saveFilterName"></Button>
    </LinearLayout>

    <Button
        android:id="@+id/request_updates_button"
        android:background="@color/colorAccent"
        android:foreground="?selectableItemBackground"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="requestLocationUpdates"
        android:text="@string/request_updates"
        android:layout_margin="10dp"/>

    <Button
        android:id="@+id/remove_updates_button"
        android:background="@color/colorAccent"
        android:foreground="?selectableItemBackground"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="@dimen/default_margin"
        android:onClick="removeLocationUpdates"
        android:text="@string/remove_updates"
        android:layout_margin="10dp"/>

    <TextView
        android:id="@+id/location_updates_result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/default_margin" />
</LinearLayout>

 

The following method start request the location.the method will called when you press the Start Background Update button.

 

/**
 * Handles the Request Updates button and requests start of location updates.
 */
public void requestLocationUpdates(View view) {
    try {
        //stop and re-start the location update..
        removeLocationUpdates(null);

        if (LocationRequestHelper.getFilterName(this).equals("")) {

            AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
            alertDialog.setTitle("Alert");
            alertDialog.setMessage("You should type Name/Email if you want to start the background task.");
            alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
                    new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                        }
                    });
            alertDialog.show();

            return;
        }
        Log.d(TAG, "requestLocationUpdates: Started to update location...!");
        LocationRequestHelper.setRequesting(this, true);
        LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, getPendingIntent());
    } catch (SecurityException e) {
       LocationRequestHelper.setRequesting(this, false);
        e.printStackTrace();
    }
}

 

Add the Retrofit related codes

The ApiClient.java and  ApiClientBuilder.java

//ApiClient.java
package com.appsgit.locationupdate.retrofit.jsonclient;

import android.location.Location;

import com.appsgit.locationupdate.retrofit.jsonclient.model.LocationData;

import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;

/**
 * Created on 10/15/17.
 */

public interface ApiClient {

    @FormUrlEncoded
    @POST("/mapsync/add_markers.php")
    Call<ResponseBody> updateLocation(@Field(value = "name") String name, @Field(value = "lat") double lat, @Field(value = "lng") double lng);
}

 

//ApiClientBuilder.java
package com.appsgit.locationupdate.retrofit.jsonclient;

import com.google.gson.GsonBuilder;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class ApiClientBuilder {

    public static final String BASE_URL = "https://appsgit.com";

    private static Retrofit retrofit = null;

    public static OkHttpClient.Builder httpClient;

    public static Retrofit getClient(String baseUrl) {

        //http logging interceptor will give us the information about web service call reqponse.
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);

        httpClient = new OkHttpClient.Builder();

        httpClient.readTimeout(60, TimeUnit.SECONDS);

        httpClient.connectTimeout(60, TimeUnit.SECONDS);

        httpClient.addInterceptor(logging);

        //We should add headers for the request.
        httpClient.addInterceptor(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request original = chain.request();

                Request request = original.newBuilder()
                        .header("Content-Type", "multipart/form-data")
                        .method(original.method(), original.body())
                        .build();

                return chain.proceed(request);
            }
        });

        retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .addConverterFactory(GsonConverterFactory.create(new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()))
                .client(httpClient.build())
                .build();

        return retrofit;
    }


    public static ApiClient getMGClient() {

        return getClient(BASE_URL).create(ApiClient.class);
    }

}

 

The following class is important. It will update the server whenever it receives the location from google location API.

 

//LocationUpdatesIntentService.java
package com.appsgit.locationupdate.retrofit;

import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.util.Log;
import android.view.View;

import com.appsgit.locationupdate.retrofit.jsonclient.model.LocationData;
import com.appsgit.locationupdate.retrofit.jsonclient.services.LocationService;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;

import java.util.List;

import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

/**
 * Handles incoming location updates and displays a notification with the location data.
 */
public class LocationUpdatesIntentService extends IntentService {

    static final String ACTION_PROCESS_UPDATES =
            "com.appsgit.locationupdate.retrofit.action" + ".PROCESS_UPDATES";

    private static final String TAG = LocationUpdatesIntentService.class.getSimpleName();


    public LocationUpdatesIntentService() {
        // Name the worker thread.
        super(TAG);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        if (intent != null) {
            final String action = intent.getAction();
            if (ACTION_PROCESS_UPDATES.equals(action)) {
                LocationResult result = LocationResult.extractResult(intent);
                if (result != null) {
                    List<Location> locations = result.getLocations();
                    LocationResultHelper locationResultHelper = new LocationResultHelper(this,
                            locations);
                    // Save the location data to SharedPreferences.
                    locationResultHelper.saveResults();

                    Location firstLocation = locations.get(0);

                    LocationData data = new LocationData();
                    data.setName(LocationRequestHelper.getFilterName(this));
                    data.setLat(firstLocation.getLatitude());
                    data.setLng(firstLocation.getLongitude());
                    updateServer(data);
                    // Show notification with the location data.
                    locationResultHelper.showNotification();
                    Log.i(TAG, LocationResultHelper.getSavedLocationResult(this));
                }
            }
        }
    }

    public void updateServer(LocationData locationData) {
        try {
            Log.d(TAG, "updateServer: called.. " + LocationRequestHelper.getFilterName(this));
            new LocationService().saveLocationData(this, locationData, new Callback<ResponseBody>() {
                @Override
                public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                    Log.d(TAG, "onResponse: called...");
                }

                @Override
                public void onFailure(Call<ResponseBody> call, Throwable t) {
                    t.printStackTrace();
                }
            });

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

 

I haven’t described all the classes which i have written in the app.  You can check them in the repository.

 

 

About Zumry

Zumry Mohamed

Self Taught iOS & Android Mobile Application Developer.

Article written by zumrywahid

Self Taught iOS & Android Mobile Application Developer.

Be the first to comment

Leave a Reply

Your email address will not be published. Required fields are marked *