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

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

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

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

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

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

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

Заранее спасибо

Ответы [ 4 ]

15 голосов
/ 05 марта 2012

Единственный способ решить эту проблему - добавить атрибуты 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 android:host="*" />
</intent-filter>

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

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

3 голосов
/ 25 апреля 2014

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

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

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

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

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

Пример.Цель: сопоставление пути uri, который включает в себя «message».

<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>

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

0 голосов
/ 03 мая 2019

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

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

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

    <data android:host="*" />
    <data android:mimeType="application/octet-stream" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.yourextension" />
    <data android:pathPattern=".*\\..*\\..*\\..*\\.yourextension" />
    <data android:pathPattern=".*\\..*\\..*\\.yourextension" />
    <data android:pathPattern=".*\\..*\\.yourextension" />
    <data android:pathPattern=".*\\.yourextension" />
    <data android:scheme="content" />
</intent-filter>
0 голосов
/ 04 сентября 2014

У меня точно такая же проблема, и в моем случае оба других ответа не работают. Самое близкое, что я получил, - это когда я комбинирую ответы Бенджамина и Сабадоу, и оставляю точку в расширении, вот так: (я использую свое собственное расширение ".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="*" />
        </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" />
        </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/*" />
        </intent-filter>

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...