Rick
Rick

Reputation: 4013

Latitude and longitude not retrieved

When the gps is disabled you can enable it with Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); but when I go back to the activity I don't get any result. I have to restart the activity, in other words I have to go back to the previous activity and then reopen it. Could you PLEASE help me?

This is my doInBackground method:

@Override
protected String doInBackground(String... uri){

    final GPSTracker gpsTracker = new GPSTracker(myactivity);
    final String[] latitudine = {null};
    final String[] longitudine = {null};

    if(gpsTracker.canGetLocation())
    {
        latitudine[0] = String.valueOf(gpsTracker.latitude);
        longitudine[0] = String.valueOf(gpsTracker.longitude);
    }
    else
    {
        myactivity.runOnUiThread(new Runnable() {
            public void run() {

                final Dialog dialog = new Dialog(myactivity);
                dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
                dialog.setContentView(R.layout.position_alert_dialog);

                Button dialogButton_deny = (Button) dialog.findViewById(R.id.deny);
                Button dialogButton_allow = (Button) dialog.findViewById(R.id.allow);

                dialogButton_allow.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        myactivity.startActivity(intent);
                        dialog.dismiss();

                        if(gpsTracker.canGetLocation())
                        {
                            latitudine[0] = String.valueOf(gpsTracker.latitude);
                            longitudine[0] = String.valueOf(gpsTracker.longitude);

                        }else{

                            latitudine[0] = "34.0522300";
                            longitudine[0] = "-118.2436800";

                        }

                    }
                });

                dialogButton_deny.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        dialog.dismiss();
                    }
                });

                dialog.show();

            }
        });
    }

GPSTracker:

public class GPSTracker extends Service implements LocationListener {
    private final Context mContext;

    boolean isGPSEnabled = false;

    boolean isNetworkEnabled = false;

    boolean canGetLocation = false;

    Location location;
    double latitude;
    double longitude;

    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; //10 meters

    private static final long MIN_TIME_BW_UPDATES = 1000 * 60; // 1 minute

    protected LocationManager locationManager;

    public GPSTracker(Context context) {
        this.mContext = context;
        getLocation();
    }

    public Location getLocation() {
        try {
            locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);

            isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

            isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

            if (!isGPSEnabled && !isNetworkEnabled) {
            } else {
                this.canGetLocation = true;
                if (isNetworkEnabled) {
                    locationManager.requestLocationUpdates(
                            LocationManager.NETWORK_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this, Looper.getMainLooper());

                    Log.d("Network", "Network");

                    if (locationManager != null) {
                        location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        updateGPSCoordinates();
                    }
                }
                if (isGPSEnabled) {
                    if (location == null) {
                        locationManager.requestLocationUpdates(
                                LocationManager.GPS_PROVIDER,
                                MIN_TIME_BW_UPDATES,
                                MIN_DISTANCE_CHANGE_FOR_UPDATES, this);

                        Log.d("GPS Enabled", "GPS Enabled");

                        if (locationManager != null) {
                            location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                            updateGPSCoordinates();
                        }
                    }
                }
            }
        } catch (Exception e) {
            //e.printStackTrace();
            Log.e("Error : Location", "Impossible to connect to LocationManager", e);
        }

        return location;
    }

    public void updateGPSCoordinates() {
        if (location != null) {
            latitude = location.getLatitude();
            longitude = location.getLongitude();
        }
    }

    public void stopUsingGPS() {
        if (locationManager != null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    // TODO: Consider calling
                    //    public void requestPermissions(@NonNull String[] permissions, int requestCode)
                    // here to request the missing permissions, and then overriding
                    //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                    //                                          int[] grantResults)
                    // to handle the case where the user grants the permission. See the documentation
                    // for Activity#requestPermissions for more details.
                    return;
                }
            }
            locationManager.removeUpdates(GPSTracker.this);
        }
    }

    public double getLatitude()
    {
        if (location != null)
        {
            latitude = location.getLatitude();
        }

        return latitude;
    }

    public double getLongitude()
    {
        if (location != null)
        {
            longitude = location.getLongitude();
        }

        return longitude;
    }

    public boolean canGetLocation()
    {
        return this.canGetLocation;
    }

    public List<Address> getGeocoderAddress(Context context)
    {
        if (location != null)
        {
            Geocoder geocoder = new Geocoder(context, Locale.ENGLISH);
            try
            {
                return geocoder.getFromLocation(latitude, longitude, 1);
            }
            catch (IOException e)
            {
                //e.printStackTrace();
                Log.e("Error : Geocoder", "Impossible to connect to Geocoder", e);
            }
        }

        return null;
    }

    public String getAddressLine(Context context)
    {
        List<Address> addresses = getGeocoderAddress(context);
        if (addresses != null && addresses.size() > 0)
        {
            Address address = addresses.get(0);

            return address.getAddressLine(0);
        }
        else
        {
            return null;
        }
    }

    public String getLocality(Context context)
    {
        List<Address> addresses = getGeocoderAddress(context);
        if (addresses != null && addresses.size() > 0)
        {
            Address address = addresses.get(0);

            return address.getLocality();
        }
        else
        {
            return null;
        }
    }

    public String getSubLocality(Context context)
    {
        List<Address> addresses = getGeocoderAddress(context);
        if (addresses != null && addresses.size() > 0)
        {
            Address address = addresses.get(0);

            return address.getSubLocality();
        }
        else
        {
            return null;
        }
    }

    public String getPostalCode(Context context)
    {
        List<Address> addresses = getGeocoderAddress(context);
        if (addresses != null && addresses.size() > 0)
        {
            Address address = addresses.get(0);

            return address.getPostalCode();
        }
        else
        {
            return null;
        }
    }

    public String getCountryName(Context context)
    {
        List<Address> addresses = getGeocoderAddress(context);
        if (addresses != null && addresses.size() > 0)
        {
            Address address = addresses.get(0);

            return address.getCountryName();
        }
        else
        {
            return null;
        }
    }

    @Override
    public void onLocationChanged(Location location)
    {
    }

    @Override
    public void onProviderDisabled(String provider)
    {
    }

    @Override
    public void onProviderEnabled(String provider)
    {
    }    

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

    @Override
    public IBinder onBind(Intent intent)
    {
        return null;
    }
}

