Фильтр намерений Android для определенного расширения файла?

93

Я хочу иметь возможность загрузить файл с определенным расширением из сети и передать его моему приложению для работы с ним, но мне не удалось выяснить фильтр намерений. Тип файла не включен в mimetypes, и я попытался использовать

<data android:path="*.ext" />

но я не мог заставить это работать.

Curyous
источник

Ответы:

120

Вот как я определил свою активность в своем AndroidManifest.xml, чтобы заставить это работать.

<activity android:name="com.keepassdroid.PasswordActivity">
    <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="file" />
        <data android:mimeType="*/*" />
        <data android:pathPattern=".*\\.kdb" />
        <data android:host="*" />
    </intent-filter>
</activity>

schemeИз fileозначает , что это должно произойти при открытии локального файла (а не протокол , как HTTP).

mimeTypeможно установить для */*соответствия любому типу MIME.

pathPatternздесь вы указываете, какое расширение вы хотите сопоставить (в этом примере .kdb). В .*начале соответствует любой последовательности символов. Эти строки требуют двойного экранирования, поэтому \\\\.соответствует буквальной точке. Затем вы заканчиваете своим расширением файла. Одно предостережение с pathPattern заключается в том, что совпадение .*не является жадным, как вы ожидали бы, если бы это было регулярное выражение. Этот шаблон не будет соответствовать путям, которые содержат .перед .kdb. Более подробное обсуждение этой проблемы и обходной путь см. Здесь

Наконец, в соответствии с документацией Android, как hostи schemeатрибуты , необходимые для pathPatternатрибута работы, так что просто установить , что для шаблона , чтобы соответствовать что - нибудь.

Теперь, если вы выберете .kdbфайл в приложении, таком как Linda File Manager, мое приложение появится в качестве опции. Я должен отметить, что одно это не позволяет вам загружать этот тип файла в браузере, поскольку он регистрируется только в файловой схеме. Наличие на телефоне такого приложения, как Linda File Manager, в целом само по себе не позволяет вам загружать файлы любого типа.

Брайан Пеллин
источник
3
Здесь это не работает. Сначала с mimeType = " " пакет не устанавливается на Android 2.1, я получаю MalformedMimeTypeException. Использование "* / " исправляет это, но тогда этот фильтр не действует. В настоящее время я тестирую браузер Skyfire, который не сохраняет MIME-тип загрузок, как это делает стандартный браузер Android. А при нажатии на файл в списке загрузок Skyfire передается упрощенное намерение ПРОСМОТР с данными файла. И этот фильтр намерений не соответствует.
olivierg
@Brian Pellin: Я на самом деле искал способ привязать mime-тип к .kdbxрасширению, чтобы позволить файловому проводнику ES открывать файлы kdbx, когда мне указали на этот пост. Очевидно, если намерение имеет пустой тип MIME, этот фильтр намерения не будет работать !! Кроме того, можно иметь намерение с EMPTY строкой в ​​качестве действия и просто URI. Документы Google ответили на это намерение, поэтому оно должно быть действительным.
billc.cn 06
2
Чтобы прояснить, mimeType должен быть "* / *" Я думаю, что некоторые люди забыли сбежать от своих * s
Брайан Пеллин
1
Это не будет работать с Android 4. Вы должны использовать <data>тег с четырьмя атрибутами. Наличие 4 тегов является логическим ИЛИ - что работало с Android 2, но Android 4 более строгий. См. Stackoverflow.com/questions/20650378/…
Мартин
3
если \\\\.спички буквального периода, почему вы не используете его , чтобы сформировать .kdbрасширение , как это: \\\\.kdb?
Lealo
36

По этой теме много дезинформации, не в последнюю очередь из собственной документации Google. Лучшее и, учитывая странную логику, возможно, единственная реальная документация - это исходный код.

Реализация фильтра намерений имеет логику, которая почти не поддается описанию. Код парсера - еще одна важная часть головоломки.

Следующие фильтры очень близки к разумному поведению. Шаблоны путей действительно применяются для "file"целей схемы.

Соответствие глобальному шаблону mime-типа будет соответствовать всем типам, если совпадает расширение файла. Это не идеально, но это единственный способ сопоставить поведение файловых менеджеров, таких как ES File Explorer, и он ограничен намерениями, для которых совпадает URI / расширение файла.

Я не включал другие схемы, подобные этой "http", но они, вероятно, будут хорошо работать со всеми этими фильтрами.

Странная схема выходит "content", для которой расширение недоступно фильтру. Но до тех пор, пока поставщик указывает ваш тип MIME (например, Gmail будет передавать тип MIME для вложения беспрепятственно), фильтр будет соответствовать.

Уловки, о которых следует знать:

  1. Имейте в виду, что в фильтрах ничего не происходит последовательно, это лабиринт особых случаев, и нарушение принципа наименьшего удивления рассматривается как цель дизайна. Ни один из алгоритмов сопоставления с образцом не следует одинаковому синтаксису или поведению. Иногда отсутствие поля является подстановочным знаком, а иногда - нет. Атрибуты в элементе данных иногда должны идти вместе, а иногда игнорировать группировку. Это действительно можно было сделать лучше.
  2. Для соответствия правилам необходимо указать schemeAND (в отличие от руководства Google по API, в настоящее время).hostpath
  3. По крайней мере, ES File Explorer генерирует намерения с типом MIME "", который фильтруется совсем иначе null, не может быть сопоставлен явно и может быть сопоставлен только рискованным "*/*"фильтром.
  4. "*/*"Фильтр не будет соответствовать Intents с nullтипом MIME - что требует отдельного фильтра для этого конкретного случая, без типа MIME вообще.
  5. "content"Схема может быть согласована только по типу MIME, так как оригинальное имя файла не доступно в намерениях (по крайней мере , с Gmail).
  6. Группировка атрибутов в отдельные "data"элементы (почти) не имеет отношения к интерпретации, за конкретным исключением hostи port- которые действительно соединяются вместе. Все остальное не имеет конкретной связи внутри "data"элемента или между "data"элементами.

