Android 无法获取我的 GPS 位置 - 一直在等待 GPS

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

我知道这是一个经常被讨论的领域,但在我的应用程序中我无法再获取用户的位置。它适用于我当前的代码,但我只是关闭然后重新打开我设备上的 GPS,从那时起应用程序无法获取我的位置。一些用户也反映,该应用无法再获取他们的位置。

代码很长,我会尽量把重要的部分放在这里:

定义参数:

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;

在 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();
}

其他部分代码:

@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);
        }
    }

当我调试它时,if (isGPS) {Log.e("GPS", String.valueOf(isGPS));...然后我看到 isGPS 是真的,但我等了已经 30 分钟了,我设备上的位置图标还在,但是没有任何反应,似乎无法获取我的位置了。

当然是通过权限等搞定的,至少我知道,getLocation方法是启动的,因为我把Log放在那里了

然后我也发现,在这个:

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

loc为空,所以没有调用updateUI

在我重新安装应用程序后,位置突然起作用了,但是如果我关闭并打开我的位置,我可以等待一个小时,但什么也没有发生。

所以现在我调换了顺序,所以首先我调用 isNetwork,然后才调用 isGPS,这样它工作得比较好。问题似乎出在 GPS 中,其中 getLastKnownLocation 给出 null 并且需要很长时间才能出现 requestLocationUpdates。

但是不确定,与 GPS 相比,网络提供商的位置有多准确