Search code examples
androidgpslocation

Android can't get my GPS location - stuck on waiting for GPS


I know it is a very often discussed area, but in my app I can't get the user's position anymore. It worked well with my current code, but I just turned off and then back on my GPS on my device, and from that while the app can't get my position. This was also reported from some users, that the app can't get their position anymore.

The code is long, I will try to put here only the important parts:

Defining params:

private final static int ALL_PERMISSIONS_RESULT = 101;
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10;
    private static final long MIN_TIME_BW_UPDATES = 60000; //1.0 mins

    LocationManager locationManager;Location loc;
    ArrayList<String> permissions = new ArrayList<>();
    ArrayList permissionsToRequest;
    ArrayList<String> permissionsRejected = new ArrayList<>();
    boolean isGPS = false; boolean isNetwork = false; boolean canGetLocation = true;

In onCreate() :

locationManager = (LocationManager) this.getSystemService(Service.LOCATION_SERVICE);
    assert locationManager != null;
    isGPS = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    isNetwork = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

permissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
permissions.add(Manifest.permission.ACCESS_COARSE_LOCATION);
permissionsToRequest = findUnAskedPermissions(permissions);

if (!isGPS && !isNetwork) {
    if (dialog != null) {
    dialog.dismiss();
    dialog = null;
}
    showSettingsAlert();

    if (dialog != null) {
        dialog.dismiss();
        dialog = null;
    }
    getLastLocation();
} else {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (permissionsToRequest.size() > 0) {
            requestPermissions((String[]) permissionsToRequest.toArray(new String[0]),
                    ALL_PERMISSIONS_RESULT);
            canGetLocation = false;
        }
    }
    getLocation();
}

Other parts of code:

@Override
    public void onLocationChanged(Location location) {updateUI(location);}

    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {}

    @Override
    public void onProviderEnabled(String s) {
        getLocation();
    }

    @Override
    public void onProviderDisabled(String s) {
        if (locationManager != null) {
            locationManager.removeUpdates(this);
        }
    }

