Как отслеживать текущее местоположение в Android с новыми компонентами архитектуры?

У меня есть проект, в котором я успешно реализовал функцию отслеживания местоположения, и она отлично работает. Я отслеживаю текущее местоположение пользователей с помощью провайдера плавного определения местоположения каждые 30 секунд (отслеживание начинается с запуска MainActivity).

Теперь я планирую обновить этот проект с помощью недавно представленных компонентов архитектуры Android. Но я не знаю, как реализовать отслеживание местоположения с помощью модели представления. Где правильно начать отслеживание местоположения, в классе MainActivity или Application? Должен ли я использовать ViewModel или AndroidViewModel? Как этого добиться.




Ответы (2)


Правильным способом было бы иметь TrackingRepository, где вы выполняете все вычисления в фоновом потоке местоположения устройства. Создайте MutableLiveData, где вы назначите местоположение. Затем обновите его значение, используя postValue() или setValue(). Напишите публичный геттер для этого MutableLiveData. Этот репозиторий будет вашим API местоположения.

Затем ваш ViewModel должен вызвать метод вашего репозитория и присвоить его результат переменной LiveData файла ViewModel. Затем в вашем фрагменте/активности наблюдайте за liveData вашего ViewModel. Как и в Руководстве по архитектуре приложений.

Не забудьте использовать внедрение зависимостей, которое действительно помогает с новой архитектурой.

person Damia Fuentes    schedule 06.12.2017
comment
Я не понимаю, где запрашивать разрешения на местоположение и откуда запускать службу, не могли бы вы предоставить пример кода? - person ; 10.12.2017
comment
Вам нужно запросить разрешения на местоположение в пользовательском интерфейсе, но получить доступ к местоположению устройства через репозиторий. Насчет того, откуда запустить службу, толком не знаю. Обратитесь к этому сообщению, хотя на него еще нет ответа (stackoverflow.com/questions/47265685/) - person Damia Fuentes; 11.12.2017
comment
Есть ли рабочий пример этой установки? Было бы здорово увидеть рабочий пример... В любом случае я планирую провести тест. - person Codeversed; 03.07.2018
comment
Но FusedLocationProviderClient требует создания экземпляра Context. Как мы можем предоставить ему Context? - person Abdul Mateen; 29.08.2019
comment
Используйте ApplicationContext вместо контекста действия - person Kitesurfer; 04.02.2020

После нескольких часов попыток, наконец, я смог найти решение.

Сначала создайте переменную внутри LocationRepository.

val currentLocation = MutableLiveData<Location>()

Внутри LocationCallBack (onLocationResult)

currentLocation.postValue(locationResult.lastLocation)

После этого снова в классе ViewModel

val currentLocation = MutableLiveData<Location>()

и

fun currentLocation(): MutableLiveData<Location>
{
    currentLocation = myLocationProvider.currentLocation
    return currentLocation
}

по крайней мере, вы наблюдаете MutableLiveDate ViewModel в своем действии/фрагменте

myLocationProvider.currentLocation.observe(this, Observer { currentLocation ->
            currentLocation?.let {
                //Your code here
            }
})

EDIT Вы должны запустить LocationCallback с помощью suspendCoroutine, GlobalScope и UiDispatcher.

person inspire_coding    schedule 15.06.2019
comment
Рекомендуется инкапсулировать MutableLiveData, чтобы представление не могло установить новое значение. var _currentLocation = MutableLiveData<Location>() это личное для использования в ViewModel val currentLocation = LiveData<Location>() get()= _currentLocation это тот, который будет наблюдаться в представлении - person Eliza Camber; 27.06.2019
comment
@ElizaCamber да, правда. Я изменил свой комментарий, спасибо - person inspire_coding; 29.06.2019