Практическое использование Intent.ACTION_VIEW в Android

Intent.ACTION_VIEW в Android открывает URL, файл или deep link по переданному URI — система выберет приложение по схеме или MIME‑типу. Ниже — краткие, рабочие примеры на Kotlin и необходимые манифест‑настройки.

Быстрый старт — общая схема и открытие URL

Создайте Intent с URI и всегда проверяйте resolveActivity(), чтобы избежать краша.

val uri = Uri.parse("https://example.com")
val intent = Intent(Intent.ACTION_VIEW, uri)
if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent)
} else {
    Toast.makeText(this, "Нет приложения для открытия ссылки", Toast.LENGTH_SHORT).show()
}

Если нужно принудительно открыть в конкретном браузере (например, Chrome):

intent.setPackage("com.android.chrome")
startActivity(intent)

Добавление флагов:

  • FLAG_ACTIVITY_NEW_TASK для запуска из контекста, не являющегося Activity.
  • Для безопасного фонового запуска комбинируйте флаги аккуратно, учитывая поведение task stack.

Проверяйте intent.resolveActivity() перед startActivity — это простой способ избежать ActivityNotFoundException.

Открытие локальных файлов: FileProvider (Android 7+)

На Android 7+ надо использовать FileProvider и давать временные права чтения.

  1. Манифест — регистрируем провайдера:
<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${applicationId}.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>
  1. res/xml/file_paths.xml:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>
  1. Открытие PDF (пример):
val file = File(context.getExternalFilesDir(null), "document.pdf")
val uri = FileProvider.getUriForFile(context, "${context.packageName}.fileprovider", file)

val intent = Intent(Intent.ACTION_VIEW).apply {
    setDataAndType(uri, "application/pdf")
    addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}

if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent)
} else {
    // fallback: показать сообщение или открыть в браузере
    Toast.makeText(context, "Установите PDF Viewer", Toast.LENGTH_SHORT).show()
}

Без FLAG_GRANT_READ_URI_PERMISSION получаете Permission Denial при доступе к content:// URI из другого приложения.

Для обработки схемы myapp://product добавьте intent-filter в активность:

<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="myapp" android:host="product" />
</intent-filter>

Запуск deep link из кода:

val deepLink = "myapp://product?id=123"
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(deepLink))
if (intent.resolveActivity(packageManager) != null) {
    startActivity(intent)
}

Чтение параметров в активности:

val uri = intent?.data
val productId = uri?.getQueryParameter("id") // "123"

Сравнение сценариев использования

Сравнение сценариев использования

СценарийURIMIMEОбязательные флаги
Открыть веб‑страницуhttps://example.com— (браузер определяет)нет
Открыть локальный PDFcontent://.../file.pdfapplication/pdfFLAG_GRANT_READ_URI_PERMISSION
Deep linkmyapp://product?id=123— (по схеме)нет

MIME‑тип определяет, какое приложение будет предложено пользователю.

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

  • Не проверять resolveActivity() → ActivityNotFoundException.
  • Не использовать FileProvider → SecurityException на Android 7+.
  • Забыть FLAG_GRANT_READ_URI_PERMISSION → Permission Denial.
  • Передавать Uri.fromFile(...) вместо FileProvider для внешних файлов — неработает в современных версиях.

FAQ

  • Как открыть intent из сервиса?
    Используйте FLAG_ACTIVITY_NEW_TASK и контекст сервиса: intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK).

  • Можно ли открыть файл напрямую по file:// URI?
    На Android 7+ file:// запрещены для межприложного обмена — используйте FileProvider.

  • Как отловить, что пользователь выбрал другое приложение?
    Запуск через startActivityForResult не даст выбора результата у внешнего приложения в новых API; предпочтительнее предлагать chooser:
    Intent.createChooser(intent, "Открыть с помощью")

  • Как обеспечить безопасность FileProvider?
    Не делайте provider экспортируемым, ограничьте пути в file_paths.xml и давайте права только с FLAG_GRANT_READ_URI_PERMISSION.

Это покрывает основные паттерны использования Intent.ACTION_VIEW: короткие рабочие примеры, манифест‑настройки и частые подводные камни. Тестируйте на реальном устройстве и разных версиях Android.