EDIT

public class GPSTracker extends Service implements LocationListener, GoogleApiClient.ConnectionCallbacks {
private final Context mContext;

boolean isPlayServicesEnabled = false;

boolean isGPSEnabled = false;

boolean isNetworkEnabled = false;

boolean canGetLocation = false;

Location location;
double latitude;
double longitude;

private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; //10 meters

private static final long MIN_TIME_BW_UPDATES = 1000 * 60; // 1 minute

protected LocationManager locationManager;

public GPSTracker(Context context) {
    this.mContext = context;
}

public Location getLocation() {
    try {
        locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);

        isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

        isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

        if (!isGPSEnabled && !isNetworkEnabled) {
        } else {
            this.canGetLocation = true;
            if (isNetworkEnabled) {
                locationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER,
                        MIN_TIME_BW_UPDATES,
                        MIN_DISTANCE_CHANGE_FOR_UPDATES, this, Looper.getMainLooper());

                Log.d("Network", "Network");

                if (locationManager != null) {
                    location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                    updateGPSCoordinates();
                }
            }
            if (isGPSEnabled) {
                if (location == null) {
                    locationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);

                    Log.d("GPS Enabled", "GPS Enabled");

                    if (locationManager != null) {
                        location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        updateGPSCoordinates();
                    }
                }
            }
        }
    } catch (Exception e) {
        //e.printStackTrace();
        Log.e("Error : Location", "Impossible to connect to LocationManager", e);
    }

    return location;
}

public void updateGPSCoordinates() {
    if (location != null) {
        latitude = location.getLatitude();
        longitude = location.getLongitude();
    }
}

public void stopUsingGPS() {
    if (locationManager != null) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                // TODO: Consider calling
                //    public void requestPermissions(@NonNull String[] permissions, int requestCode)
                // here to request the missing permissions, and then overriding
                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                //                                          int[] grantResults)
                // to handle the case where the user grants the permission. See the documentation
                // for Activity#requestPermissions for more details.
                return;
            }
        }
        locationManager.removeUpdates(GPSTracker.this);
    }
}

public double getLatitude() {
    if (location != null) {
        latitude = location.getLatitude();
    }

    return latitude;
}

public double getLongitude() {
    if (location != null) {
        longitude = location.getLongitude();
    }

    return longitude;
}

public boolean canGetLocation() {
    return this.canGetLocation;
}

public List<Address> getGeocoderAddress(Context context) {
    if (location != null) {
        Geocoder geocoder = new Geocoder(context, Locale.ENGLISH);
        try {
            return geocoder.getFromLocation(latitude, longitude, 1);
        } catch (IOException e) {
            //e.printStackTrace();
            Log.e("Error : Geocoder", "Impossible to connect to Geocoder", e);
        }
    }

    return null;
}

public String getAddressLine(Context context) {
    List<Address> addresses = getGeocoderAddress(context);
    if (addresses != null && addresses.size() > 0) {
        Address address = addresses.get(0);

        return address.getAddressLine(0);
    } else {
        return null;
    }
}

public String getLocality(Context context) {
    List<Address> addresses = getGeocoderAddress(context);
    if (addresses != null && addresses.size() > 0) {
        Address address = addresses.get(0);

        return address.getLocality();
    } else {
        return null;
    }
}

