我知道这是一个经常讨论的领域,但是在我的应用程序中,我无法再获得用户的位置。它与我当前的代码配合得很好,但是我只是先关闭然后再在设备上重新启动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);
}
}
[当我调试它时,如果(isGPS){Log.e(“ GPS”,String.valueOf(isGPS)); ...然后我看到isGPS是真实的,但是我已经等了30分钟,我的位置图标设备在那里,但什么也没发生,似乎无法再获取我的位置。
当然,我获得了权限等,并且至少我知道,getLocation
方法已启动,因为我将日志放在这里。
然后我也发现了这个:
if (locationManager != null) {
loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Log.e("loc", String.valueOf(loc));
if (loc != null) {updateUI(loc);}
}
该位置为null,因此未调用updateUI。
重新安装应用程序后,突然该位置起作用了,但是再次关闭电源后,我可以等待一个小时,什么也没发生。
所以现在我切换了顺序,所以首先我要呼叫isNetwork,然后才呼叫isGPS,这样它就可以正常工作了。然后,问题似乎出在GPS中,其中getLastKnownLocation为null。
但是不确定,来自网络提供商的位置有多准确。