Как работают Intent в Android: action, activity и map intent с примерами

Intent — это объект для запуска действий между компонентами Android: явные Intents направляют конкретную Activity/Service, неявные описывают action (например ACTION_VIEW) и данные (URI), а для карт используют geo: URI; запуск выполняют через startActivity / startService с проверкой resolveActivity или новым Activity Result API.

Что такое Intent и какие они бывают

Intent связывает компоненты (Activity, Service, BroadcastReceiver) и передаёт данные. Коротко:

  • Явный (explicit) — указывает конкретный компонент в приложении: используется для навигации внутри вашего приложения.
  • Неявный (implicit) — указывает действие (action) и/или данные; система найдёт подходящий компонент в других приложениях.
  • По назначению: для Activity (UI), Service (фоновые задачи), Broadcast (широковещательные сообщения).

Пример структуры Intent:

  • action: Intent.ACTION_VIEW, Intent.ACTION_SEND и т.д.
  • data/uri: Uri.parse("https://...") или "geo:lat,lon?q=place"
  • extras: пары ключ/значение через putExtra

Action, Activity и Map Intent — практические примеры

Явный Intent — запуск Activity в том же приложении.

Kotlin:

val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("userId", 42)
startActivity(intent)

Java:

Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("userId", 42);
startActivity(intent);

Неявный Intent — открыть ссылку в браузере:

val uri = Uri.parse("https://example.com")
val intent = Intent(Intent.ACTION_VIEW, uri)
if (intent.resolveActivity(packageManager) != null) startActivity(intent)

Map Intent — открыть координаты или поиск места в картах:

// Открыть координаты с подписью
val geoUri = Uri.parse("geo:34.99,-106.61?q=34.99,-106.61(Treasure)")
val mapIntent = Intent(Intent.ACTION_VIEW, geoUri)
mapIntent.setPackage("com.google.android.apps.maps") // опционально — вызвать конкретное приложение
if (mapIntent.resolveActivity(packageManager) != null) startActivity(mapIntent)

Или использовать chooser, чтобы позволить пользователю выбрать приложение:

val chooser = Intent.createChooser(mapIntent, "Открыть в:")
startActivity(chooser)

Отправка данных (ACTION_SEND):

val shareIntent = Intent(Intent.ACTION_SEND).apply {
    type = "text/plain"
    putExtra(Intent.EXTRA_TEXT, "Текст для отправки")
}
startActivity(Intent.createChooser(shareIntent, "Поделиться"))

Запуск Service:

val svc = Intent(this, MyService::class.java)
startService(svc) // для foreground/background сервисов используйте ContextCompat.startForegroundService, учитывайте ограничения Android 8+

Современный способ получить результат от Activity — Activity Result API вместо устаревшего startActivityForResult:

  • Зарегистрируйте ActivityResultLauncher в onCreate и вызывайте launcher.launch(intent).

Перед вызовом неявного Intent проверяйте resolveActivity(packageManager) или используйте try/catch, чтобы избежать Crash, если подходящего обработчика нет.

Лучшие практики при запуске интентов из кода

  • Всегда проверяйте resolveActivity(packageManager) для неявных Intent.
  • Для чувствительных данных используйте явные Intents и права доступа.
  • Используйте Intent.createChooser для улучшения UX.
  • Не полагайтесь на конкретное приложение — оставьте возможность выбора, если это не критично.
  • Для получения результата используйте Activity Result API (ActivityResultLauncher).
  • Указывайте манифестные и нужные разрешения в AndroidManifest.xml.
  • При передаче больших объектов — не через extras, а через локальную базу/файл/синглтон.

Не отправляйте в Intent приватные ключи или большие бинарные данные через extras — это может привести к утечкам или OOM.

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

  • Запуск неявного Intent без проверки resolveActivity — приложение упадёт на устройстве без подходящего приложения.
  • Передача больших объёмов данных через putExtra — OOM или TransactionTooLargeException.
  • Ожидание результата через устаревший startActivityForResult вместо Activity Result API.
  • Указание неверного URI для geo: — карты не откроются корректно.

FAQ

  • Как проверить, что Intent обработается?
    Используйте intent.resolveActivity(packageManager) != null или оборачивайте startActivity в try/catch.

  • Нужно ли добавлять активности в AndroidManifest?
    Да, все Activity и Service должны быть объявлены в манифесте (за исключением тестовых/динамически зарегистрированных компонентов).

  • Как отдать предпочтение Google Maps?
    Установите setPackage("com.google.android.apps.maps"), но учтите, что если приложение не установлено, Intent не будет обработан.

  • Как получить результат из запущенной Activity?
    Зарегистрируйте ActivityResultLauncher и используйте контракт ActivityResultContracts.StartActivityForResult.

  • Можно ли запускать Intent из Service или BroadcastReceiver?
    Да, но при запуске Activity из background на новых версиях Android действуют ограничения — используйте уведомления/foreground service либо интент в UI-потоке.

Если нужно — добавлю готовые фрагменты кода под ваш проект (Kotlin/Java) или пример с Activity Result API.