1

I am using Android Query to detect user's location.

For some reason, when I try to retrieve my latitude and longitude, it shows my previous location which is a couple hundred meters away, as if it was cached.

What could be the issue here?

public class LocationHelper {
    private Context mContext;
    private double latitude;
    private double longitude;

    public LocationHelper(Context mContext) {
        this.mContext = mContext;
        location_ajax();
    }

    public double getLatitude() {
        return latitude;
    }

    public double getLongitude() {
        return longitude;
    }

    private void location_ajax() {
        // Get the location
        LocationAjaxCallback cb = new LocationAjaxCallback();
        cb.weakHandler(this, "locationCb");
        cb.async(mContext);
    }

    public void locationCb(String url, Location loc, AjaxStatus status) {
        if (loc != null) {
            //Toast.makeText(mContext, loc.toString(), Toast.LENGTH_LONG).show();
            this.latitude = loc.getLatitude();
            this.longitude = loc.getLongitude();            
        } else {
            Toast.makeText(mContext, mContext.getString(R.string.msg_could_not_retrieve_location), Toast.LENGTH_LONG).show();
        }
    }   
}

Logcat:

03-19 23:03:17.146: W/AQuery(29954): reporting:java.lang.reflect.InvocationTargetException
03-19 23:03:17.146: W/AQuery(29954):    at java.lang.reflect.Method.invokeNative(Native Method)
03-19 23:03:17.146: W/AQuery(29954):    at java.lang.reflect.Method.invoke(Method.java:511)
03-19 23:03:17.146: W/AQuery(29954):    at com.androidquery.util.AQUtility.invokeMethod(AQUtility.java:206)
03-19 23:03:17.146: W/AQuery(29954):    at com.androidquery.util.AQUtility.invokeHandler(AQUtility.java:183)
03-19 23:03:17.146: W/AQuery(29954):    at com.androidquery.callback.AbstractAjaxCallback.callback(AbstractAjaxCallback.java:577)
03-19 23:03:17.146: W/AQuery(29954):    at com.androidquery.callback.LocationAjaxCallback.failure(LocationAjaxCallback.java:192)
03-19 23:03:17.146: W/AQuery(29954):    at com.androidquery.callback.LocationAjaxCallback.access$3(LocationAjaxCallback.java:183)
03-19 23:03:17.146: W/AQuery(29954):    at com.androidquery.callback.LocationAjaxCallback$Listener.run(LocationAjaxCallback.java:308)
03-19 23:03:17.146: W/AQuery(29954):    at java.util.Timer$TimerImpl.run(Timer.java:284)
03-19 23:03:17.146: W/AQuery(29954): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
03-19 23:03:17.146: W/AQuery(29954):    at android.os.Handler.<init>(Handler.java:121)
03-19 23:03:17.146: W/AQuery(29954):    at android.widget.Toast$TN.<init>(Toast.java:361)
03-19 23:03:17.146: W/AQuery(29954):    at android.widget.Toast.<init>(Toast.java:97)
03-19 23:03:17.146: W/AQuery(29954):    at android.widget.Toast.makeText(Toast.java:254)
03-19 23:03:17.146: W/AQuery(29954):    at uk.ac.gla.project.helpers.LocationHelper.locationCb(LocationHelper.java:46)
03-19 23:03:17.146: W/AQuery(29954):    ... 9 more
03-19 23:03:20.001: W/AQuery(29954): reporting:java.lang.reflect.InvocationTargetException
03-19 23:03:20.001: W/AQuery(29954):    at java.lang.reflect.Method.invokeNative(Native Method)
03-19 23:03:20.001: W/AQuery(29954):    at java.lang.reflect.Method.invoke(Method.java:511)
03-19 23:03:20.001: W/AQuery(29954):    at com.androidquery.util.AQUtility.invokeMethod(AQUtility.java:206)
03-19 23:03:20.001: W/AQuery(29954):    at com.androidquery.util.AQUtility.invokeHandler(AQUtility.java:183)
03-19 23:03:20.001: W/AQuery(29954):    at com.androidquery.callback.AbstractAjaxCallback.callback(AbstractAjaxCallback.java:577)
03-19 23:03:20.001: W/AQuery(29954):    at com.androidquery.callback.LocationAjaxCallback.failure(LocationAjaxCallback.java:192)
03-19 23:03:20.001: W/AQuery(29954):    at com.androidquery.callback.LocationAjaxCallback.access$3(LocationAjaxCallback.java:183)
03-19 23:03:20.001: W/AQuery(29954):    at com.androidquery.callback.LocationAjaxCallback$Listener.run(LocationAjaxCallback.java:308)
03-19 23:03:20.001: W/AQuery(29954):    at java.util.Timer$TimerImpl.run(Timer.java:284)
03-19 23:03:20.001: W/AQuery(29954): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
03-19 23:03:20.001: W/AQuery(29954):    at android.os.Handler.<init>(Handler.java:121)
03-19 23:03:20.001: W/AQuery(29954):    at android.widget.Toast$TN.<init>(Toast.java:361)
03-19 23:03:20.001: W/AQuery(29954):    at android.widget.Toast.<init>(Toast.java:97)
03-19 23:03:20.001: W/AQuery(29954):    at android.widget.Toast.makeText(Toast.java:254)
03-19 23:03:20.001: W/AQuery(29954):    at uk.ac.gla.project.helpers.LocationHelper.locationCb(LocationHelper.java:46)
03-19 23:03:20.001: W/AQuery(29954):    ... 9 more
03-19 23:03:20.671: W/AQuery(29954): reporting:java.lang.reflect.InvocationTargetException
03-19 23:03:20.671: W/AQuery(29954):    at java.lang.reflect.Method.invokeNative(Native Method)
03-19 23:03:20.671: W/AQuery(29954):    at java.lang.reflect.Method.invoke(Method.java:511)
03-19 23:03:20.671: W/AQuery(29954):    at com.androidquery.util.AQUtility.invokeMethod(AQUtility.java:206)
03-19 23:03:20.671: W/AQuery(29954):    at com.androidquery.util.AQUtility.invokeHandler(AQUtility.java:183)
03-19 23:03:20.671: W/AQuery(29954):    at com.androidquery.callback.AbstractAjaxCallback.callback(AbstractAjaxCallback.java:577)
03-19 23:03:20.671: W/AQuery(29954):    at com.androidquery.callback.LocationAjaxCallback.failure(LocationAjaxCallback.java:192)
03-19 23:03:20.671: W/AQuery(29954):    at com.androidquery.callback.LocationAjaxCallback.access$3(LocationAjaxCallback.java:183)
03-19 23:03:20.671: W/AQuery(29954):    at com.androidquery.callback.LocationAjaxCallback$Listener.run(LocationAjaxCallback.java:308)
03-19 23:03:20.671: W/AQuery(29954):    at java.util.Timer$TimerImpl.run(Timer.java:284)
03-19 23:03:20.671: W/AQuery(29954): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
03-19 23:03:20.671: W/AQuery(29954):    at android.os.Handler.<init>(Handler.java:121)
03-19 23:03:20.671: W/AQuery(29954):    at android.widget.Toast$TN.<init>(Toast.java:361)
03-19 23:03:20.671: W/AQuery(29954):    at android.widget.Toast.<init>(Toast.java:97)
03-19 23:03:20.671: W/AQuery(29954):    at android.widget.Toast.makeText(Toast.java:254)
03-19 23:03:20.671: W/AQuery(29954):    at uk.ac.gla.project.helpers.LocationHelper.locationCb(LocationHelper.java:46)
03-19 23:03:20.671: W/AQuery(29954):    ... 9 more
03-19 23:03:20.906: W/AQuery(29954): reporting:java.lang.reflect.InvocationTargetException
03-19 23:03:20.906: W/AQuery(29954):    at java.lang.reflect.Method.invokeNative(Native Method)
03-19 23:03:20.906: W/AQuery(29954):    at java.lang.reflect.Method.invoke(Method.java:511)
03-19 23:03:20.906: W/AQuery(29954):    at com.androidquery.util.AQUtility.invokeMethod(AQUtility.java:206)
03-19 23:03:20.906: W/AQuery(29954):    at com.androidquery.util.AQUtility.invokeHandler(AQUtility.java:183)
03-19 23:03:20.906: W/AQuery(29954):    at com.androidquery.callback.AbstractAjaxCallback.callback(AbstractAjaxCallback.java:577)
03-19 23:03:20.906: W/AQuery(29954):    at com.androidquery.callback.LocationAjaxCallback.failure(LocationAjaxCallback.java:192)
03-19 23:03:20.906: W/AQuery(29954):    at com.androidquery.callback.LocationAjaxCallback.access$3(LocationAjaxCallback.java:183)
03-19 23:03:20.906: W/AQuery(29954):    at com.androidquery.callback.LocationAjaxCallback$Listener.run(LocationAjaxCallback.java:308)
03-19 23:03:20.906: W/AQuery(29954):    at java.util.Timer$TimerImpl.run(Timer.java:284)
03-19 23:03:20.906: W/AQuery(29954): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
03-19 23:03:20.906: W/AQuery(29954):    at android.os.Handler.<init>(Handler.java:121)
03-19 23:03:20.906: W/AQuery(29954):    at android.widget.Toast$TN.<init>(Toast.java:361)
03-19 23:03:20.906: W/AQuery(29954):    at android.widget.Toast.<init>(Toast.java:97)
03-19 23:03:20.906: W/AQuery(29954):    at android.widget.Toast.makeText(Toast.java:254)
03-19 23:03:20.906: W/AQuery(29954):    at uk.ac.gla.project.helpers.LocationHelper.locationCb(LocationHelper.java:46)
03-19 23:03:20.906: W/AQuery(29954):    ... 9 more
03-19 23:03:21.061: W/AQuery(29954): reporting:java.lang.reflect.InvocationTargetException
03-19 23:03:21.061: W/AQuery(29954):    at java.lang.reflect.Method.invokeNative(Native Method)
03-19 23:03:21.061: W/AQuery(29954):    at java.lang.reflect.Method.invoke(Method.java:511)
03-19 23:03:21.061: W/AQuery(29954):    at com.androidquery.util.AQUtility.invokeMethod(AQUtility.java:206)
03-19 23:03:21.061: W/AQuery(29954):    at com.androidquery.util.AQUtility.invokeHandler(AQUtility.java:183)
03-19 23:03:21.061: W/AQuery(29954):    at com.androidquery.callback.AbstractAjaxCallback.callback(AbstractAjaxCallback.java:577)
03-19 23:03:21.061: W/AQuery(29954):    at com.androidquery.callback.LocationAjaxCallback.failure(LocationAjaxCallback.java:192)
03-19 23:03:21.061: W/AQuery(29954):    at com.androidquery.callback.LocationAjaxCallback.access$3(LocationAjaxCallback.java:183)
03-19 23:03:21.061: W/AQuery(29954):    at com.androidquery.callback.LocationAjaxCallback$Listener.run(LocationAjaxCallback.java:308)
03-19 23:03:21.061: W/AQuery(29954):    at java.util.Timer$TimerImpl.run(Timer.java:284)
03-19 23:03:21.061: W/AQuery(29954): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
03-19 23:03:21.061: W/AQuery(29954):    at android.os.Handler.<init>(Handler.java:121)
03-19 23:03:21.061: W/AQuery(29954):    at android.widget.Toast$TN.<init>(Toast.java:361)
03-19 23:03:21.061: W/AQuery(29954):    at android.widget.Toast.<init>(Toast.java:97)
03-19 23:03:21.061: W/AQuery(29954):    at android.widget.Toast.makeText(Toast.java:254)
03-19 23:03:21.061: W/AQuery(29954):    at uk.ac.gla.project.helpers.LocationHelper.locationCb(LocationHelper.java:46)
03-19 23:03:21.061: W/AQuery(29954):    ... 9 more
03-19 23:03:21.486: W/AQuery(29954): reporting:java.lang.reflect.InvocationTargetException
03-19 23:03:21.486: W/AQuery(29954):    at java.lang.reflect.Method.invokeNative(Native Method)
03-19 23:03:21.486: W/AQuery(29954):    at java.lang.reflect.Method.invoke(Method.java:511)
03-19 23:03:21.486: W/AQuery(29954):    at com.androidquery.util.AQUtility.invokeMethod(AQUtility.java:206)
03-19 23:03:21.486: W/AQuery(29954):    at com.androidquery.util.AQUtility.invokeHandler(AQUtility.java:183)
03-19 23:03:21.486: W/AQuery(29954):    at com.androidquery.callback.AbstractAjaxCallback.callback(AbstractAjaxCallback.java:577)
03-19 23:03:21.486: W/AQuery(29954):    at com.androidquery.callback.LocationAjaxCallback.failure(LocationAjaxCallback.java:192)
03-19 23:03:21.486: W/AQuery(29954):    at com.androidquery.callback.LocationAjaxCallback.access$3(LocationAjaxCallback.java:183)
03-19 23:03:21.486: W/AQuery(29954):    at com.androidquery.callback.LocationAjaxCallback$Listener.run(LocationAjaxCallback.java:308)
03-19 23:03:21.486: W/AQuery(29954):    at java.util.Timer$TimerImpl.run(Timer.java:284)
03-19 23:03:21.486: W/AQuery(29954): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
03-19 23:03:21.486: W/AQuery(29954):    at android.os.Handler.<init>(Handler.java:121)
03-19 23:03:21.486: W/AQuery(29954):    at android.widget.Toast$TN.<init>(Toast.java:361)
03-19 23:03:21.486: W/AQuery(29954):    at android.widget.Toast.<init>(Toast.java:97)
03-19 23:03:21.486: W/AQuery(29954):    at android.widget.Toast.makeText(Toast.java:254)
03-19 23:03:21.486: W/AQuery(29954):    at uk.ac.gla.project.helpers.LocationHelper.locationCb(LocationHelper.java:46)

