Я следил за официальной документацией от здесь, чтобы отобразить диалоговое окно местоположения для пользователя, поскольку наше приложение не работает без местоположения. Проблема в том, что даже когда я нажимаю кнопку ОК в диалоговом окне, иногда вызывается onFailure прослушивателя задач, что более важно, даже когда вызывается onSuccess (LocationSettingsResponse locationSettingsResponse), я не могу сразу получить данные о местоположении, обходной путь, который я сделал, - создать отдельный поток для получения деталей в цикле. Мне нужно знать более простой способ сделать это.
Это заняло у меня более двух дней, и я до сих пор не могу понять, что не так в моем коде.
FusedLocationProviderClient client;
TextView textView;
boolean started = false;
double lat = 0;
protected static final int REQUEST_CHECK_SETTINGS = 0x1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.text);
client = LocationServices.getFusedLocationProviderClient(this);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Log.e(tag, "no perm");
ActivityCompat.requestPermissions(this, new String[]{ACCESS_FINE_LOCATION}, 1);
} else
work();
}
void work() {
if (!isLocationEnabled()) createLocationRequest();
else locationDetails();
}
int t = 0;
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.e(tag, "activity result");
work();
}
void locationDetails() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
client.getLastLocation()
.addOnSuccessListener(this, new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
if (location != null) {
if (lat!=0)return;
lat = location.getLatitude();
textView.setText("location: lat" + lat + " lng" + location.getLongitude());
Log.e(tag, "happy");
} else {
repeatedRequests();
Log.e(tag, "null location");
}
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{ACCESS_FINE_LOCATION}, 1);
} else work();
}
void createLocationRequest() {
final LocationRequest mLocationRequest = LocationRequest.create();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
final SettingsClient settingsclient = LocationServices.getSettingsClient(this);
Task<LocationSettingsResponse> task = settingsclient.checkLocationSettings(builder.build());
task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
repeatedRequests();
Log.e(tag, "success");
}
});
task.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
if (e instanceof ResolvableApiException) {
Log.e(tag, "failure" + e.getLocalizedMessage());
// repeatedRequests();
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
ResolvableApiException resolvable = (ResolvableApiException) e;
resolvable.startResolutionForResult(MainActivity.this,
REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException sendEx) {
Log.e(tag, "erorr " + sendEx.getLocalizedMessage());
// Ignore the error.
}
}
}
});
}
void repeatedRequests() {
if (!started) {
started = true;
Log.e(tag, "Thread started");
new Thread(new Runnable() {
@Override
public void run() {
while (lat == 0) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
t++;
if (t > 50) break;
Log.e(tag, "repeat");
runOnUiThread(new Runnable() {
@Override
public void run() {
locationDetails();
}
});
}
}
}).start();
}
}
boolean isLocationEnabled() {
int locationMode = 0;
try {
locationMode = Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCATION_MODE);
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
return false;
}
return locationMode != Settings.Secure.LOCATION_MODE_OFF;
}
Привет, когда вы пытаетесь сделать ResolvableApiException resolvable = (ResolvableApiException) e; resolvable.startResolutionForResult(MainActivity.this, 2); , вы получаете ответ onActivityResult. При нажатии на системный диалог будет там. покажите свой onActivityResult, также на какой версии устройства / ОС вы его проверяете?
Проверял на Samsung S8, который работает на API 26.
Я получил результат, но все же мне нужно было вызвать цикл, чтобы получить запросы местоположения. Я не могу точно знать, когда будет гарантировано обнаружение этого места.
)))))) не принимайте близко к сердцу. Это БАГ на samsung s8 и обратите внимание. Проверял на 3-х устройствах samsung s8. есть одна вещь, которую вы можете сделать - когда вы поймаете onActivityResult requestCode == REQUEST_CHECK_SETTINGS && resultCode == RESULT_CANCELED, вы можете показать диалог второй раз, и если пользователь нажмет «ОК», вы получите местоположение в своем LocationRequest.
попробуйте проверить настройки s8, когда вы нажмете ОК в диалоговом окне, он запустит службу определения местоположения, но с низкими настройками использования батареи, если вы измените настройки на высокий, это также даст местоположение.




Попробуй поставить mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
только для вашего samsung, в моем случае это работает, но имейте в виду, что locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) в этом случае вернет false.
getLastLocation()
работает при наличии хотя бы одного подписчика на сервис гугл ..
Вам необходимо подписаться, и если вам не нужно постоянно обновлять координаты, вы можете сразу отписаться ...
val client = LocationServices.getFusedLocationProviderClient(this)
client.requestLocationUpdates(locationRequest, object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult?) {
val location = locationResult?.lastLocation
//job.invoke()
client.removeLocationUpdates(this)
}
}, Looper.myLooper())
OnFailureListener () запускается, даже если не нажимается никакая кнопка.