0Pricing
Android Academy · Урок

Получение местоположения пользователя

Основы объединённого провайдера местоположения

«Получение местоположения пользователя» — бесплатный урок 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 — локальная установка не требуется.

Все уроки этого курса

  1. Отображение карты
  2. Получение местоположения пользователя
  3. Маркеры и камера
  4. Правильная работа с разрешениями на доступ к местоположению
← Назад к Android Academy