0

I am a newbie to Android and working on my very first application. I am working on a application which takes continuous location update and show that on google map. It means no matter whether application is in foreground or in background.

For the same I am using fusedlocation API's requestLocationUpdates. There are two version of the same viz:

  1. With LocationListener when app is in foreground
  2. With pendingIntent when app goes to background.

So as per my understanding I have to use both as I need continuous update.So I am using both in my application as I need continuous update.

But as a surprise I got that requestLocationUpdates with pendingIntent giving me location update in foreground as well. So I am very confused here and sometime giving Location as NULL .

Please tell me what is the exact behaviour of requestLocationUpdates with pendingIntent . Will it work for both foreground and bckground ? If yes then why I am getting the Location as NULL sometime.

Another problem when I was using Locationreveiver then I was able toget proper location update when app was in foreground and I was drawing a line on googlemap. But I noticed my line was not in sync with googlemap route. It was zig zag . So here I am confused If I am getting continuous update then why not m route is sync with google route .

I am attaching the complecode of my location class. Please help

public class LocationMapsActivity extends FragmentActivity implements
        LocationListener,
        OnMapReadyCallback,
        GoogleApiClient.ConnectionCallbacks,
        ComponentCallbacks2,
        GoogleApiClient.OnConnectionFailedListener {

//*******************************member variables*********************************************
    private static final String TAG = "LocationActivity";
    private static final long INTERVAL = 1000 *02; //   1000*60*1  = 1 minute
    private static final long FASTEST_INTERVAL = 1000 *01 ;// 10 sec
    public  static LatLng mPrev = null;
    private double mCurrentDistance = 0;
    private double mTotalDistance = 0;
    private double mCurrentSpeed = 0;
    public static String stateOfLifeCycle = "";
    public static boolean wasInBackground = false;
    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;
    Location mCurrentLocation;
    Location mStartLocation;
    GoogleMap googleMap;


//********************************************
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate ...............................");

        wasInBackground = false;
        stateOfLifeCycle = "Create";

        //show error dialog if GoolglePlayServices not available
        if (!isGooglePlayServicesAvailable()) {
            finish();
        }
        createLocationRequest();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();

        setContentView(R.layout.activity_map_location);
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }
    //*******************ComponentCallbacks2*************************
    @Override
    public void onTrimMemory(int level) {
        if (stateOfLifeCycle.equals("Stop")) {
        wasInBackground = true;
        }
        super.onTrimMemory(level);
        Toast.makeText(getApplicationContext(),
                "Application OnTrimmemory ", Toast.LENGTH_SHORT)
        .show();

        }

//****************Activity****************************
        @Override
    public void onStart() {
        Toast.makeText(getApplicationContext(),"OnStart ", Toast.LENGTH_SHORT).show();
        Log.d(TAG, "onStart fired ..............");

        stateOfLifeCycle = "Start";
        if (wasInBackground) {
            Toast.makeText(getApplicationContext(),"Application came to foreground",Toast.LENGTH_SHORT).show();
           wasInBackground = false;
        }
        super.onStart();
            if(!mGoogleApiClient.isConnected())
               mGoogleApiClient.connect();
    }
//********************Activity************************
    @Override
    public void onStop() {
        stateOfLifeCycle = "Stop";
        Log.d(TAG, "onStop fired ..............");
        stopLocationUpdates();
      //  mGoogleApiClient.disconnect();
        super.onStop();
        Toast.makeText(getApplicationContext(), "OnStop ", Toast.LENGTH_SHORT).show();
        Log.d(TAG, "isConnected ...............: " + mGoogleApiClient.isConnected());
    }
    //**************Activity******************************
    @Override
    protected void onPause() {
        stateOfLifeCycle = "Pause";
        super.onPause();
        Toast.makeText(getApplicationContext(), "OnPause ", Toast.LENGTH_SHORT) .show();
    }
    //*******************Activity*************************
    @Override
    public void onResume() {
        Toast.makeText(getApplicationContext(),"OnResume ", Toast.LENGTH_SHORT).show();

        stateOfLifeCycle = "Resume";
        super.onResume();
        if (mGoogleApiClient.isConnected()) {
            startLocationUpdates();
            Log.d(TAG, "Location update resumed .....................");
        }
    }
    //*****************Activity***************************
    @Override
    public void onDestroy()
    {
        wasInBackground = false;
        stateOfLifeCycle = "Destroy";
        super.onDestroy();
        Toast.makeText(getApplicationContext(), "Application OnDestroy ", Toast.LENGTH_SHORT).show();
    }
    //******************OnMapReadyCallback**************************
    @Override
    public void onMapReady(GoogleMap map) {
        googleMap = map;
        googleMap.setMyLocationEnabled(true);
        googleMap.getUiSettings().setZoomControlsEnabled(true);
        //googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
    }
    //*******************GoogleApiClient.ConnectionCallbacks*************************
    @Override
    public void onConnected(Bundle bundle) {
        Log.d(TAG, "onConnected - isConnected ...............: " + mGoogleApiClient.isConnected());
        startLocationUpdates();
    }

    //*******************GoogleApiClient.ConnectionCallbacks*************************
    @Override
    public void onConnectionSuspended(int i) {

    }

    //*****************GoogleApiClient.ConnectionCallbacks***************************
    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Log.d(TAG, "Connection failed: " + connectionResult.toString());
    }

    //*****************LocationListener***************************
    // @Override
    public void onLocationChanged(Location location) {
        Log.d(TAG, "Firing onLocationChanged..............................................");
        mCurrentLocation = location;

        LatLng current = new LatLng(location.getLatitude(), location.getLongitude());
        if(mPrev == null)  //when the first update comes, we have no previous points,hence this
        {
            mPrev=current;
            mStartLocation = location;
            addMarker();
        }
        else {
            CameraUpdate update = CameraUpdateFactory.newLatLngZoom(current, 17);
            googleMap.animateCamera(update);

            PolylineOptions pOptions = new PolylineOptions()
                    .width(7)
                    .color(Color.BLUE)
                    .visible(true);// .geodesic(true)

            pOptions.add(mPrev);
            pOptions.add(current);
            googleMap.addPolyline(pOptions);

            mPrev = current;
            current = null;
        }
    }
    //********************************************
    protected void createLocationRequest() {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(INTERVAL);
        mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

//********************************************
    private boolean isGooglePlayServicesAvailable() {
        int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (ConnectionResult.SUCCESS == status) {
            Log.d(TAG, "isGooglePlayServicesAvailable ...............: SUCCESS"  );
            return true;
        } else {
            GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
            return false;
        }
    }

    //********************************************
    protected void startLocationUpdates() {

        //Get foreground location update
       /* PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, this);*/

        //Get background location update

        String proximitys = "ACTION";
        IntentFilter filter = new IntentFilter(proximitys);
        getApplicationContext().registerReceiver(new LocationReceiver() , filter);
        Intent intent = new Intent(proximitys);

        //  Intent intent = new Intent(this, LocationReceiver.class);
        PendingIntent locationIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, locationIntent);

    }
    //********************************************

    public void HandleLocationChanged(Location location) {
        Log.d(TAG, "Firing HandleLocationChanged..............................................");
       // Toast.makeText(getApplicationContext(), "HandleLocationChanged", Toast.LENGTH_LONG).show();

        if(location == null)
        {
            Toast.makeText(getApplicationContext(), "location is null", Toast.LENGTH_LONG).show();
            return;
        }
        mCurrentLocation = location;

        LatLng current = new LatLng(location.getLatitude(), location.getLongitude());
        if(mPrev == null)  //when the first update comes, we have no previous points,hence this
        {
            mPrev=current;
            mStartLocation = location;
            addMarker();
        }
        else {
            CameraUpdate update = CameraUpdateFactory.newLatLngZoom(current, 17);
            googleMap.animateCamera(update);

            PolylineOptions pOptions = new PolylineOptions()
                    .width(7)
                    .color(Color.BLUE)
                    .visible(true);// .geodesic(true)

            pOptions.add(mPrev);
            pOptions.add(current);
            googleMap.addPolyline(pOptions);

            mPrev = current;
            current = null;
        }
    }