Учитывая все это, вот пример с комментариями:

<!--
     Capture content by MIME type, which is how Gmail broadcasts
     attachment open requests.  pathPattern and file extensions
     are ignored, so the MIME type *MUST* be explicit, otherwise
     we will match absolutely every file opened.
-->
<intent-filter
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:priority="50" >
    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.BROWSABLE" />
    <category android:name="android.intent.category.DEFAULT" />

    <data android:scheme="file" />
    <data android:scheme="content" />
    <data android:mimeType="application/vnd.my-type" />
</intent-filter>

<!--
     Capture file open requests (pathPattern is honoured) where no
     MIME type is provided in the Intent.  An Intent with a null
     MIME type will never be matched by a filter with a set MIME
     type, so we need a second intent-filter if we wish to also
     match files with this extension and a non-null MIME type
     (even if it is non-null but zero length).
-->
<intent-filter
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:priority="50" >
    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.BROWSABLE" />
    <category android:name="android.intent.category.DEFAULT" />

    <data android:scheme="file" />
    <data android:host="*" />

    <!--
         Work around Android's ugly primitive PatternMatcher
         implementation that can't cope with finding a . early in
         the path unless it's explicitly matched.
    -->
    <data android:pathPattern=".*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.my-ext" />
</intent-filter>

<!--
     Capture file open requests (pathPattern is honoured) where a
     (possibly blank) MIME type is provided in the Intent.  This
     filter may only be necessary for supporting ES File Explorer,
     which has the probably buggy behaviour of using an Intent
     with a MIME type that is set but zero-length.  It's
     impossible to match such a type except by using a global
     wildcard.
-->
<intent-filter
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:priority="50" >
    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.BROWSABLE" />
    <category android:name="android.intent.category.DEFAULT" />

    <data android:scheme="file" />
    <data android:host="*" />
    <data android:mimeType="*/*" />

    <!--
         Work around Android's ugly primitive PatternMatcher
         implementation that can't cope with finding a . early in
         the path unless it's explicitly matched.
    -->
    <data android:pathPattern=".*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\.my-ext" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\..*\\..*\\.my-ext" />
