我正在编写一个应用程序,其中特定模块需要用户的位置。现在我正在使用 Google 的 Fused Location API,可以在这里找到。
当用户设置中的位置被关闭时,问题就出现了。我写了一个提示更改设置的代码。我收到更改后的设置onActivityResult
。但显然,融合的位置提供者需要一些时间来获取位置。我使用该handler.postDelayed
方法在几秒钟后获取位置(这只是猜测)并且代码似乎工作正常。
所以我想问一下,有没有更好的方法来检索位置或减少延迟?
我的代码如下:
public class MainActivity extends AppCompatActivity {
String addressText = "";
int LOCATION_REQUEST_CODE = 1;
int REQUEST_CHECK_SETTINGS = 2;
TextView latitude, longitude;
LocationRequest mLocationRequest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
latitude = (TextView) findViewById(R.id.latitude);
longitude = (TextView) findViewById(R.id.longitude);
createLocationRequest();
}
void getLocation() {
FusedLocationProviderClient mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions( this,
new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE);
}
else {
mFusedLocationClient.getLastLocation()
.addOnSuccessListener(this, new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
if (location != null) {
latitude.setText("Latitude : " + location.getLatitude());
longitude.setText("Latitude : " + location.getLongitude());
new GetAddress().execute(location);
}
}
});
}
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
SettingsClient client = LocationServices.getSettingsClient(this);
Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());
task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
getLocation();
}
});
task.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
if (e instanceof ResolvableApiException) {
try {
ResolvableApiException resolvable = (ResolvableApiException) e;
resolvable.startResolutionForResult(MainActivity.this,
REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException ignored) {
}
}
}
});
}
class GetAddress extends AsyncTask<Location, Void, Void> {
@Override
protected Void doInBackground(Location... locations) {
Location location = locations[0];
List<Address> addresses = null;
Geocoder geocoder = new Geocoder(MainActivity.this, Locale.getDefault());
try
{
addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
}
catch (IOException ioException)
{
Toast.makeText(MainActivity.this, "Network Weak, can't fetch address", Toast.LENGTH_SHORT).show();
}
if (addresses == null || addresses.size() == 0) {
Toast.makeText(MainActivity.this, "Address not found", Toast.LENGTH_SHORT).show();
}
else {
Address address = addresses.get(0);
for(int i = 0; i <= address.getMaxAddressLineIndex(); i++)
addressText = addressText + System.getProperty("line.separator") + address.getAddressLine(i);
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
Toast.makeText(MainActivity.this, addressText, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == LOCATION_REQUEST_CODE && grantResults[0] == PackageManager.PERMISSION_GRANTED)
getLocation();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CHECK_SETTINGS && resultCode == RESULT_OK)
{
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
getLocation();
}
}, 5000);
}
}
}