Как запустить Activity из другого приложения в Android на Kotlin
1. Основы: явные и неявные интенты
В Android есть два типа Intent для запуска Activity:
- Явный (Explicit Intent) — вы точно знаете package name и class name целевого Activity. Используется для запуска Activity внутри вашего приложения или когда вы знаете точное имя компонента другого приложения.
- Неявный (Implicit Intent) — вы описываете действие (например, просмотр веб-страницы или съёмка фото), а система сама находит подходящее приложение. Это более гибкий и безопасный способ для запуска сторонних приложений.
2. Как узнать package name другого приложения
Самый простой способ — скачать приложение Package Name Viewer из Google Play или использовать ADB-команду:
adb shell pm list packages | grep частичное_имя_приложения
Например, для Google Карт: com.google.android.apps.maps, для Камеры: com.android.camera (или com.google.android.GoogleCamera на Pixel).
3. Запуск Activity с явным Intent (когда знаете package name)
Пример запуска приложения Камера:
val launchIntent = packageManager.getLaunchIntentForPackage("com.android.camera")
if (launchIntent != null) {
startActivity(launchIntent)
} else {
// Приложение не установлено
Toast.makeText(this, "Камера не найдена", Toast.LENGTH_SHORT).show()
// Можно открыть Google Play для установки
try {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.android.camera")))
} catch (e: ActivityNotFoundException) {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=com.android.camera")))
}
}
Метод getLaunchIntentForPackage() возвращает Intent для запуска главного Activity приложения. Всегда проверяйте на null — это лучшая практика.
4. Запуск Activity с неявным Intent (рекомендуемый способ)
Неявные интенты не требуют знания package name. Вы просто указываете действие. Вот несколько примеров:
Открыть URL в браузере
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://pythonlib.ru"))
startActivity(intent)
Открыть местоположение в Картах
val gmmIntentUri = Uri.parse("geo:55.751244,37.618423?z=10")
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
if (mapIntent.resolveActivity(packageManager) != null) {
startActivity(mapIntent)
} else {
// Карты не установлены
Toast.makeText(this, "Приложение карт не найдено", Toast.LENGTH_SHORT).show()
}
Сделать фото
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
if (takePictureIntent.resolveActivity(packageManager) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
} else {
// Камера недоступна
}
Отправить текст в другое приложение (например, мессенджер)
val sendIntent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_TEXT, "Привет! Это сообщение из моего приложения")
type = "text/plain"
}
startActivity(Intent.createChooser(sendIntent, "Поделиться через"))
5. Важные моменты
- Всегда проверяйте наличие приложения с помощью
resolveActivity()илиgetLaunchIntentForPackage(). Если приложение не установлено, вызовstartActivity()вызоветActivityNotFoundException. - Используйте
Intent.createChooser()для неявных интентов — это позволит пользователю выбрать приложение, если их несколько. - Для передачи данных используйте
putExtra(). Например, для ACTION_SEND передавайте текст, для ACTION_VIEW — URI. - В Android 11+ появились ограничения на запрос package name других приложений. Если вам нужно получить список установленных приложений, добавьте в манифест запрос
<queries>.
6. Полный пример с обработкой ошибок
fun launchApp(packageName: String) {
try {
val intent = packageManager.getLaunchIntentForPackage(packageName)
if (intent != null) {
startActivity(intent)
} else {
// Приложение не найдено — предлагаем установить
showInstallDialog(packageName)
}
} catch (e: Exception) {
Log.e("AppLauncher", "Ошибка запуска: ${e.message}")
Toast.makeText(this, "Не удалось запустить приложение", Toast.LENGTH_SHORT).show()
}
}
private fun showInstallDialog(packageName: String) {
AlertDialog.Builder(this)
.setTitle("Приложение не установлено")
.setMessage("Хотите установить его из Google Play?")
.setPositiveButton("Да") { _, _ ->
val playStoreIntent = Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=$packageName"))
startActivity(playStoreIntent)
}
.setNegativeButton("Нет", null)
.show()
}
<<Альтернативный подход: использование Deep Links и App Links
Если вы разрабатываете приложение, которое должно запускаться из других приложений, лучше использовать Deep Links (глубокие ссылки). Это стандартный механизм Android, который позволяет запускать определённый экран вашего приложения по URL.
Как это работает:
- В манифесте вашего приложения добавьте intent-filter для Activity, которое хотите открывать:
<activity android:name=".TargetActivity">
<intent-filter>
<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="myapp.example.com"
android:pathPrefix="/open" />
</intent-filter>
</activity>
Запуск из другого приложения:
val deepLink = "https://myapp.example.com/open?user_id=123"
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(deepLink))
startActivity(intent)
Преимущества этого подхода:
- Независимость от package name — вы работаете через URL, который легко запомнить.
- Единый интерфейс — можно открыть и в браузере, если приложение не установлено (с помощью
android:autoVerify="true"). - Безопасность — система проверяет, что URL принадлежит вашему приложению (через Digital Asset Links).
- Гибкость — можно передавать параметры прямо в URL (query parameters).
Этот метод особенно полезен, если вы создаёте SDK или библиотеку, которая должна взаимодействовать с другими приложениями, не раскрывая внутренние package name.
Ответов пока нет.
Войдите чтобы оставить ответ