Ответ
Да, приходилось. Например, писал модуль для работы с геолокацией, который включал:
- Получение координат через FusedLocationProvider
- Обработку пермишенов (включая runtime-запросы)
- Кеширование последней локации
- Кастомные callback’и для UI
class LocationModule(private val context: Context) {
private val fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
fun getLastLocation(callback: (Location?) -> Unit) {
if (checkPermissions()) {
fusedLocationClient.lastLocation.addOnSuccessListener { location ->
callback(location)
}
} else callback(null)
}
private fun checkPermissions(): Boolean {
return ContextCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
}
}
Учитывал edge cases: отказ в разрешениях, выключенный GPS, обработку ошибок. Модуль изолировал логику от UI-слоя.
Ответ 18+ 🔞
А, ну это же классика, ёпта! Приходилось, как же без этого. Вот, например, писал я модуль для геолокации — обычная история, но там столько подводных камней, что овердохуища просто.
Сначала, конечно, этот твой FusedLocationProvider. Чувак, это же просто пизда рулю, если честно. Вроде бы всё просто: дай координаты, сука. А он тебе: «А разрешения есть? А GPS включён? А может, ты в самолёте летишь?». Ну, блядь, ёперный театр.
Самое весёлое — это пермишены. Runtime-запросы, мать их. Пользователь открывает приложение, а ты ему: «Дай доступ к локации, будь другом». А он такой: «А нахуя?». И ты начинаешь объяснять, что без этого фича не работает, а он всё равно отказывает. И вот ты сидишь с callback’ом, который возвращает null, и думаешь: «Ну зачем тогда вообще приложение скачивал, пидарас шерстяной?». Доверия ебать ноль к этим пользователям.
class LocationModule(private val context: Context) {
private val fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
fun getLastLocation(callback: (Location?) -> Unit) {
if (checkPermissions()) {
fusedLocationClient.lastLocation.addOnSuccessListener { location ->
callback(location)
}
} else callback(null)
}
private fun checkPermissions(): Boolean {
return ContextCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
}
}
Смотри, в коде-то вроде всё чисто. Но edge cases, блядь! Это отдельная песня. Отказ в разрешениях — это ещё цветочки. А вот когда GPS выключен — это уже ягодки. Приложение думает, что всё окей, пермишен есть, а локации нет нихуя. Или она есть, но точность — хуй с горы, плюс-минус километр. И как с этим работать? Приходится городить огород с проверками провайдера, точности, времени последнего обновления. Волнение ебать, пока всё оттестируешь.
Ну и главная фишка — изоляция логики. Чтобы этот модуль был как чёрный ящик. UI-слой туда данные шлёт, а обратно получает локацию или ошибку. И не парится, что там внутри творится: запросы, кеширование, обработка ошибок. Сделал кастомные callback’и для UI, чтобы можно было красиво показать: «Всё ок, вот ваши координаты» или «Э, сабака сука, включите GPS, пожалуйста». В общем, стандартная история, но если не предусмотреть все эти «а если...», то потом сидишь и дебажишь, почему у пользователя из Нижнего Тагила показывает, что он в Турции. Сам от себя охуеешь.