Практическое использование 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 и давать временные права чтения.
- Манифест — регистрируем провайдера:
<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>
- res/xml/file_paths.xml:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
- Открытие 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 из другого приложения.
Deep link: intent-filter и запуск из кода
Для обработки схемы 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"
Сравнение сценариев использования
Сравнение сценариев использования
| Сценарий | URI | MIME | Обязательные флаги |
|---|---|---|---|
| Открыть веб‑страницу | https://example.com | — (браузер определяет) | нет |
| Открыть локальный PDF | content://.../file.pdf | application/pdf | FLAG_GRANT_READ_URI_PERMISSION |
| Deep link | myapp://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.