</intent-filter>
Дэвид Сейнти
источник
Замечательно, что вы противостоите многочисленным доказательствам необходимости \\ .. снова и снова и других причуд. Google должен был исправить это в 4.2, черт возьми. Увы, у меня все еще есть случаи, которые ваш пример, похоже, не исправляет. Есть ли проблема с 6-ю расширениями, такими как ".gblorb", что мой код работает нормально с 3 буквами или меньше?
RoundSparrow hilltx
На мой взгляд, лучший ответ на этот и аналогичные вопросы! К сожалению, до тех пор, пока невозможно сопоставить намерения содержимого по расширению файла (как вы указываете в 5.), невозможно надежно фильтровать ВСЕ правильные намерения, не сопоставляя также неправильные. Это на тот случай, когда вы не можете использовать настраиваемый тип пантомимы. Итак, пока Android не предоставляет решение для этого, он будет для меня средством выбора файлов в приложении ... Я не хочу запутывать пользователя непоследовательным поведением.
Benjamin
1
Большое спасибо .. Вы только что сделали мой день .. В моем случае мне пришлось изменить MimeType, как и <data android:mimeType="*/*" /> во всех трех вариантах, и это отлично сработало для всех приложений, включая Google Drive и Gmail.
Rishabh Wadhwa
1
Я хотел бы поблагодарить вас, @David Sainty. Вы положили конец моей 24-часовой агонии в попытках понять, как с этим справиться. Я пробовал stackoverflow.com/q/18577860/6110285 , stackoverflow.com/a/8599921/6110285 и многие другие похожие. Это единственный, который работал.
pittix
24

Я должен признать, что простая задача открытия вложений из электронных писем и файлов из файловой системы на Android была одним из самых раздражающих опытов. Легко обрабатывать слишком много файлов или слишком мало. Но сделать все правильно сложно. Большинство решений, опубликованных в stackoverflow, у меня не работали.

Мои требования были:

  • пусть мое приложение обрабатывает вложения, которыми поделено мое приложение
  • иметь мое приложение для обработки файлов в хранилище файлов, которые были созданы моим приложением и имеют определенное расширение

Вероятно, лучший способ решить эту задачу - указать пользовательский тип MIME для ваших вложений. И вы, вероятно, также выберете собственное расширение файла. Итак, предположим, что наше приложение называется «Cool App», и мы создаем вложения файлов с расширением «.cool» в конце.

Это самое близкое к моей цели, и оно работает ... удовлетворительно.

<!-- Register to handle email attachments -->
<!-- WARNING: Do NOT use android:host="*" for these as they will not work properly -->
<intent-filter>
    <!-- needed for properly formatted email messages -->
    <data
        android:scheme="content"
        android:mimeType="application/vnd.coolapp"
        android:pathPattern=".*\\.cool" />
    <!-- needed for mangled email messages -->
    <data
        android:scheme="content"
        android:mimeType="application/coolapp"
        android:pathPattern=".*\\.cool" />
    <!-- needed for mangled email messages -->
    <data
        android:scheme="content"
        android:mimeType="application/octet-stream"
        android:pathPattern=".*\\.cool" />

    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
</intent-filter>

<!-- Register to handle file opening -->
<intent-filter>
    <data android:scheme="file"
          android:mimeType="*/*"
          android:pathPattern=".*\\.cool"
          android:host="*"/>

    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
</intent-filter>

Примечания:

  • pathPattern, Кажется, более или менее игнорируется для вложений (при использовании android:scheme="content"). Если кто-то заставит pathPattern реагировать только на определенные шаблоны, я буду очень рад узнать, как это сделать.
  • Приложение Gmail отказывалось отображать мое приложение в списке выбора, если я добавлял android:host="*"атрибут.
  • Возможно, это все еще работает, если эти intent-filterблоки объединить, но я этого не проверял.
  • Для обработки запросов из браузера при загрузке файла android:scheme="http"может использоваться. Обратите внимание, что некоторые браузеры могут испортить работу, android:mimeTypeпоэтому поэкспериментируйте android:mimeType="*/*"и проверьте в отладчике, что на самом деле проходит, а затем ужесточите фильтрацию, чтобы не стать тем раздражающим приложением, которое обрабатывает все .
  • Некоторые проводники файлов также могут испортить MIME-типы ваших файлов. Вышеупомянутое intent-filterбыло протестировано с приложением Samsung «Мои файлы» на Galaxy S3. FX Explorer по-прежнему отказывается правильно открывать файл, и я также заметил, что значок приложения не используется для файлов. Опять же, если у кого-то это работает, прокомментируйте ниже.