public String getSubLocality(Context context) {
    List<Address> addresses = getGeocoderAddress(context);
    if (addresses != null && addresses.size() > 0) {
        Address address = addresses.get(0);

        return address.getSubLocality();
    } else {
        return null;
    }
}

public String getPostalCode(Context context) {
    List<Address> addresses = getGeocoderAddress(context);
    if (addresses != null && addresses.size() > 0) {
        Address address = addresses.get(0);

        return address.getPostalCode();
    } else {
        return null;
    }
}

public String getCountryName(Context context) {
    List<Address> addresses = getGeocoderAddress(context);
    if (addresses != null && addresses.size() > 0) {
        Address address = addresses.get(0);

        return address.getCountryName();
    } else {
        return null;
    }
}

@Override
public void onLocationChanged(Location location) {

    this.location = location;

}

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

}

@Override
public void onProviderDisabled(String provider) {
}

@Override
public void onProviderEnabled(String provider) {
}

@Override
public void onConnected(Bundle connectionHint) {
    isPlayServicesEnabled = true;
    getLocation();
}

@Override
public void onConnectionSuspended(int cause) {
    isPlayServicesEnabled = false;
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

}

This is where I call the AsyncTask:

public class Weather extends AppCompatActivity{

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

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_layout);
    setSupportActionBar(toolbar);

    toolbar.setPadding(0, getStatusBarHeight(), 0, 0);

    assert getSupportActionBar() != null;

    this.getSupportActionBar().setDisplayHomeAsUpEnabled(true);    
    this.getSupportActionBar().setDisplayShowTitleEnabled(false);  

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        getWindow().getDecorView().setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
    }

    new WeatherApi(this).execute();  // the doInBackground method above is from this class

}

public int getStatusBarHeight() {
    int result = 0;

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = getResources().getDimensionPixelSize(resourceId);
        }
    }
    return result;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            finish();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

}

Upvotes: 2

Views: 610

Answers (3)

Rajesh Jadav
Rajesh Jadav

Reputation: 12861

I assume you are calling doInBackground() method in onCreate() method of your activity So if GPS is not enabled then your application is redirected to GPS settings screen.

So when you come back from GPS settings screen after enabling it your Activity resume so it will not call doInBackground() again that's why you don't get any result.

Simplest solution is to define onResume() method for your Activity and call doInBackground() in onResume() rather than onCreate() so when your Activity resume so it will call doInBackground() again you get updated result.

You should update your Whether Activity like this:

public class Weather extends AppCompatActivity{

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

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_layout);
    setSupportActionBar(toolbar);

    toolbar.setPadding(0, getStatusBarHeight(), 0, 0);

    assert getSupportActionBar() != null;

    this.getSupportActionBar().setDisplayHomeAsUpEnabled(true);    
    this.getSupportActionBar().setDisplayShowTitleEnabled(false);  

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        getWindow().getDecorView().setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
    }  
}

@Override
public void onResume(){
    super.onResume();
   new WeatherApi(this).execute();  // the doInBackground method above is from this class

}

public int getStatusBarHeight() {
    int result = 0;

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = getResources().getDimensionPixelSize(resourceId);
        }
    }
    return result;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            finish();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}
}

I hope it helps you.

Upvotes: 1

Piyush
Piyush

Reputation: 18923

As far as i have faced this issue , but i have solved it my own way.

In your GPSTracker class make one method.

public void onActivityResult(int requestCode, int resultcode, Intent data) {

}

Now start activity with startActivityForResult instead of startActivity,

Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivityForResult(intent, 0);

Now in your activity when you back in onActivityResult method

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    gpsTracker.onActivityResult(requestCode, resultCode, data);// This line is more important 

    if (requestCode == 0) {

        handler.sendEmptyMessage(0);

    }
}

Now the handler is

android.os.Handler handler = new android.os.Handler(new android.os.Handler.Callback() {
    @Override
    public boolean handleMessage(Message message) {
        try {
              Location location = gpsTracker.getLocation();
              latitude = location.getLatitude();
              longitude = location.getLongitude();
        } catch (Exception e) {
            Log.v("Error:", "Location is null");
        }
        return false;
    }
});

Using this you can immidiate location as i got. May be it will helpful. In my case it is working fine.

Upvotes: 2

Shane Duffy
Shane Duffy

Reputation: 1147

Using getLastKnownLocation causes issues sometimes because it can take time for it to actually find a lastKnownLocation.

Try setting your location with the onLocationChanged function, this should effectively remove this problem.

You can do this as follows:

@Override
public void onLocationChanged(Location location)
{
    this.location = location;
}

Now, every time your location is changed (or found for the first time) the onLocationChanged event will get called and will set your GPSTracker location variable to the location passed in the calling parameter!

Edit:

Try changing your GPSTracker class to the following:

