Как правильно передать utm_source и utm_campaign в Android-приложении

Короткий ответ: используйте глубокие ссылки (deep links) для внешних URL и Intent extras/ PendingIntent для внутренних переходов и виджетов — считывайте utm_source и utm_campaign в Activity и сразу логируйте в аналитику (Firebase/GA/Appsflyer).

Что такое UTM и зачем они в Android

UTM — это параметры URL (например ?utm_source=google&utm_campaign=sale) для идентификации источника трафика. В Android они важны, чтобы связывать установки и сессии с рекламой, виджетами и рассылками. Практическая цель: передать значения utm_* в момент открытия приложения и записать событие в аналитике.

Deep linking и интенты: как ловить utm_source и utm_campaign

  1. Настройте intent-filter в AndroidManifest для домена:
<intent-filter android:autoVerify="true">
  <action android:name="android.intent.action.VIEW"/>
  <category android:name="android.intent.category.DEFAULT"/>
  <category android:name="android.intent.category.BROWSABLE"/>
  <data android:scheme="https" android:host="yourapp.com"/>
</intent-filter>
  1. В Activity извлекайте параметры из URI и логируйте их:
override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  intent?.data?.let { uri ->
    val source = uri.getQueryParameter("utm_source")
    val campaign = uri.getQueryParameter("utm_campaign")
    if (!source.isNullOrBlank() || !campaign.isNullOrBlank()) {
      val bundle = Bundle().apply {
        putString("utm_source", source)
        putString("utm_campaign", campaign)
      }
      FirebaseAnalytics.getInstance(this).logEvent("utm_click", bundle)
      // Сохраните в SharedPreferences, если нужно использовать позже
    }
  }
}
  1. Тестирование через ADB: adb shell am start -a android.intent.action.VIEW -d "https://yourapp.com/?utm_source=test&utm_campaign=campaign" com.your.package

Если кампания может приводить и к установкам, передавайте UTM в install-referrer (Play Install Referrer) или связывайте сервер-сайдом для более точных атрибуций.

UTM в виджетах: реализация и передача через PendingIntent

Виджеты не передают UTM автоматически. Сделайте клики, которые стартуют Activity с extras.

  1. В AppWidgetProvider при обновлении:
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
  for (appWidgetId in appWidgetIds) {
    val views = RemoteViews(context.packageName, R.layout.widget_layout)
    val intent = Intent(context, MainActivity::class.java).apply {
      putExtra("utm_source", "widget")
      putExtra("utm_campaign", "daily_promo")
      flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
    }
    val pendingIntent = PendingIntent.getActivity(
      context,
      appWidgetId, // уникальный requestCode
      intent,
      PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
    )
    views.setOnClickPendingIntent(R.id.promo_button, pendingIntent)
    appWidgetManager.updateAppWidget(appWidgetId, views)
  }
}
  1. В Activity обрабатывайте extras так же, как параметры из URI:
val source = intent.getStringExtra("utm_source")
val campaign = intent.getStringExtra("utm_campaign")
// логирование в аналитику

Используйте уникальный requestCode (например, appWidgetId) при создании PendingIntent и указывайте FLAG_IMMUTABLE/FLAG_UPDATE_CURRENT. Иначе клики могут вести себя некорректно на современных версиях Android.

Тестирование и проверка в аналитике

  • Установите виджет, кликните и смотрите Logcat на наличие extras. Логируйте сразу событие в Firebase, чтобы отследить приход.
  • Симулируйте deep link через ADB (см. пример выше).
  • Проверьте консоль аналитики на появление события utm_click или на поля utm_source/utm_campaign.
  • Если UTM "теряются" между установкой и первым запуском — используйте Play Install Referrer API или серверную генерацию ссылок.

Частые ошибки

  • Не добавили flags или использовали неподходящий requestCode для PendingIntent — клики не работают.
  • Не логируете UTM в момент получения — аналитика не свяжет сессии.
  • Ожидание автоматической передачи UTM из виджета — нужно передать extras вручную.
  • Использование нестабильного хранения (не сохраняете UTM в persistent storage до логирования).

FAQ

  • Как передать UTM из push-уведомления?
    В Intent уведомления положите extras ("utm_source","utm_campaign") и обработайте в Activity.

  • Нужно ли сохранять UTM для последующей аналитики?
    Да — сохраните в SharedPreferences/DB, если данные нужны позже (например, при первом экране регистрации).

  • Как связать UTM с установкой приложения?
    Используйте Play Install Referrer или MMP (Appsflyer) для корректной атрибуции установок.

  • Что безопаснее для виджета: FLAG_IMMUTABLE или FLAG_MUTABLE?
    Используйте FLAG_IMMUTABLE, если не планируете менять PendingIntent; это рекомендовано для безопасности.