Надеюсь, вы найдете это полезным и вам не придется тратить дни на перебор всех возможных комбинаций. Есть возможности для улучшения, поэтому комментарии приветствуются.

омахена
источник
Для меня это рабочее решение. Регистрация отдельного <intent-filter> для Content-Scheme и File-Scheme сделала свое дело! Благодарность!
Mehlyfication
Благодарность! Работал у меня. И приложение Gmail, и приложение Samsung My Files на Galaxy S6 смогли открыть файл в моем приложении с помощью вашего решения!
Харис
Что такое «название приложения»? (В моем случае в удобочитаемом имени приложения есть пробелы.)
Уильям Джокуш,
@WilliamJockusch похоже, что @DavidSainty просто сохраняет имя приложения в строковом файле ресурсов. Пробелов должно хватить. Строка, используемая для android:labelфильтра намерений, - это строка, которую пользователь увидит в меню выбора. По умолчанию используется название приложения.
omahena
Что мне следует использовать для приложения "Google Диск"?
разработчик Android
9

Ответ Брайана, приведенный выше, помог мне на 90%. Чтобы закончить это, для пантомимы я использовал

android:mimeType="*/*"

Я подозреваю, что предыдущие плакаты пытались опубликовать ту же деталь, но без указания косой черты звездочка в качестве кода, stackoverflow отображает ее как просто косую черту.

Доусон
источник
2
С этим вы будете обрабатывать ВСЕ типы файлов, и это действительно раздражает (ну, кроме случаев, когда ваше приложение действительно обрабатывает все) ...
Тим Атин
Это плохо. Пожалуйста, не делайте этого в своих приложениях.
Марс
8

Вместо того android:path, чтобы попробовать android:mimeType, со значением типа MIME этого конкретного фрагмента содержимого. Также android:pathне принимает подстановочные знаки - используйте android:pathPatternдля этого.

CommonsWare
источник
"Тип файла не включен в миметипы"? По-прежнему должен существовать mimetype для типа загружаемого контента, даже если он не использует то же слово.
Эрик Милл
Для типа содержимого существует mimetype, но файл создается сторонним приложением, которое добавляет к нему другое расширение, поэтому я не думаю, что он будет распознан как этот mimetype.
Curyous
7

Я пытался заставить это работать целую вечность и пробовал в основном все предлагаемые решения, но до сих пор не могу заставить Android распознавать определенные расширения файлов. У меня есть фильтр намерений с "*/*"типом mimetype, который, похоже, работает, и файловые браузеры теперь перечисляют мое приложение как вариант для открытия файлов, однако теперь мое приложение отображается как вариант для открытия ЛЮБОГО ВИДА файла, хотя Я указал определенные расширения файлов с помощью тега pathPattern. Это заходит так далеко, что даже когда я пытаюсь просмотреть / отредактировать контакт в моем списке контактов, Android спрашивает меня, хочу ли я использовать свое приложение для просмотра контакта, и это лишь одна из многих ситуаций, когда это происходит, ОЧЕНЬ ОЧЕНЬ раздражая.

В конце концов я нашел это сообщение групп Google с аналогичным вопросом, на который ответил настоящий разработчик фреймворка Android. Она объясняет, что Android просто ничего не знает о расширениях файлов, только о MIME-типах ( https://groups.google.com/forum/#!topic/android-developers/a7qsSl3vQq0 ).

Итак, из того, что я видел, пробовал и читал, Android просто не может отличить расширения файлов, а тег pathPattern - это, по сути, гигантская трата времени и энергии. Если вам повезло, что вам нужны файлы только определенного типа mime (например, текст, видео или аудио), вы можете использовать фильтр намерения с типом mime. Однако если вам нужно конкретное расширение файла или mime-тип, неизвестный Android, вам не повезло.

Если я ошибаюсь в чем-либо из этого, скажите мне, до сих пор я читал все сообщения и пробовал все предлагаемые решения, которые мог найти, но ни одно не сработало.

Я мог бы написать еще одну или две страницы о том, насколько распространены подобные вещи в Android и насколько неприятен опыт разработчиков, но я спасу вас от своих гневных разглагольствований;). Надеюсь, я избавил кого-то от неприятностей.