//********************************************
    public String getAddress( )
    {
        Geocoder geocoder = new Geocoder(this);
        String addressLineTemp=null;
        List<Address> addresses;
        try {
            addresses = geocoder.getFromLocation(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude(), 1);
            if (addresses.size() > 0) {
                addressLineTemp = addresses.get(0).getAddressLine(0);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return addressLineTemp;
    }
//********************************************
    private void addMarker() {

        MarkerOptions options = new MarkerOptions();
        LatLng currentLatLng = new LatLng(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude());
        options.position(currentLatLng);
        Marker mapMarker = googleMap.addMarker(options);
        mapMarker.setTitle(getAddress());
        Log.d(TAG, "Marker added.............................");
        googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng,
                13));
        Log.d(TAG, "Zoom done.............................");
    }

//********************************************
    protected void stopLocationUpdates() {
        LocationServices.FusedLocationApi.removeLocationUpdates(
                mGoogleApiClient, this);
        Log.d(TAG, "Location update stopped .......................");
    }


//********************************************

  public  class LocationReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent)
        {

            Log.d(TAG, "Firing LocationReceiver....onReceive..........................................");
            Location location = (Location) intent.getExtras().get(LocationServices.FusedLocationApi.KEY_LOCATION_CHANGED);
            HandleLocationChanged(location);
        }
    }
Isha
  • 13
  • 3
  • Aren't you using handler to get updated latitude and longitude? – Anshul Tyagi Aug 13 '15 at 04:43
  • No , I am not using handler as I am using broadcast receiver in case of requestlocationupdate with pending intent and OnlocationChanged callback with another version of requestlocationupdate with LocationListener. Let me know why I need Handler here ?? Also my query is about requestlocationupdate API behaviour – Isha Aug 13 '15 at 04:55
  • If you want to work it in background then start a Service and perform operation to get latitude and longitude. And for requestlocationupdate you must see http://stackoverflow.com/q/16898675/2404262 – Anshul Tyagi Aug 13 '15 at 05:07
  • You mean PHP webservice? – Anshul Tyagi Aug 13 '15 at 05:36
  • yes I can use service for background location update but If there is an api for the same I think I can use that. requestLocationUpdates (GoogleApiClient client, LocationRequest request, LocationListener listener)Requests location updates.This method is suited for the foreground use cases, For background use cases, the PendingIntent version of the method is recommended, see requestLocationUpdates(GoogleApiClient, LocationRequest, PendingIntent). – Isha Aug 13 '15 at 05:37
  • ofc, PHP service is also a good way to get updated lats and longs. Tell me exactly your problem. Are you getting intent null or what? – Anshul Tyagi Aug 13 '15 at 05:46
  • As per the defination in document requestLocationUpdates for foreground I should use with Locationlistener and for background i should use with pendingintent . But I have commented Locationlistener version using with pending intent and getting this callbacks in foreground as well here I am confused and many times I getting location as null.you can see in my code above. – Isha Aug 13 '15 at 05:53
  • You get null and your app get problem. Why don't you debug and check ?? And one more thing if you're performing some tasks after getting longs then check first like if((lat != null) && (long !=null)) then go ahead. – Anshul Tyagi Aug 13 '15 at 05:56

0 Answers0