Получение местоположения пользователя
Основы объединённого провайдера местоположения
«Получение местоположения пользователя» — бесплатный урок Android Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Android Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Android Academy содержит 4 уроков всего.
Где находится пользователь?
Большинство приложений, использующих данные о местоположении, начинаются с одного вопроса: где сейчас находится устройство? Android отвечает на него с помощью Fused Location Provider — компонента сервисов Google Play.
В этом уроке вы добавите зависимость, запросите однократное определение местоположения, подключите непрерывные обновления и отобразите результат в Compose.
Почему стоит использовать Fused Provider
У Android есть несколько источников местоположения: GPS, Wi-Fi и вышки сотовой связи. Fused Location Provider интеллектуально объединяет их, чтобы определить наилучшее местоположение с минимальным расходом заряда батареи.
Теперь почти никогда не нужно напрямую использовать LocationManager — объединённый клиент проще и эффективнее.
// build.gradle.kts (module)
dependencies {
implementation("com.google.android.gms:play-services-location:21.3.0")
}Объявление разрешения
Местоположение — конфиденциальный ресурс. Объявите разрешение в файле AndroidManifest.xml. Используйте ACCESS_FINE_LOCATION для точного определения или ACCESS_COARSE_LOCATION для приблизительного.
Объявление — лишь первый шаг: разрешение также нужно запросить во время работы приложения (это будет рассмотрено в следующем уроке).
<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />Создание объединённого клиента
Получите FusedLocationProviderClient из LocationServices. В Compose получите контекст с помощью LocalContext.current и сохраните клиент, чтобы он не создавался заново при каждой рекомпозиции.
import com.google.android.gms.location.LocationServices
@Composable
fun rememberFusedClient() = run {
val context = LocalContext.current
remember {
LocationServices.getFusedLocationProviderClient(context)
}
}Получение последнего известного местоположения
Быстрее всего получить ответ через lastLocation — самые свежие координаты, которые система уже сохранила в кэше. Он возвращает объект Task, поэтому добавьте обработчик успешного выполнения.
Результат может быть равен null, если недавно ни одно приложение не запрашивало местоположение, поэтому всегда проверяйте его на отсутствие значения.
@SuppressLint("MissingPermission")
fun fetchLastLocation(
client: FusedLocationProviderClient,
onResult: (Location?) -> Unit
) {
client.lastLocation
.addOnSuccessListener { location -> onResult(location) }
.addOnFailureListener { onResult(null) }
}Ожидание Task с помощью корутин
Цепочки обратных вызовов быстро становятся вложенными. Библиотека kotlinx-coroutines-play-services добавляет .await(), позволяя получать местоположение с помощью понятного приостанавливаемого кода.
import kotlinx.coroutines.tasks.await
@SuppressLint("MissingPermission")
suspend fun currentLastLocation(
client: FusedLocationProviderClient
): Location? {
return client.lastLocation.await()
}Запрос актуального местоположения
lastLocation может устареть. Чтобы получить актуальные координаты, вызовите getCurrentLocation с указанием приоритета. PRIORITY_HIGH_ACCURACY использует GPS, а PRIORITY_BALANCED_POWER_ACCURACY экономит заряд батареи.
import com.google.android.gms.location.Priority
import com.google.android.gms.location.CurrentLocationRequest
@SuppressLint("MissingPermission")
suspend fun freshLocation(
client: FusedLocationProviderClient
): Location? {
val request = CurrentLocationRequest.Builder()
.setPriority(Priority.PRIORITY_HIGH_ACCURACY)
.build()
return client.getCurrentLocation(request, null).await()
}Непрерывные обновления местоположения
Для навигации или отслеживания нужен поток обновлений. Создайте LocationRequest с интервалом, а затем зарегистрируйте LocationCallback с помощью requestLocationUpdates.
После завершения всегда прекращайте обновления, чтобы экономить заряд батареи.
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationResult
import com.google.android.gms.location.LocationCallback
val request = LocationRequest.Builder(
Priority.PRIORITY_HIGH_ACCURACY,
5000L // 5 seconds
).build()
val callback = object : LocationCallback() {
override fun onLocationResult(result: LocationResult) {
result.lastLocation?.let { /* use it */ }
}
}Обновления в виде Flow
Удобный подход оборачивает обновления в callbackFlow, поэтому потребители получают местоположения, а после завершения сбора данных обновления автоматически прекращаются через awaitClose.
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.callbackFlow
@SuppressLint("MissingPermission")
fun FusedLocationProviderClient.locationFlow(request: LocationRequest) = callbackFlow {
val cb = object : LocationCallback() {
override fun onLocationResult(result: LocationResult) {
result.lastLocation?.let { trySend(it) }
}
}
requestLocationUpdates(request, cb, Looper.getMainLooper())
awaitClose { removeLocationUpdates(cb) }
}Отображение местоположения в Compose
Получайте результат в компонуемом компоненте с помощью LaunchedEffect для однократного чтения или collectAsStateWithLifecycle для потока данных. Затем отобразите координаты.
@Composable
fun LocationLabel(client: FusedLocationProviderClient) {
var location by remember { mutableStateOf<Location?>(null) }
LaunchedEffect(Unit) {
location = freshLocation(client)
}
Text(
location?.let { "Lat ${it.latitude}, Lng ${it.longitude}" }
?: "Locating..."
)
}Компромисс между зарядом батареи и точностью
Местоположение — один из самых значительных источников расхода заряда в мобильных приложениях. Выбирайте минимальную точность, которая соответствует вашим требованиям, используйте максимально допустимый интервал обновления и всегда прекращайте обновления, когда экран закрывается.
Высокая точность и частые обновления быстро разряжают батарею — оставьте такой режим для активной навигации.
Быстрая проверка
Вам нужно прямо сейчас получить наиболее точное текущее местоположение с помощью приостанавливаемой функции. Какой подход лучше всего подходит?
Итоги
Теперь вы умеете получать местоположение устройства:
- Добавьте
play-services-locationи объявитеACCESS_FINE/COARSE_LOCATION. - Получите
FusedLocationProviderClientизLocationServices. - Используйте
lastLocationдля получения сохранённых координат, аgetCurrentLocation— для актуальных. - Получайте поток обновлений через
requestLocationUpdatesилиcallbackFlowи прекращайте их, чтобы экономить заряд батареи.
Далее: добавление маркеров и перемещение камеры к этим координатам.
Часто задаваемые вопросы
Урок «Получение местоположения пользователя» бесплатный?
Да — полный текст урока «Получение местоположения пользователя» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Android Academy, подпишись на CoddyKit PRO. Курс Android Academy содержит 4 уроков всего.
Чему я научусь в уроке «Получение местоположения пользователя»?
Основы объединённого провайдера местоположения Ты практикуешь Android Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Android Academy?
Предыдущий опыт не требуется. Android Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Получение местоположения пользователя»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Android Academy?
Да. Каждый урок Android Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Отображение карты
- Получение местоположения пользователя
- Маркеры и камера
- Правильная работа с разрешениями на доступ к местоположению