PeeGee85
источник
1
Проголосовал за вас, потому что в вашем ответе есть полезная ссылка, а участник, проголосовавший против, не оставил комментарий. Извините, ТАК иногда может быть недружелюбным, но не прекращайте это делать.
Джон Хаттон
4

Обновление 2020

Android перешел на URI контента и MIME-типы для фильтров намерений.

Проблема

URI контента не обязательно должен содержать расширение или имя файла, и он будет отличаться в разных приложениях, которые предоставляют контент / файл.

Вот несколько примеров URI контента из разных почтовых приложений для одного и того же вложения электронной почты:

Gmail -> content://com.google.android.gm.sapi/some_email@gmail.com/message_attachment_external/%23thread-a%3Ar332738858767305663/%23msg-a%3Ar-5439466788231005876/0.1?account_type=com.google&mimeType=application%2Foctet-stream&rendition=1

Outlook -> content://com.microsoft.office.outlook.fileprovider/outlookfile/data/data/com.microsoft.office.outlook/cache/file-download/file--2146063402/filename.customextention

Приложение электронной почты Samsung -> content://com.samsung.android.email.attachmentprovider/1/1/RAW

Как видите, все они разные и не гарантируют, что они содержат что-либо, связанное с вашим фактическим файлом. Таким образом, вы не можете использовать то, android:pathPatternчто предлагалось большинством.

Обходное решение для вложений электронной почты

<intent-filter>
    <action android:name="android.intent.action.VIEW"/>

    <category android:name="android.intent.category.BROWSABLE"/>
    <category android:name="android.intent.category.DEFAULT"/>

    <data android:scheme="content"/>
    <data android:host="*"/>

    <!--  Required for Gmail and Samsung Email App  -->
    <data android:mimeType="application/octet-stream"/>

    <!--  Required for Outlook  -->
    <data android:mimeType="application/my-custom-extension"/>
</intent-filter>

В ходе тестирования я обнаружил типы MIME, которые используют Gmail, Outlook и Samsung Email, и добавил их в свой фильтр намерений.

Предостережения / Проблемы

  • Я обнаружил, что с помощью приведенного выше решения, если я открою любой файл двоичного типа, он автоматически запустит мое приложение. Я обработал это в своей деятельности, отображая состояние сбоя, если мы не могли проанализировать файл. Я подумал, что это было довольно редкое событие, так что это было приемлемо.

  • Я не мог найти способ запустить свое приложение через файловый браузер без добавления <data android:mimeType="*/*"/>в мой фильтр намерений. Я не мог использовать это, потому что он запускал бы мое приложение всякий раз, когда пользователь щелкал любой файл на своем телефоне (а не только файлы с расширением пользовательского файла). Я бы не рекомендовал добавлять это в ваш фильтр намерений.

Последние мысли

  • В настоящее время нет элегантного решения для связывания вашего приложения с определенным типом расширения в Android. Это было лучшее, что я мог сделать в своей ситуации.
Александр Антая
источник
спасибо большое, работает, проверено окт 2020, с android 7
сурово
3

Ответ Брайана очень близок, но вот чистый и безошибочный способ вызвать ваше приложение при попытке открыть файл с вашим собственным расширением (нет необходимости в схеме или хосте):

<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:mimeType="*/*" />
    <data android:pathPattern="*.*\\.kdb" />
</intent-filter>
Кон
источник
2
В документации Android указано, что атрибут pathPattern имеет смысл только в том случае, если указаны схема и хост, и я проверил это: developer.android.com/guide/topics/manifest/data-element.html
Брайан Пеллин,
4
-1; это будет соответствовать любому файлу; Комментарий Брайана верен, и с незначительной модификацией mimeType = " / " его исходный пример идеален.
Ник
Этот пост если давно, но никакой "/" не устанавливает. Вам нужен "* / *", который будет соответствовать любому типу файла (не уверен, если вы хотели это сказать). Таким образом, вашу программу могут попросить открыть видео или mp3. Я пока не нашел решения этого.
Rene
Вы должны использовать один <data>тег с четырьмя атрибутами. Ваше решение может работать с Android 2, но правила стали более строгими: stackoverflow.com/questions/20650378/…
Мартин
Что случилось со странным pathPattern ? А так hostи schemeтребуются!
Игорь Ганапольский
3