Are there any reliable alternatives?

chuckfinley
  • 2,577
  • 10
  • 32
  • 42
  • which AQuery version are you using? I mean Location call is in beta mode or it is in stable mode in that library? – Solution Mar 25 '14 at 12:45

7 Answers7

3

Why so complicated ? Use Google Play Services. They are for free and uses complex Location Strategies

Gaskoin
  • 2,469
  • 13
  • 22
1

According to your logCat you have a RuntimeException when your LocationAjaxCallback$Listener fires and calls this method.

locationCb(String url, Location loc, AjaxStatus status)

Since that fails to update your variables

private double latitude;
private double longitude;

You will be returned whatever was previously stored in them. (Your old location)

You need to fix whatever is causing this error

at com.androidquery.callback.LocationAjaxCallback$Listener.run(LocationAjaxCallback.java:308)
at java.util.Timer$TimerImpl.run(Timer.java:284)
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

After that your update method will fire correctly and update the lat and long

1

why not classical one:

locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

// Define a listener that responds to location updates

locationListener = new LocationListener() {

        public void onLocationChanged(Location location) {

                // Called when a new location is found by the network location provider.

                longitude = String.valueOf(location.getLongitude());

                latitude = String.valueOf(location.getLatitude());

                Log.d(TAG, "changed Loc : " + longitude + ":" + latitude);

        }

        public void onStatusChanged(String provider, int status, Bundle extras) {

        }

        public void onProviderEnabled(String provider) {

        }

        public void onProviderDisabled(String provider) {

        }

};