getLocation method:

 private void getLocation() {

        try {
            if (canGetLocation) {

                if (isGPS) {
                    Log.e("GPS", String.valueOf(isGPS));
                    locationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);

                    if (locationManager != null) {
                        loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        if (loc != null) {updateUI(loc);}
                    }
                } else if (isNetwork) {  Log.e("isNetwork", String.valueOf(isNetwork));
                    // from Network Provider
                    locationManager.requestLocationUpdates(
                            LocationManager.NETWORK_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);

                    if (locationManager != null) {
                        loc = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        if (loc != null) {updateUI(loc);}
                    }
                } else { 
                    loc.setLatitude(0);
                    loc.setLongitude(0);
                    updateUI(loc);
                }
            } else {Toast.makeText(this, R.string.nolocation,Toast.LENGTH_LONG).show();}
        } catch (SecurityException e) {
            e.printStackTrace();}
    }

  private void getLocation() {

        try {
            if (canGetLocation) {

                if (isGPS) {
                    Log.e("GPS", String.valueOf(locationManager));
                    locationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);

                    if (locationManager != null) {
                        loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        if (loc != null) {updateUI(loc);}
                    }
                } else if (isNetwork) {  Log.e("isNetwork", String.valueOf(isNetwork));
                    // from Network Provider
                    locationManager.requestLocationUpdates(
                            LocationManager.NETWORK_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);

                    if (locationManager != null) {
                        loc = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        if (loc != null) {updateUI(loc);}
                    }
                } else {  Log.e("aaaaaa", "sssss");
                    loc.setLatitude(0);
                    loc.setLongitude(0);
                    updateUI(loc);
                }
            } else {Toast.makeText(this, R.string.nolocation,Toast.LENGTH_LONG).show();}
        } catch (SecurityException e) {
            e.printStackTrace();}
    }

    private void getLastLocation() {
        try {
            Criteria criteria = new Criteria();
            String provider = locationManager.getBestProvider(criteria, false);

            if(provider==null) {   if (dialog != null) {
                dialog.dismiss();
                dialog = null;
            } showSettingsAlert();   if (dialog != null) {
                dialog.dismiss();
                dialog = null;
            }}
            else {
                Location location = locationManager.getLastKnownLocation(provider);
                if (location != null) {updateUI(location);}
            }
        } catch (SecurityException e) {
            e.printStackTrace();
        }
    }

    private ArrayList findUnAskedPermissions(ArrayList<String> wanted) {
        ArrayList<String> result = new ArrayList<>();

        for (String perm : wanted) {
            if (!hasPermission(perm)) {
                result.add(perm);
            }
        }
        return result;
    }

    private boolean hasPermission(String permission) {
        if (canAskPermission()) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                return (this.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED);
            }
        }
        return true;
    }

    private boolean canAskPermission() {
        return true;
    }

 @TargetApi(Build.VERSION_CODES.M)
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

        if (requestCode == ALL_PERMISSIONS_RESULT) {
            for (Object perms : permissionsToRequest) {
                if (!hasPermission((String) perms)) {
                    permissionsRejected.add((String) perms);
                }
            }

            if (permissionsRejected.size() > 0) {

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    if (shouldShowRequestPermissionRationale(permissionsRejected.get(0))) {

                        showMessageOKCancel(getString(R.string.denied),
                                new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        requestPermissions(permissionsRejected.toArray(
                                                new String[0]), ALL_PERMISSIONS_RESULT);
                                    }
                                });
                    }
                }
            } else {

                canGetLocation = true;
                getLocation();
            }
        }
    }

    public void showSettingsAlert() {  if (dialog != null) {
        dialog.dismiss();
        dialog = null; }
        final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this, R.style.Theme_AppCompat_Dialog_Alert);
        alertDialog.setTitle(R.string.nogps);
        alertDialog.setMessage(R.string.askgps);
        alertDialog.setPositiveButton(R.string.ano, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) { dialog.dismiss();
                Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                isFromSetting = true;
                startActivity(intent);
            }
        });

        alertDialog.setNegativeButton(R.string.nie, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        });

     alertDialog.show();
    }

    private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
        new AlertDialog.Builder(this, R.style.Theme_AppCompat_Dialog_Alert)
                .setMessage(message)
                .setPositiveButton("OK", okListener)
                .setNegativeButton(R.string.cancel, null)
                .create()
                .show();  }

    public void updateUI(Location loc) {
        double Act1=loc.getLatitude();
        double Act2=loc.getLongitude();
        adapter.clear();adapter.notifyDataSetChanged();

        TextView listTitle = findViewById(R.id.booklist_title1);
        ListView lv = findViewById(R.id.listViewx);

        if (Act1 > 0.0) { listTitle.setVisibility(View.GONE);lv.setVisibility(View.VISIBLE);
            Object[] obj = new Object[3];obj[0] = Act1;obj[1] = Act2;
            new GetContacts(Okoli.this).execute(obj);
        } else {
            listTitle.setVisibility(View.VISIBLE);listTitle.setText(R.string.waitGPS);lv.setVisibility(View.GONE);
        }
    }

When I debug it, if (isGPS) {Log.e("GPS", String.valueOf(isGPS));... then I see isGPS is true, but I waited already 30 minutes, the location icon on my device is there, but nothing happens, seems it can't get my location anymore.

Of course I got through permissions etc., and at least I know, the getLocation method is started, because I put the Log there.

Then I also found out, that in this:

 if (locationManager != null) {
                    loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                    Log.e("loc", String.valueOf(loc));
                    if (loc != null) {updateUI(loc);}
                }

The loc is null, so the updateUI is not called.

After I reinstalled the app, suddenly the position worked, but again if I turn off and on my location, I can wait a hour and nothing happens.


Solution

  • So now I switched the order, so firstly I am calling isNetwork and only after that isGPS and this way it is working relatively good. The problem seems to be in GPS then, where the getLastKnownLocation gives null and takes very long time until requestLocationUpdates comes up.

    However not sure, how accurate is the position from Network provider comparing to GPS