На Android 4 правила стали строже, чем раньше. Использование:

    <data
      android:host=""
      android:mimeType="*/*"
      android:pathPattern=".*\\.ext"
      android:scheme="file"
    ></data>
Мартин
источник
3

Я сам немного боролся с этим для собственного расширения файла. После долгих поисков я нашел эту веб-страницу, где плакат обнаружил, что класс Android patternMatcher (который используется для сопоставления pathPattern в Intent-Filters) имеет неожиданное поведение, когда ваш путь содержит первый символ вашего шаблона сопоставления в другом месте пути (например, если вы пытаетесь сопоставить «* .xyz», класс patternMatcher останавливается, если на вашем пути есть «x»). Вот что он нашел для обходного пути и сработал для меня, хотя это немного похоже на взлом:

PatternMatcher используется для pathPattern в IntentFilter. Но алгоритм PatternMatcher мне довольно странен. Вот алгоритм Android PatternMatcher.

Если в середине строки есть «следующий символ» шаблона «. *», PatternMatcher останавливает цикл в этой точке. (См. PatternMatcher.java платформы Android.)

Ex. строка: "это мое приложение" шаблон: ". att. ". Android PatternMatcher введите цикл для соответствия '. 'шаблон до тех пор, пока не встретится следующий символ шаблона (в данном примере' a ') Итак,'. 'соответствующий цикл останавливается на индексе 8 -' a 'между' is 'и' my '. Следовательно, результат этого совпадения возвращает false.

Довольно странно, не правда ли? Чтобы обойти это - фактически уменьшить вероятность - разработчик должен использовать надоедливый тупой pathPattern.

Ex. Цель: соответствие пути uri, содержащего слово «сообщение».

<intent-filter>
...
<data android:pathPattern=".*message.*" />
<data android:pathPattern=".*m.*message.*" />
<data android:pathPattern=".*m.*m.*message.*" />
<data android:pathPattern=".*m.*m.*m.*message.*" />
<data android:pathPattern=".*m.*m.*m.*m.*message.*" />
...
</intent-filter>

Это особенно актуально при сопоставлении с настраиваемым расширением файла.

Бенджамин Дэвис
источник
Для тех , кто заинтересован, вопрос был записан в code.google.com
Бенжамина Девис
3

Ничего из вышеперечисленного не работает должным образом для действий VIEW или SEND, если суффикс не зарегистрирован с типом MIME в базе данных MIME system = wide Android. Единственные настройки, которые я обнаружил, срабатывают для указанного суффикса, включают android:mimeType="*/*", но затем действие срабатывает для ВСЕХ файлов. Ясно НЕ то, что вы хотите!

Я не могу найти подходящего решения, не добавив mime и суффикс в базу данных mime Android, но пока я не нашел способа сделать это. Если кто знает, указатель был бы потрясающим.

Гленн Уайднер
источник
2

Когда Намерение соответствует a intent-filter, вот intent-filterтребования: (представьте контрольный список).

  • Любое соответствие <action>
  • Любое соответствие <category>
  • Любое совпадение <data mimeType>(простое исправление: " / ")
  • По выбору:

    • Любое согласование <data scheme>(легко исправить: <data android:scheme="file" /> <data android:scheme="content" />)

    • Любое совпадение <data host>(простое исправление: "*")

    • Любое соответствие <data pathPattern/etc.>(например .*\\.0cc)

При определении нескольких <data $type="">элементов проверяется поле $ type, если какой-либо из них <data $type=>соответствует Intent.

Отсутствие mimeType нарушает вашу работу intent-filter, даже если оно кажется избыточным. Пропуск <data scheme/host/pathPattern>заставляет ваш фильтр соответствовать всему.