// getting GPS status

isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

// check if GPS enabled

if (isGPSEnabled) {

        Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

        if (location != null) {

                longitude = String.valueOf(location.getLongitude());

                latitude = String.valueOf(location.getLatitude());

                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);

        } else {

                location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

                if (location != null) {

                        longitude = String.valueOf(location.getLongitude());

                        latitude = String.valueOf(location.getLatitude());

                        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);

                } else {

                        longitude = "0.00";

                        latitude = "0.00";

                }

        }

}

taken from here http://androidadvance.com/android_snippets.php

OWADVL
  • 10,704
  • 7
  • 55
  • 67
1

add cb.uiCallback(true); before cb.async(mContext);

Why

For what I can tell you create instance of LocationHelper from a background Thread that doesn't have a Looper so you can't use it to get async callbacks.

Basically if you want to call cb.async(mContext); without calling cb.uiCallback(true); you have to do it from the UI Thread*

* or any other thread that has a Looper

gabcas
  • 162
  • 1
  • 4
  • 6
1
Try this one.

package com.example.tracker;

import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;

import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

import android.content.Context;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v4.app.FragmentActivity;
import android.widget.Toast;

public class MainActivity extends FragmentActivity implements LocationListener {
    private GoogleMap map;
    private static final LatLng ROMA = new LatLng(42.093230818037,
            11.7971813678741);
    private LocationManager locationManager;
    private String provider;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        map = ((SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map)).getMap();

        LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
        boolean enabledGPS = service
                .isProviderEnabled(LocationManager.GPS_PROVIDER);
        boolean enabledWiFi = service
                .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

        // Check if enabled and if not send user to the GSP settings
        // Better solution would be to display a dialog and suggesting to
        // go to the settings
        if (!enabledGPS) {
            Toast.makeText(this, "GPS signal not found", Toast.LENGTH_LONG)
                    .show();
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(intent);
        }

        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        // Define the criteria how to select the locatioin provider -> use
        // default
        Criteria criteria = new Criteria();
        provider = locationManager.getBestProvider(criteria, false);
        Location location = locationManager.getLastKnownLocation(provider);

        // Initialize the location fields
        if (location != null) {
            Toast.makeText(this, "Selected Provider " + provider,
                    Toast.LENGTH_SHORT).show();
            onLocationChanged(location);
        } else {

            // do something
        }

    }

    /* Request updates at startup */
    @Override
    protected void onResume() {
        super.onResume();
        locationManager.requestLocationUpdates(provider, 400, 1, this);
    }

    /* Remove the locationlistener updates when Activity is paused */
    @Override
    protected void onPause() {
        super.onPause();
        locationManager.removeUpdates(this);
    }

    @Override
    public void onLocationChanged(Location location) {
        double lat = location.getLatitude();
        double lng = location.getLongitude();
        Toast.makeText(this, "Location " + lat + "," + lng, Toast.LENGTH_LONG)
                .show();
        LatLng coordinate = new LatLng(lat, lng);
        Toast.makeText(this,
                "Location " + coordinate.latitude + "," + coordinate.longitude,
                Toast.LENGTH_LONG).show();
        Marker startPerc = map.addMarker(new MarkerOptions()
                .position(coordinate)
                .title("Start")
                .snippet("Inizio del percorso")
                .icon(BitmapDescriptorFactory
                        .fromResource(R.drawable.ic_launcher)));
    }

    @Override
    public void onProviderDisabled(String provider) {
        Toast.makeText(this, "Enabled new provider " + provider,
                Toast.LENGTH_SHORT).show();

    }

    @Override
    public void onProviderEnabled(String provider) {
        Toast.makeText(this, "Disabled provider " + provider,
                Toast.LENGTH_SHORT).show();

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub

    }

}
Sethu
  • 430
  • 2
  • 13
