12 KiB
Runtime-детекция Google Services и Firebase
📋 Обзор
Приложение SoundWaveRadio теперь поддерживает универсальную работу на устройствах как с Google Services, так и без них (FOSS-устройства, Huawei без GMS, и т.д.).
Важно: Firebase библиотеки включены в APK, но используются только при наличии Google Play Services на устройстве. Файл google-services.json всегда присутствует в проекте, но детекция происходит в runtime на основе реального наличия GMS на устройстве.
✅ Что было реализовано
1. GoogleServicesHelper - Централизованная система детекции
Создан класс GoogleServicesHelper.kt, который обеспечивает:
- ✅ Runtime-проверку доступности Google Play Services
- ✅ Runtime-проверку доступности Firebase
- ✅ Безопасную инициализацию Firebase
- ✅ Безопасное получение Firebase Analytics
- ✅ Безопасное получение FCM токенов
- ✅ Логирование аналитических событий (с fallback)
- ✅ Кэширование результатов проверки
2. Gradle конфигурация
app/build.gradle:
plugins {
id 'com.google.gms.google-services'
id 'com.google.firebase.crashlytics'
// Плагины всегда применяются
}
// Firebase зависимости включены в APK
implementation platform("com.google.firebase:firebase-bom:33.12.0")
implementation "com.google.firebase:firebase-analytics"
implementation "com.google.firebase:firebase-crashlytics"
implementation "com.google.firebase:firebase-config"
implementation "com.google.firebase:firebase-messaging"
implementation "com.google.firebase:firebase-perf"
// Google Play Services для runtime-детекции
implementation "com.google.android.gms:play-services-base:18.5.0"
implementation "com.google.android.gms:play-services-ads-identifier:18.2.0"
Важно: Firebase библиотеки включены в APK, но GoogleServicesHelper проверяет наличие Google Play Services на устройстве в runtime и использует Firebase только если GMS доступен.
3. Обновленные классы
URLRadio.kt:
- ✅ Использует
GoogleServicesHelperдля инициализации - ✅ Graceful fallback при отсутствии Firebase
- ✅ Логирует статус сервисов при запуске
MainActivity.kt:
- ✅ Безопасная инициализация Firebase Analytics
- ✅ Безопасная инициализация Firebase Messaging
- ✅ Nullable типы для Firebase объектов
ReviewManager.kt:
- ✅ Опциональная поддержка Firebase Analytics
- ✅ Логирование событий через
GoogleServicesHelper
PermissionHelper.kt:
- ✅ Упрощенное логирование без прямой зависимости от Firebase
4. AndroidManifest.xml
Все Google/Firebase компоненты помечены как опциональные:
<!-- Опциональные разрешения -->
<uses-permission android:name="com.google.android.gms.permission.AD_ID" tools:node="replace"/>
<!-- Опциональные meta-data -->
<meta-data
android:name="com.google.android.gms.car.application"
tools:node="replace" />
<!-- Опциональный Firebase Messaging Service -->
<service
android:name=".helpers.FMessagingService"
tools:node="replace">
🚀 Как это работает
Сценарий 1: Устройство С Google Services
- APK содержит Firebase библиотеки
- При запуске
GoogleServicesHelperпроверяет наличие Google Play Services на устройстве - GMS обнаружен → Firebase инициализируется
- Firebase Analytics, Crashlytics, Messaging работают нормально
- Приложение получает FCM токен для push-уведомлений
Логи:
✓ Google Play Services available
✓ Firebase available
✓ Firebase Analytics initialized successfully
✓ FCM Token: [token]
Сценарий 2: Устройство БЕЗ Google Services (FOSS/Huawei)
- APK содержит Firebase библиотеки (но они не используются)
- При запуске
GoogleServicesHelperпроверяет наличие Google Play Services на устройстве - GMS НЕ обнаружен → Firebase НЕ инициализируется
- Приложение продолжает работать без аналитики и push-уведомлений
- Все основные функции (радио, плейлисты, настройки) работают нормально
Логи:
⚠ Google Play Services not available
⚠ Firebase not available
⚠ Firebase services are unavailable - running in FOSS mode
⚠ Firebase Messaging not available - push notifications disabled
📱 Тестирование
Тест 1: На устройстве С Google Services
- Соберите APK:
./gradlew assembleRelease - Установите на устройство с Google Play Services (обычный Android)
- Проверьте логи - должны быть сообщения об успешной инициализации Firebase
- Проверьте получение FCM токена
- Проверьте работу основного функционала
Тест 2: На устройстве БЕЗ Google Services (Huawei, эмулятор без GMS)
- Соберите тот же APK:
./gradlew assembleRelease - Установите на устройство без Google Play Services
- Проверьте логи - должны быть предупреждения о FOSS режиме
- Проверьте основной функционал - всё должно работать без крашей
- Firebase функции будут отключены автоматически
Тест 3: Эмулятор без GMS
- Создайте эмулятор без Google Play Services
- Установите APK
- Приложение должно запуститься и работать стабильно
- Проверьте отсутствие крашей при попытке использования Firebase
🔧 API GoogleServicesHelper
Основные методы:
// Проверка доступности Google Play Services
GoogleServicesHelper.isGooglePlayServicesAvailable(context): Boolean
// Проверка доступности Firebase
GoogleServicesHelper.isFirebaseAvailable(): Boolean
// Безопасная инициализация Firebase
GoogleServicesHelper.initFirebaseSafely(context): Boolean
// Получение Firebase Analytics (nullable)
GoogleServicesHelper.getFirebaseAnalytics(context): Any?
// Логирование событий (с fallback)
GoogleServicesHelper.logAnalyticsEvent(context, eventName, params)
// Получение FCM токена
GoogleServicesHelper.getFirebaseMessagingToken(onSuccess, onFailure)
// Проверка необходимости Google функций
GoogleServicesHelper.shouldEnableGoogleFeatures(context): Boolean
// Получение статуса сервисов
GoogleServicesHelper.getServicesStatus(context): String
Пример использования:
// В Activity или Fragment
if (GoogleServicesHelper.isFirebaseAvailable()) {
val analytics = GoogleServicesHelper.getFirebaseAnalytics(this)
// Используем analytics
} else {
// Работаем без аналитики
}
// Логирование события
GoogleServicesHelper.logAnalyticsEvent(
context,
"user_action",
mapOf("action" to "button_click", "screen" to "main")
)
// Получение FCM токена
GoogleServicesHelper.getFirebaseMessagingToken(
onSuccess = { token ->
// Отправить токен на сервер
},
onFailure = { exception ->
// Обработать ошибку
}
)
📦 Сборка приложения
Универсальная сборка (для всех магазинов)
# Один APK для всех типов устройств
./gradlew assembleRelease
Результат:
- APK содержит Firebase библиотеки
- На устройствах с GMS → Firebase работает
- На устройствах без GMS → Firebase не используется
- Один APK подходит для Google Play, RuStore, F-Droid, Huawei AppGallery
⚠️ Важные замечания
-
Firebase библиотеки: Всегда включены в APK, но используются только при наличии GMS на устройстве:
- Код компилируется с Firebase API
- Библиотеки включены в APK (~15-20 МБ)
- Runtime-детекция определяет доступность GMS
- Если GMS нет - Firebase не инициализируется
-
Размер APK:
- Универсальный APK: ~15-20 МБ (включая Firebase)
- Firebase библиотеки занимают ~5-8 МБ
- На устройствах без GMS библиотеки просто не используются
-
Функциональность:
- На устройствах с GMS: Полная функциональность + аналитика + push-уведомления
- На устройствах без GMS: Полная функциональность радио, но без аналитики и push
-
Crashlytics: В release сборке отключен через:
manifestPlaceholders = [crashlyticsCollectionEnabled: "false"] -
google-services.json: Файл всегда присутствует в проекте и используется для конфигурации Firebase, но реальное использование зависит от наличия GMS на устройстве.
🎯 Преимущества решения
✅ Универсальность: Один APK для всех типов устройств и магазинов ✅ Безопасность: Нет крашей при отсутствии Google Services ✅ Простота: Не нужно собирать разные версии APK ✅ Автоматизация: Runtime-детекция работает автоматически ✅ Совместимость: Работает на Huawei, китайских устройствах, эмуляторах ✅ Поддержка: Легко поддерживать и тестировать ✅ Единая сборка: Один APK для Google Play, RuStore, F-Droid, Huawei AppGallery
🔍 Отладка
Для проверки статуса сервисов в runtime:
// В любом месте приложения
val status = GoogleServicesHelper.getServicesStatus(context)
Timber.d(status)
Вывод:
Google Services Status:
- Google Play Services: ✓ Available
- Firebase: ✓ Available
или
Google Services Status:
- Google Play Services: ✗ Not Available
- Firebase: ✗ Not Available
📝 Дополнительная информация
- Все изменения обратно совместимы
- Существующий функционал не затронут
- Приложение автоматически адаптируется к окружению
- Нет необходимости в разных build flavors (хотя можно добавить при желании)
Дата создания: 2025 Версия: 1.0 Статус: ✅ Готово к использованию