https://f-droid.org/en/packages/de.k3b.android.intentintercept/ - это приложение, предназначенное для получения всех намерений и позволяющее проверять намерения. Я узнал, что нераспознанные расширения файлов, открытые с помощью Simple File Manager, поставляются с типом MIME application/octet-stream.

https://stackoverflow.com/a/4621284/2683842 сообщает, что <data pathPattern=> .*xyzпрерывается при первом обнаружении xи немедленно завершается неудачей, если не следует yz. Так /sdcard/.hidden/foo.0ccчто не пройдет, .*\\.0ccесли вы не попробуете .*\\..*\\.0cc.

  • Я не проверял необходимость этого обходного пути.

Конечный результат:

<activity android:name=".Ft2NsfActivity">

    <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="file" />
        <data android:scheme="content" />
        <data android:host="*" />
        <data android:pathPattern=".*\\.ftm"/>
        <data android:pathPattern=".*\\..*\\.ftm"/>
        <data android:pathPattern=".*\\..*\\..*\\.ftm"/>
        <data android:pathPattern=".*\\..*\\..*\\..*\\.ftm"/>
        <data android:pathPattern=".*\\.0cc"/>
        <data android:pathPattern=".*\\..*\\.0cc"/>
        <data android:pathPattern=".*\\..*\\..*\\.0cc"/>
        <data android:pathPattern=".*\\..*\\..*\\..*\\.0cc"/>
        <data android:mimeType="*/*" />
    </intent-filter>

</activity>
ньянпасу64
источник
1

Если вы хотите, чтобы файлы открывались непосредственно из Gmail, Dropbox или любого из встроенных файловых инструментов Android, используйте следующий код (удалите 'android: host = "*"', из-за которого файл стал недоступен для Gmail):

<intent-filter>
    <action android:name="android.intent.action.VIEW"/>
    <category android:name="android.intent.category.BROWSABLE"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:scheme="content" android:pathPattern=".*\\.kdb" 
          android:mimeType="application/octet-stream"/>


</intent-filter>

<intent-filter>
    <action android:name="android.intent.action.VIEW"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:scheme="file" android:mimeType="*/*"     
          android:pathPattern=".*\\.kdb"/>
</intent-filter>

Фильтр данных должен быть записан одним оператором в соответствии с версией Android 4.x.

АндреасРифф
источник
Я пробовал все, чтобы заставить Android-браузер правильно загружать и открывать. Ваше решение хорошо работает для собственного браузера Android и Chrome для Android, однако Firefox Firefox по-прежнему открывает мой файл в текстовом окне. Это настраиваемый тип mime и настраиваемое расширение. Раньше только с расширением работало только в firefox. Теперь работает везде, кроме firefox (включая gmail). Я все еще тестирую его, но просто хотел отметить тот факт, что здесь есть новый набор кроссбраузерных проблем.
Дэймон Смит
1

Используя фильтр, как показано ниже, для открытия из браузера, Gmail и файлового браузера (проверено). ПРИМЕЧАНИЕ. Не объединяйте два фильтра, иначе браузер проигнорирует ваше приложение (Протестировано).

        <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="file" android:pathPattern=".*\\.ext" android:mimeType="application/*"/>
            <data android:scheme="content" android:pathPattern=".*\\.ext" android:mimeType="application/*"/>
        </intent-filter>

        <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="http"
                  android:host="*"
                  android:pathPattern=".*\\.ext" />
            <data android:scheme="https"
                  android:host="*"
                  android:pathPattern=".*\\.ext" />
            <data android:scheme="ftp"
                  android:host="*"
                  android:pathPattern=".*\\.ext" />

        </intent-filter>
Тран Хиеу
источник
Вы проверяли этот ответ с приложениями Gmail?
Игорь Ганапольский
0

Прочтите https://developer.android.com/training/sharing/receive , это может помочь начать работу. затем в файле манифеста попробуйте фильтр намерений ниже при регистрации получателя в открываемой активности

<intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="content"/>
            <category android:name="android.intent.category.BROWSABLE"/>
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="application/your_extension" />
</intent-filter>

убедитесь, что расширение предоставляется без "." в этом

Суровый
источник