public class GPSTracker extends Service implements LocationListener, ConnectionCallbacks {
private final Context mContext;

boolean isPlayServicesEnabled = false;

boolean isGPSEnabled = false;

boolean isNetworkEnabled = false;

boolean canGetLocation = false;

Location location;
double latitude;
double longitude;

private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; //10 meters

private static final long MIN_TIME_BW_UPDATES = 1000 * 60; // 1 minute

protected LocationManager locationManager;

public GPSTracker(Context context) {
    this.mContext = context;
}

public Location getLocation() {
    try {
        locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);

        isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

        isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

        if (!isGPSEnabled && !isNetworkEnabled) {
        } else {
            this.canGetLocation = true;
            if (isNetworkEnabled) {
                locationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER,
                        MIN_TIME_BW_UPDATES,
                        MIN_DISTANCE_CHANGE_FOR_UPDATES, this, Looper.getMainLooper());

                Log.d("Network", "Network");

                if (locationManager != null) {
                    location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                    updateGPSCoordinates();
                }
            }
            if (isGPSEnabled) {
                if (location == null) {
                    locationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);

                    Log.d("GPS Enabled", "GPS Enabled");

                    if (locationManager != null) {
                        location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        updateGPSCoordinates();
                    }
                }
            }
        }
    } catch (Exception e) {
        //e.printStackTrace();
        Log.e("Error : Location", "Impossible to connect to LocationManager", e);
    }

    return location;
}

public void updateGPSCoordinates() {
    if (location != null) {
        latitude = location.getLatitude();
        longitude = location.getLongitude();
    }
}

public void stopUsingGPS() {
    if (locationManager != null) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                // TODO: Consider calling
                //    public void requestPermissions(@NonNull String[] permissions, int requestCode)
                // here to request the missing permissions, and then overriding
                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                //                                          int[] grantResults)
                // to handle the case where the user grants the permission. See the documentation
                // for Activity#requestPermissions for more details.
                return;
            }
        }
        locationManager.removeUpdates(GPSTracker.this);
    }
}

public double getLatitude()
{
    if (location != null)
    {
        latitude = location.getLatitude();
    }

    return latitude;
}

public double getLongitude()
{
    if (location != null)
    {
        longitude = location.getLongitude();
    }

    return longitude;
}

public boolean canGetLocation()
{
    return this.canGetLocation;
}

public List<Address> getGeocoderAddress(Context context)
{
    if (location != null)
    {
        Geocoder geocoder = new Geocoder(context, Locale.ENGLISH);
        try
        {
            return geocoder.getFromLocation(latitude, longitude, 1);
        }
        catch (IOException e)
        {
            //e.printStackTrace();
            Log.e("Error : Geocoder", "Impossible to connect to Geocoder", e);
        }
    }

    return null;
}

public String getAddressLine(Context context)
{
    List<Address> addresses = getGeocoderAddress(context);
    if (addresses != null && addresses.size() > 0)
    {
        Address address = addresses.get(0);

        return address.getAddressLine(0);
    }
    else
    {
        return null;
    }
}

public String getLocality(Context context)
{
    List<Address> addresses = getGeocoderAddress(context);
    if (addresses != null && addresses.size() > 0)
    {
        Address address = addresses.get(0);

        return address.getLocality();
    }
    else
    {
        return null;
    }
}

public String getSubLocality(Context context)
{
    List<Address> addresses = getGeocoderAddress(context);
    if (addresses != null && addresses.size() > 0)
    {
        Address address = addresses.get(0);

        return address.getSubLocality();
    }
    else
    {
        return null;
    }
}

public String getPostalCode(Context context)
{
    List<Address> addresses = getGeocoderAddress(context);
    if (addresses != null && addresses.size() > 0)
    {
        Address address = addresses.get(0);

        return address.getPostalCode();
    }
    else
    {
        return null;
    }
}

public String getCountryName(Context context)
{
    List<Address> addresses = getGeocoderAddress(context);
    if (addresses != null && addresses.size() > 0)
    {
        Address address = addresses.get(0);

        return address.getCountryName();
    }
    else
    {
        return null;
    }
}

@Override
public void onLocationChanged(Location location)
{
}

@Override
public void onProviderDisabled(String provider)
{
}

@Override
public void onProviderEnabled(String provider)
{
}

@Override
public void onConnected(Bundle connectionHint) {
    isPlayServicesEnabled = true;
    getLocation();
}

@Override
public void onConnectionSuspended(int cause) {
    isPlayServicesEnabled = false;
}

I believe what may be causing your issue is the fact that you don't check if Google Play Services has connected or not. In the above code, I implemented ConnectionCallbacks and included the onConnected and onConnectionSuspended overrides. Now, getLocation() will only be called once Play Services have been connected. Let me know if this works out.

Upvotes: 1

Related Questions