我正在使用AsyncTask来获取使用最佳提供商条件的用户位置。它适用于模拟器,但不适用于真实设备。
我使用Criteria()
选择最佳提供商,使用getLastKnownLocation
来获取该位置。
这是我的代码:
class GetPositionTask extends AsyncTask<Void, Void, Location> implements LocationListener
{
ProgressDialog progressDialog;
private Location location;
private LocationManager lm;
private String mProviderName;
protected void onPreExecute()
{
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (checkPermission()) {
Criteria criteria = new Criteria(); //Using criteria to get the best provider.
mProviderName = lm.getBestProvider(criteria, true);
lm.requestLocationUpdates(mProviderName, 1000, 0, this);
}
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setTitle("Please Wait..");
progressDialog.setMessage("Processing...!!");
progressDialog.setCancelable(false);
progressDialog.show();
}
protected Location doInBackground(Void... params)
{
// Try to use the last known position
if (checkPermission()) {
Location location = lm.getLastKnownLocation(mProviderName);
return location;
}
return null;
}
protected void onPostExecute(Location location)
{
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
if (location != null) {
Toast.makeText(getApplicationContext(), "GPS locked! Processing your address!", Toast.LENGTH_SHORT).show();
} else {
new AlertDialog.Builder(MainActivity.this)
.setTitle("Error")
.setMessage("Server Error! Please Try again!!") //This error message is thrown in the real device, not on emulator.
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
})
.setCancelable(false)
.show();
}
if (checkPermission()) {
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lm.removeUpdates(this);
if (location != null) {
new GeocodeAsyncTask().execute(location.getLatitude(), location.getLongitude()); //This is another AsyncTask to get the address from the location.
}
}
}
@Override
public void onLocationChanged(Location location) {}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
}
private boolean checkPermission() {
int result = ContextCompat.checkSelfPermission(getApplicationContext(), ACCESS_FINE_LOCATION);
return result == PackageManager.PERMISSION_GRANTED;
}
private void requestPermission() {
ActivityCompat.requestPermissions(this, new String[]{ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_CODE);
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
if (grantResults.length > 0) {
boolean locationAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
if (locationAccepted)
checkLocationStatus();
else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (shouldShowRequestPermissionRationale(ACCESS_FINE_LOCATION)) {
showMessageOKCancel("You need to allow access to the Locations!",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{ACCESS_FINE_LOCATION},
PERMISSION_REQUEST_CODE);
}
}
});
return;
}
}
}
}
break;
}
}
private void checkLocationStatus() {
if (checkPermission()) {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
new GetPositionTask().execute();
}
else{
startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
} else {
Toast.makeText(this, "Needs to access GPS. Please give access to it!", Toast.LENGTH_SHORT).show();
requestPermission();
}
}
}
它有什么错误吗?任何提示都会有所帮助。
有没有办法在不使用最后一个已知位置的情况下获得当前位置?
编辑: 只是旁注:在真实设备上,GPS符号可见一秒钟然后隐藏,然后出现错误。