Android Как создать Intent Filter для пользовательского расширения файла, которое НЕ делает его частью выбора для всего, что есть на телефоне

Я видел многочисленные ответы здесь о создании фильтра намерений для пользовательского расширения файла, но ни один из них, кажется, не отвечает на мой вопрос:

У меня есть фильтр намерений, который работает прямо сейчас... когда я просматриваю файл или открываю его из вложения электронной почты, мое приложение появится в списке. Сам файл имеет собственное расширение "tgtp", но в основном это просто файл xml.

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

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

Вот мой текущий фильтр намерений, который использует мое приложение, чтобы открыть все:

<intent-filter>
<action android:name="android.intent.action.VIEW">
<category android:name="android.intent.category.DEFAULT">
<data android:mimetype="*/*">
<data android:pathpattern=".*\\.tgtp"> 
</data></data></category></action></intent-filter>

Заранее благодарю

3 ответа

Единственный способ решить эту проблему - добавить атрибуты scheme и host в ваш фильтр намерений:

<intent-filter>
 <action android:name="android.intent.action.VIEW">
 <category android:name="android.intent.category.DEFAULT">
 <data android:scheme="file">
 <data android:mimetype="*/*">
 <data android:pathpattern=".*\\.tgtp"> 
 </data></data></data></category></action></intent-filter>

Это потому, что в документации говорится, что android:pathPattern работает только в том случае, если определена схема и хост. http://developer.android.com/guide/topics/manifest/data-element.html

Надеюсь, что это поможет.


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

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

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

Ex. string: шаблон "this my attachment": ".att.". Android PatternMatcher вводит цикл для соответствия '.' шаблон, чтобы встретить следующий характер шаблона (в этом примере, 'a') Итак, '.' контур соответствия останавливается с индексом 8 - 'a' между 'is' и 'my'. Поэтому результат этого match возвращает 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.*">
...
</data></data></data></data></data></intent-filter>

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


У меня есть одна и та же проблема, и в моем случае оба других ответа не работают. Ближайший я пришел, когда я совмещаю ответы benjamin и sabadow, и оставляю точку в расширении, так вот так: (я использую свое пользовательское расширение ".trk" )

<!-- For opening/viewing only trk-files: (works in google drive and "File Manager", not gmail) -->
 <intent-filter>
 <action android:name="android.intent.action.VIEW">
 <action android:name="android.intent.action.SEND">
 <action android:name="android.intent.action.SEND_MULTIPLE">
 <action android:name="android.intent.action.SENDTO">
 <category android:name="android.intent.category.DEFAULT">
 <category android:name="android.intent.category.BROWSABLE">
 <data android:scheme="file" android:mimetype="*/*" android:pathpattern=".*trk" android:host="*">
 <data android:scheme="file" android:mimetype="*/*" android:pathpattern=".*t.*trk" android:host="*">
 <data android:scheme="file" android:mimetype="*/*" android:pathpattern=".*t.*t.*trk" android:host="*">
 <data android:scheme="file" android:mimetype="*/*" android:pathpattern=".*t.*t.*t.*trk" android:host="*">
 <data android:scheme="file" android:mimetype="*/*" android:pathpattern=".*t.*t.*t.*t.*trk" android:host="*">
 <data android:scheme="file" android:mimetype="*/*" android:pathpattern=".*t.*t.*t.*t.*t.*trk" android:host="*">
 <data android:scheme="file" android:mimetype="*/*" android:pathpattern=".*t.*t.*t.*t.*t.*t.*trk" android:host="*">
 <data android:scheme="file" android:mimetype="*/*" android:pathpattern=".*t.*t.*t.*t.*t.*t.*t.*trk" android:host="*">
 </data></data></data></data></data></data></data></data></category></category></action></action></action></action></intent-filter> 
 <!-- For catching attachments in Gmail: (also triggers non-trk-files that aren't associated with some other app, but not non-trk-files that already have one of more associations, strangely) -->
 <intent-filter>
 <action android:name="android.intent.action.VIEW">
 <action android:name="android.intent.action.SEND">
 <action android:name="android.intent.action.SEND_MULTIPLE">
 <action android:name="android.intent.action.SENDTO">
 <category android:name="android.intent.category.DEFAULT">
 <category android:name="android.intent.category.BROWSABLE">
 <data android:mimetype="*/*" android:scheme="content">
 </data></category></category></action></action></action></action></intent-filter>
 <!-- For catching share actions from apps: (also triggered by sharing actions for all other file types) -->
 <intent-filter>
 <action android:name="android.intent.action.SEND">
 <category android:name="android.intent.category.DEFAULT">
 <data android:mimetype="application/*">
 </data></category></action></intent-filter>

Это немного длиннее, но вам могут не понадобиться все строки, такие как SENDTO и SEND_MULTIPLE действия. Мне просто нужно, чтобы он работал во всех случаях, когда он мог работать. К сожалению, это также вызывает некоторые, но не все, другие случаи.

licensed under cc by-sa 3.0 with attribution.