Вот как я определил свою активность в своем 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, в целом само по себе не позволяет вам загружать файлы любого типа.
.kdbx
расширению, чтобы позволить файловому проводнику ES открывать файлы kdbx, когда мне указали на этот пост. Очевидно, если намерение имеет пустой тип MIME, этот фильтр намерения не будет работать !! Кроме того, можно иметь намерение с EMPTY строкой в качестве действия и просто URI. Документы Google ответили на это намерение, поэтому оно должно быть действительным.<data>
тег с четырьмя атрибутами. Наличие 4 тегов является логическим ИЛИ - что работало с Android 2, но Android 4 более строгий. См. Stackoverflow.com/questions/20650378/…\\\\.
спички буквального периода, почему вы не используете его , чтобы сформировать.kdb
расширение , как это:\\\\.kdb
?По этой теме много дезинформации, не в последнюю очередь из собственной документации Google. Лучшее и, учитывая странную логику, возможно, единственная реальная документация - это исходный код.
Реализация фильтра намерений имеет логику, которая почти не поддается описанию. Код парсера - еще одна важная часть головоломки.
Следующие фильтры очень близки к разумному поведению. Шаблоны путей действительно применяются для
"file"
целей схемы.Соответствие глобальному шаблону mime-типа будет соответствовать всем типам, если совпадает расширение файла. Это не идеально, но это единственный способ сопоставить поведение файловых менеджеров, таких как ES File Explorer, и он ограничен намерениями, для которых совпадает URI / расширение файла.
Я не включал другие схемы, подобные этой
"http"
, но они, вероятно, будут хорошо работать со всеми этими фильтрами.Странная схема выходит
"content"
, для которой расширение недоступно фильтру. Но до тех пор, пока поставщик указывает ваш тип MIME (например, Gmail будет передавать тип MIME для вложения беспрепятственно), фильтр будет соответствовать.Уловки, о которых следует знать:
scheme
AND (в отличие от руководства Google по API, в настоящее время).host
path
""
, который фильтруется совсем иначеnull
, не может быть сопоставлен явно и может быть сопоставлен только рискованным"*/*"
фильтром."*/*"
Фильтр не будет соответствовать Intents сnull
типом MIME - что требует отдельного фильтра для этого конкретного случая, без типа MIME вообще."content"
Схема может быть согласована только по типу MIME, так как оригинальное имя файла не доступно в намерениях (по крайней мере , с Gmail)."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>
источник
<data android:mimeType="*/*" />
во всех трех вариантах, и это отлично сработало для всех приложений, включая Google Drive и Gmail.Я должен признать, что простая задача открытия вложений из электронных писем и файлов из файловой системы на 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 реагировать только на определенные шаблоны, я буду очень рад узнать, как это сделать.android:host="*"
атрибут.intent-filter
блоки объединить, но я этого не проверял.android:scheme="http"
может использоваться. Обратите внимание, что некоторые браузеры могут испортить работу,android:mimeType
поэтому поэкспериментируйтеandroid:mimeType="*/*"
и проверьте в отладчике, что на самом деле проходит, а затем ужесточите фильтрацию, чтобы не стать тем раздражающим приложением, которое обрабатывает все .intent-filter
было протестировано с приложением Samsung «Мои файлы» на Galaxy S3. FX Explorer по-прежнему отказывается правильно открывать файл, и я также заметил, что значок приложения не используется для файлов. Опять же, если у кого-то это работает, прокомментируйте ниже.Надеюсь, вы найдете это полезным и вам не придется тратить дни на перебор всех возможных комбинаций. Есть возможности для улучшения, поэтому комментарии приветствуются.
источник
android:label
фильтра намерений, - это строка, которую пользователь увидит в меню выбора. По умолчанию используется название приложения.Ответ Брайана, приведенный выше, помог мне на 90%. Чтобы закончить это, для пантомимы я использовал
android:mimeType="*/*"
Я подозреваю, что предыдущие плакаты пытались опубликовать ту же деталь, но без указания косой черты звездочка в качестве кода, stackoverflow отображает ее как просто косую черту.
источник
Вместо того
android:path
, чтобы попробоватьandroid:mimeType
, со значением типа MIME этого конкретного фрагмента содержимого. Такжеandroid:path
не принимает подстановочные знаки - используйтеandroid:pathPattern
для этого.источник
Я пытался заставить это работать целую вечность и пробовал в основном все предлагаемые решения, но до сих пор не могу заставить Android распознавать определенные расширения файлов. У меня есть фильтр намерений с
"*/*"
типом mimetype, который, похоже, работает, и файловые браузеры теперь перечисляют мое приложение как вариант для открытия файлов, однако теперь мое приложение отображается как вариант для открытия ЛЮБОГО ВИДА файла, хотя Я указал определенные расширения файлов с помощью тега pathPattern. Это заходит так далеко, что даже когда я пытаюсь просмотреть / отредактировать контакт в моем списке контактов, Android спрашивает меня, хочу ли я использовать свое приложение для просмотра контакта, и это лишь одна из многих ситуаций, когда это происходит, ОЧЕНЬ ОЧЕНЬ раздражая.В конце концов я нашел это сообщение групп Google с аналогичным вопросом, на который ответил настоящий разработчик фреймворка Android. Она объясняет, что Android просто ничего не знает о расширениях файлов, только о MIME-типах ( https://groups.google.com/forum/#!topic/android-developers/a7qsSl3vQq0 ).
Итак, из того, что я видел, пробовал и читал, Android просто не может отличить расширения файлов, а тег pathPattern - это, по сути, гигантская трата времени и энергии. Если вам повезло, что вам нужны файлы только определенного типа mime (например, текст, видео или аудио), вы можете использовать фильтр намерения с типом mime. Однако если вам нужно конкретное расширение файла или mime-тип, неизвестный Android, вам не повезло.
Если я ошибаюсь в чем-либо из этого, скажите мне, до сих пор я читал все сообщения и пробовал все предлагаемые решения, которые мог найти, но ни одно не сработало.
Я мог бы написать еще одну или две страницы о том, насколько распространены подобные вещи в Android и насколько неприятен опыт разработчиков, но я спасу вас от своих гневных разглагольствований;). Надеюсь, я избавил кого-то от неприятностей.
источник
Обновление 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="*/*"/>
в мой фильтр намерений. Я не мог использовать это, потому что он запускал бы мое приложение всякий раз, когда пользователь щелкал любой файл на своем телефоне (а не только файлы с расширением пользовательского файла). Я бы не рекомендовал добавлять это в ваш фильтр намерений.Последние мысли
источник
Ответ Брайана очень близок, но вот чистый и безошибочный способ вызвать ваше приложение при попытке открыть файл с вашим собственным расширением (нет необходимости в схеме или хосте):
<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>
источник
<data>
тег с четырьмя атрибутами. Ваше решение может работать с Android 2, но правила стали более строгими: stackoverflow.com/questions/20650378/…host
иscheme
требуются!На Android 4 правила стали строже, чем раньше. Использование:
<data android:host="" android:mimeType="*/*" android:pathPattern=".*\\.ext" android:scheme="file" ></data>
источник
Я сам немного боролся с этим для собственного расширения файла. После долгих поисков я нашел эту веб-страницу, где плакат обнаружил, что класс Android patternMatcher (который используется для сопоставления pathPattern в Intent-Filters) имеет неожиданное поведение, когда ваш путь содержит первый символ вашего шаблона сопоставления в другом месте пути (например, если вы пытаетесь сопоставить «* .xyz», класс patternMatcher останавливается, если на вашем пути есть «x»). Вот что он нашел для обходного пути и сработал для меня, хотя это немного похоже на взлом:
<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>
источник
Ничего из вышеперечисленного не работает должным образом для действий VIEW или SEND, если суффикс не зарегистрирован с типом MIME в базе данных MIME system = wide Android. Единственные настройки, которые я обнаружил, срабатывают для указанного суффикса, включают
android:mimeType="*/*"
, но затем действие срабатывает для ВСЕХ файлов. Ясно НЕ то, что вы хотите!Я не могу найти подходящего решения, не добавив mime и суффикс в базу данных mime Android, но пока я не нашел способа сделать это. Если кто знает, указатель был бы потрясающим.
источник
Когда Намерение соответствует 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>
источник
Если вы хотите, чтобы файлы открывались непосредственно из 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.
источник
Используя фильтр, как показано ниже, для открытия из браузера, 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>
источник
Прочтите 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>
убедитесь, что расширение предоставляется без "." в этом
источник