1
@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Intent intent=new Intent("android.location.GPS_ENABLED_CHANGE");
        intent.putExtra("enabled", true);
        sendBroadcast(intent);  
        LocationManager mlocManager = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
        LocationListener mlocListener = new MyLocationListener();
         mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
    }

  /* Class My Location Listener */
        public class MyLocationListener implements LocationListener
        {

          @Override
          public void onLocationChanged(Location loc)
          {
    try{
           lat=loc.getLatitude();
            longs=loc.getLongitude();
            getAddress(lat, longs);
            String Text = "My current location is: " +
            "Latitud = " + loc.getLatitude() +
            "Longitud = " + loc.getLongitude();
    }catch (NullPointerException e) {

    }
           // Toast.makeText( getActivity().getApplicationContext(), Text, Toast.LENGTH_SHORT).show();
          }

          @Override
          public void onProviderDisabled(String provider)
          {
            Toast.makeText(getApplicationContext(), "Gps Disabled", Toast.LENGTH_SHORT ).show();
          }

          @Override
          public void onProviderEnabled(String provider)
          {
            Toast.makeText(getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show();
          }

          @Override
          public void onStatusChanged(String provider, int status, Bundle extras)
          {

          }
        }
0

The next error indicates that you have started a handler which is going to receive message asynch. To do this you need to be on main thread or you could start a looper:

Can't create handler inside thread that has not called Looper.prepare()

I think the point is that you are creating an AJAX handler which seems to expects some async messages from the GeoLoc API.

You could try to instantiate this handler in an Activity or try to start a Looper:

Looper.prepare();
LocationAjaxCallback cb = new LocationAjaxCallback();
Looper.loop();

If you start a looper be careful so it needs to be shutdown when you finish. Think that a looper is like a listener running in its current thread (so it doesn't run in the calling thread) and it has an internal queue where new message are stored. Anytime a new message arrives the queue is updated and the looper thread process this event (when it finish with the current event takes the next one or blocks until a new message arrives).

For this reason you should start the looper (creating a new thread which will process the messages) and shutdown when finish (releasing that thread + message queue).

Carlos Verdes
  • 3,037
  • 22
  • 20