Разработка расширения для Share Sheet (Android)
Пользователь нажал Share, но ваше приложение не появилось в списке. Или появилось, но упало с SecurityException. Знакомая ситуация? Типичные причины — неправильный intent-filter или отсутствие обработки ContentResolver. Разберём, как построить надёжный Share Extension, который корректно принимает любые типы контента — от текста до видео — и персонализирует шеринг через Direct Share.
В Android 10+ модель доступа к файлам изменилась: прямой путь к файлу не получить. Каждый content:// URI требует временного разрешения, которое действует только во время активности Activity. Игнорирование этого правила ведёт к падениям на Android 11 и выше. Мы расскажем, как избежать этих ошибок и обеспечить стабильную обработку контента на всех актуальных версиях.
Наше решение включает проверенные паттерны: раздельные intent-filter для каждого MIME-типа, безопасное копирование файлов через ContentResolver и персонализированный Direct Share для повышения конверсии. Вы получите готовый код, который уже протестирован на Android 10–14. Это экономит время на отладку и гарантирует совместимость.
Как настроить intent-filter для нескольких MIME-типов?
Главная ошибка — один фильтр на всё. Система Android плохо обрабатывает несколько <data> внутри одного <intent-filter>. Правильный подход: создаём отдельные фильтры для text/plain, image/*, video/*, application/octet-stream. Пример:
<intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/*" /> </intent-filter> Для SEND_MULTIPLE добавляем аналогичные фильтры. Это гарантирует появление приложения в Chooser для каждого типа.
Как обрабатывать URI без потери данных?
Uri из Intent.EXTRA_STREAM живёт только во время активности (если не взято persistedUriPermission). Читать его нужно через ContentResolver.openInputStream(), а не File(). Мы копируем файл в cacheDir сразу:
val inputStream = contentResolver.openInputStream(sourceUri) val destFile = File(cacheDir, "shared_${System.currentTimeMillis()}.jpg") inputStream?.use { it.copyTo(destFile.outputStream()) } Так файл доступен даже после завершения Activity. На Android 10+ прямой доступ к /data/ заблокирован, поэтому этот pattern обязателен.
Почему Direct Share увеличивает конверсию?
Direct Share показывает персонализированных получателей прямо в системном шеринге. По данным A/B-тестов, конверсия таких шерингов выше в 2–3 раза по сравнению с базовым Chooser. Реализуется через ShortcutManagerCompat.pushDynamicShortcut() с категорией SHORTCUT_CATEGORY_CONVERSATION:
val shortcut = ShortcutInfoCompat.Builder(context, "chat_anna") .setShortLabel("Анна") .setLongLived(true) .setCategories(setOf(ShortcutInfoCompat.SHORTCUT_CATEGORY_CONVERSATION)) .setIntent(Intent(context, ChatActivity::class.java).apply { putExtra("user_id", 42) }) .build() ShortcutManagerCompat.pushDynamicShortcut(context, shortcut) Это отдельная работа: нужно поддерживать актуальность shortcuts, обновлять аватарки, реагировать на изменения контактов. Но результат того стоит.
Сравнение подходов
| Характеристика | Базовый Share | С Direct Share |
|---|---|---|
| Время разработки | 2–3 недели | 4–6 недель |
| Конверсия шеринга | стандартная | +150% |
| Обработка файлов | только online | фоновая синхронизация |
| Персонализация | нет | да, с аватарками |
| Сложность интеграции | низкая | средняя |
Типичные проблемы и их решения
| Проблема | Решение |
|---|---|
| Приложение не появляется в Chooser | Проверить intent-filter: разделить по MIME-типам, добавить SEND_MULTIPLE |
| SecurityException при открытии URI | Использовать ContentResolver.openInputStream() вместо File() |
| Потеря данных при повороте экрана | Сохранять скопированный путь в onSaveInstanceState |
| Неправильный back-стек | Настроить launchMode="singleTask" и taskAffinity |
Чек-лист тестирования Share Extension
- Проверить одиночный и множественный шеринг текста, изображений, видео. - Проверить на Android 10, 12, 14 (на эмуляторе и реальных устройствах). - Убедиться, что приложение появляется в Chooser для всех целевых типов. - Проверить Direct Share: отображаются ли персонализированные контакты. - Симулировать прерывание (звонок, поворот) до завершения обработки.Что входит в работу
- Анализ типов контента, которые должно принимать приложение.
- Проектирование intent-filter и UI выбора (при необходимости).
- Реализация Activity-приёмника с обработкой URI и копированием.
- Настройка Direct Share с поддержкой актуальных shortcuts.
- Тестирование на Android 10–14 с реальными файлами и текстом.
- Документация по интеграции и поддержка при деплое.
- Экономия времени на отладку за счёт готовых решений.
Процесс работы
- Анализ — изучаем типы контента, которые ваше приложение должно принимать.
- Проектирование — выбираем схему intent-filter, проектируем UI выбора (если нужно).
- Разработка — пишем Activity-приёмник, обрабатываем URI, реализуем копирование.
- Тестирование — проверяем на Android 10, 12, 14 с разными файлами и текстом.
- Деплой — публикуем в Google Play, настраиваем Google Play Console для принятия ссылок.
Сроки и стоимость
Оценим ваш проект за 1–2 дня. Базовое расширение — от 2 недель. Сложные интеграции — до 6 недель. Стоимость фиксируется после согласования ТЗ. У нас 5+ лет опыта в Android-разработке, более 20 успешных Share Extension. Получите готовое решение с гарантией совместимости на Android 10–14. Закажите разработку Share Extension прямо сейчас — начнём с консультации.
Согласно Android Developer Guide, для надёжного приёма контента используйте отдельные intent-filter на каждый MIME-тип.
Свяжитесь с нами, чтобы обсудить ваш проект и получить индивидуальное предложение.







