Android: невозможно создать диалоговое окно запроса местоположения и получить местоположение при обратном вызове

Я следил за официальной документацией от здесь, чтобы отобразить диалоговое окно местоположения для пользователя, поскольку наше приложение не работает без местоположения. Проблема в том, что даже когда я нажимаю кнопку ОК в диалоговом окне, иногда вызывается 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;
}

OnFailureListener () запускается, даже если не нажимается никакая кнопка.

Harsha 04.11.2018 07:53

Привет, когда вы пытаетесь сделать ResolvableApiException resolvable = (ResolvableApiException) e; resolvable.startResolutionForResult(MainActivity.this, 2); , вы получаете ответ onActivityResult. При нажатии на системный диалог будет там. покажите свой onActivityResult, также на какой версии устройства / ОС вы его проверяете?

Vadim Eksler 04.11.2018 09:52

Проверял на Samsung S8, который работает на API 26.

Harsha 04.11.2018 10:21

Я получил результат, но все же мне нужно было вызвать цикл, чтобы получить запросы местоположения. Я не могу точно знать, когда будет гарантировано обнаружение этого места.

Harsha 04.11.2018 10:27

)))))) не принимайте близко к сердцу. Это БАГ на samsung s8 и обратите внимание. Проверял на 3-х устройствах samsung s8. есть одна вещь, которую вы можете сделать - когда вы поймаете onActivityResult requestCode == REQUEST_CHECK_SETTINGS && resultCode == RESULT_CANCELED, вы можете показать диалог второй раз, и если пользователь нажмет «ОК», вы получите местоположение в своем LocationRequest.

Vadim Eksler 04.11.2018 10:27

попробуйте проверить настройки s8, когда вы нажмете ОК в диалоговом окне, он запустит службу определения местоположения, но с низкими настройками использования батареи, если вы измените настройки на высокий, это также даст местоположение.

Vadim Eksler 04.11.2018 10:28
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
6
248
2

Ответы 2

Попробуй поставить 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())

Другие вопросы по теме