Android получить информацию о местоположении с высоким разрешением при нажатии кнопки - PullRequest
0 голосов
/ 30 марта 2020

Я прочитал Android Документы, FusedLocationProvider против LocationManager; просматривал головокружительный набор вопросов и ответов вокруг этой темы c здесь в stackoverflow; и разработал много тестов с плохими результатами до сих пор. Почему это так чертовски запутанно и трудно для gr asp ???

У меня есть приложение, которому нужно получить объект Location с высоким разрешением (lat / long / alt / precision / et c) когда пользователь выполняет действие в приложении; скажем, они нажимают кнопку. Каков наилучший способ сделать это?

Я использую fusedLocationProviderClient.getLastLocation (). AddOnSuccessListener () и получаю дико смешанные результаты.

Я использовал locationManager.getLastKnownLocation (LocationManager.GPS_PRO) ). Если я запускаю приложение GPS Status на моем Galaxy S9, то это дает довольно замечательные результаты. Но если это не работает, то результаты бесполезны.

Что мне здесь не хватает? Всем нравится указывать на этот сайт Do c или тот пример сайта, который в основном бесполезен и на самом деле не отвечает на этот конкретный c вопрос. Я потратил впустую часы, проливая те сайты, которые просто не отвечают на этот вопрос. Пожалуйста, подведите итог общему алгоритму, который следует использовать здесь, и звонкам. Это все, что мне нужно.

Я хочу иметь возможность ходить по своему двору (10 метров здесь и там) и нажать кнопку, и приложение покажет широту / долготу / точность / высоту / расстояние от последнего места и пусть это будет правильно каждый раз с определенным уровнем точности. Что мне нужно сделать? Мне нужна высокая разрешающая способность, но возможность уведомлять пользователя о точности меньше, чем, скажем, 100 футов, и все равно получать максимально возможную точность, даже если она имеет ошибку 400 футов.

Ответы [ 2 ]

1 голос
/ 30 марта 2020

Вам не хватает работы GPS-приемников.

Когда нет приложения, использующего точное местоположение, все смартфоны отключают приемник GPS для экономии заряда батареи.

Даже если вы выбрали службы определения местоположения чтобы быть включенным (в настройках), вы заметите, что в панели уведомлений значок для использования GPS присутствует, только когда приложение активно, например, Google Maps или тестовое приложение GPS.

После включения приемника ( потому что это требуется некоторым приложениям), для «исправления» требуется некоторое время - доступно точное измерение местоположения.

Сколько времени потребуется, чтобы получить исправление, зависит от нескольких факторов, включая условия окружающей среды и тип вашего телефона. время и расстояние с момента последнего точного исправления и т. д. c.

Это может занять от нескольких секунд до нескольких минут.

Итак, что вы должны сделать, это подписаться на местоположение, как только когда ваше приложение открыто, и просите получать его как можно чаще.

Затем, включите кнопку только тогда, когда у вас будет хорошая точность, и когда кнопка нажата, покажите последний результат.

Вы, вероятно, должны также отобразить какой-нибудь счетчик или сообщение пользователю, ожидая точного исправления, чтобы пользователь знал, что ваше приложение не застряло.

Редактировать : под «подпиской» я имею в виду зарегистрировать необходимый обратный вызов, чтобы ваше приложение получало местоположение из системы, когда оно будет готово.

Как это сделать, зависит от того, какой API вы используете выберите.

В документации Google нет ошибок. Если вы решите использовать объединенное местоположение, вам нужно будет сделать следующее:

  • Создать объект запроса местоположения и установить приоритет для PRIORITY_HIGH_ACCURACY, а также setInterval и setFastestInterval для 1000 (1 секунда), чтобы получить лучшую точность.

  • Получить FusedLocationProviderClient объект из LocationServices

  • Используйте клиент для регистрации обратный вызов в ваше приложение

Здесь приведены примеры кодов: https://developer.android.com/training/location/request-updates

В функции обратного вызова в вашем приложении вы можете проверить точность и если это достаточно для вас, активируйте кнопку и сохраните местоположение, чтобы вы могли отобразить его пользователю, когда он нажмет кнопку.

0 голосов
/ 31 марта 2020

Хорошо, похоже, это работает. Этот общий поток кажется ответом.

Допущения: вы запрашиваете "android .permission.ACCESS_FINE_LOCATION" или Course in manifest.

Просто пример кода в функции onCreate () MainActivity для целей тестирования.

  • проверьте, есть ли у нас разрешение ACCESS_FINE_LOCATION; если нет, запрос.
  • get FusedLocationProviderClient
  • получить начальное местоположение из getLastLocation (); в целях сравнения и начала дорожки
  • определите locationCallback (), который будет вызван fusedLocationProvider; все, что нас интересует, это получить последний в стеке и сохранить его в классе Field.
  • определить LocationRequest с интервалом в 5 секунд и PRIORITY_HIGH_ACCURACY
  • проверить, разрешает ли пользовательское устройство это ; не уверен, что делать с этим, кроме как уведомлять пользователя, если это не разрешено.
  • теперь requestLocationUpdates с использованием LocationCallback, определенного выше.
  • , когда пользователь выполняет действие, требующее текущего широты / долготы (например, нажмите кнопку) , получить поле класса, заполненное объектом Location в последнем LocationCallback ().

Я очень открыт для обратной связи по этому шаблону. Надеюсь, что это помогает другим (так как есть множество вопросов по этому поводу). И хотел бы услышать о любых проблемах с этим дизайном или проблемах, с которыми я могу столкнуться.

    if (Build.VERSION.SDK_INT >= 23) {
        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_ASK_PERMISSIONS);
        } else {
            // getFusedLocationProviderClient
            fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
            // getStartLocation
            fusedLocationProviderClient.getLastLocation().addOnSuccessListener(this, new OnSuccessListener<Location>() {
                @Override
                public void onSuccess(Location location) {
                    if (location != null) {
                        StartLocation.set(location);
                    }
                }
            }).addOnFailureListener(this, new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
                }
            });

            // Define LocationCallback
            locationCallback = new LocationCallback() {
                @Override
                public void onLocationResult(LocationResult locationResult) {
                    if (locationResult != null) {
                        LastLocation = locationResult.getLastLocation();
                    }
                }
            };

            // Now lets request location updates - that is how this must happen
            // https://developer.android.com/training/location/change-location-settings
            LocationRequest locationRequest = LocationRequest.create();
            locationRequest.setInterval(5000);
            locationRequest.setFastestInterval(1000);
            locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

            // Attempt to see if requested settings are compatible with user device.
            LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
            builder.addLocationRequest(locationRequest);

            // Check to see if location settings are satisfied by user's device settings?
            SettingsClient client = LocationServices.getSettingsClient(this);
            Task<LocationSettingsResponse> locationTask = client.checkLocationSettings(builder.build())
                    .addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
                        @Override
                        public void onSuccess(LocationSettingsResponse locationSettingsResponse) {

                        }
                    }).addOnFailureListener(this, new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            if (e instanceof ResolvableApiException) {
                                // Location settings are not satisfied, but this can be fixed
                                // by showing the user a dialog.
                            }
                            Toast.makeText(MainActivity.this, "Location Settings Are Not " +
                                    "Correct On This Device", Toast.LENGTH_LONG).show();
                        }
                    });

            // Request location updates
            fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper());
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...