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


92

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

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

але я не міг змусити це працювати.

Відповіді:


119

Ось як я визначив свою активність у своєму 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>

Значок schemeof 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, спрощений намір VIEW транслюється із даними про файл. І цей фільтр намірів не збігається.
olivierg

@Brian Pellin: Я насправді шукав спосіб прив'язати mime-тип до .kdbxрозширення, щоб дозволити ES Explorer-провіднику відкривати файли kdbx, коли мені вказали на цю публікацію. Очевидно, якщо намір має порожній тип MIME, цей фільтр намірів не працюватиме !! Крім того, можна мати намір із ПУСТИМ рядком як дією та просто URI. Документи Google відповіли на цей намір, тому він повинен бути дійсним.
billc.cn

2
Щоб зрозуміти, mimeType має бути "* / *". Я думаю, що деякі люди забули втекти від своїх *
Брайан Пеллін,

1
Це не буде працювати з Android 4. Вам слід використовувати <data>тег із чотирма атрибутами. Наявність 4 тегів логічно АБО - що працювало з Android 2 - але Android 4 є більш суворим. Дивіться stackoverflow.com/questions/20650378/…
Мартін

3
якщо \\\\.збігається з буквальним періодом, чому ви не використовуєте його для формування .kdbрозширення таким чином \\\\.kdb:?
Леало

34

На цю тему є багато дезінформації, не в останню чергу з власної документації Google. Найкраща, і враховуючи дивну логіку, можливо, єдиною справжньою документацією є вихідний код.

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

Наступні фільтри наближаються до розумної поведінки. Шаблони шляхів дійсно застосовуються для намірів схеми "файл".

Глобальна відповідність шаблону типу mime буде відповідати всім типам, доки розширення файлу відповідає. Це не ідеально, але це єдиний спосіб відповідати поведінці файлових менеджерів, таких як ES File Explorer, і він обмежений намірами, де URI / розширення файлу відповідає.

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

Дивною схемою є "вміст", для якого розширення недоступне для фільтра. Але поки постачальник вказує ваш тип MIME (наприклад, Gmail передаватиме тип MIME для вкладення безперешкодно), фільтр буде відповідати.

Потрібно знати:

  1. Пам’ятайте, що у фільтрах ніщо не поводиться послідовно, це лабіринт футлярів із специфікою і розглядає порушення принципу найменшого здивування як ціль дизайну. Жоден з алгоритмів узгодження шаблонів не дотримується однакового синтаксису чи поведінки. Відсутність поля іноді є підстановкою, а іноді ні. Атрибути в елементі даних іноді повинні поєднуватися, а іноді ігнорувати групування. Це справді могло бути зроблено краще.
  2. Схема І хост повинні бути вказані, щоб правила шляху збігалися (всупереч керівництву API Google, наразі).
  3. Принаймні ES File Explorer генерує наміри з типом MIME "", який фільтрується зовсім інакше, як нульовий, неможливо однозначно зіставити, і він може відповідати лише ризикованому фільтру "* / *".
  4. Фільтр "* / *" НЕ буде відповідати Intents із нульовим типом MIME - для цього потрібен окремий фільтр для цього конкретного випадку, що взагалі не має типу MIME.
  5. Схемі "вмісту" можна порівняти лише за типом MIME, оскільки оригінальне ім'я файлу недоступне у намірі (принаймні в Gmail).
  6. Групування атрибутів в окремих елементах "даних" (майже) не має значення для інтерпретації, за винятком хоста та порту, які поєднуються. Все інше не має конкретної асоціації в елементі "дані" або між елементами "дані".

З огляду на все це, ось приклад із коментарями:

<!--
     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 cha, такими як ".gblorb", що мій код чудово працює з 3 буквами або менше?
RoundSparrow hilltx

На мою думку, найкраща відповідь на це та подібні запитання! На жаль, поки неможливо зіставити наміри вмісту за розширенням файлу (як ви вказуєте в п. 5.), неможливо надійно відфільтрувати ВСІ правильні наміри, не збігаючи також неправильні. Це для випадку, коли ви не можете використовувати власний тип mime. Отож, поки Android не надає рішення для цього, для мене це буде програма вибору файлів у програмі ... Я не хочу плутати користувача непослідовною поведінкою.
Benjamin Bisinger

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 все ще відмовляється правильно відкривати файл, і я також помітив, що піктограма програми не використовується для файлів. Знову ж таки, якщо хтось змусить це працювати, будь ласка, коментуйте нижче.

Сподіваюся, це вам стане в нагоді, і вам не доведеться витрачати дні, переглядаючи всі можливі комбінації. Є місце для вдосконалення, тому коментарі вітаються.


Це робоче рішення для мене. Реєстрація окремого <intent-filter> для Content-Scheme і File-Scheme зробила трюк! Дякую!
Мехліфікація

Дякую! Працював у мене. Як додаток Gmail, так і додаток Samsung My Files на Galaxy S6 змогли відкрити файл із моїм додатком за допомогою вашого рішення!
Харіс,

Що саме таке "назва програми?" (У моєму випадку в
зручній

@WilliamJockusch схоже, що @DavidSainty просто зберігає ім'я програми у файлі рядкового ресурсу. Місця повинні бути в порядку. Рядок, який використовується для android:labelфільтра намірів - це рядок, який користувач побачить у меню вибору. За замовчуванням використовується назва програми.
omahena

Що слід використовувати для програми "Google Drive"?
розробник android

9

Відповідь Брайана вище привела мене до 90% шляху. Щоб закінчити це, для mime-типу я використовував

android:mimeType="*/*"

Я підозрюю, що попередні плакати намагалися розмістити ту саму деталь, але при достатньому цитуванні зірки косою зіркою як коду, stackoverflow відображає це просто як скісну риску.


2
Завдяки цьому ви будете обробляти ВСІ типи файлів, і це справді дратує (ну, крім випадків, якщо ваш додаток справді все обробляє) ...
Тім Аутін

Це погано. Не робіть цього всередині своїх додатків.
Марс,

8

Замість того, щоб android:pathспробувати android:mimeType, зі значенням типу MIME цього конкретного вмісту. Крім того, android:pathне приймає символи підстановки - використовуйте android:pathPatternдля цього.


"Тип файлу не входить до міметипів"? Для типу вмісту, який ви завантажуєте, все одно має бути тип mimeype, навіть якщо в ньому не використовується те саме слово.
Ерік Мілл

Існує тип mimeype для типу вмісту, але файл створюється стороннім додатком, який додає інше розширення, тому я не думаю, що він буде визнаний таким mimetype.
Curyous

7

Я намагався змусити це працювати впродовж століть і в основному спробував усі запропоновані рішення, і все ще не можу змусити Android розпізнавати конкретні розширення файлів. У мене є фільтр намірів із"*/*" mimeype, який єдине, що, здається, працює, і браузери файлів тепер перелічують мою програму як опцію для відкриття файлів, однак моя програма тепер відображається як опція для відкриття БУДЬ-ЯКОГО ВИДУ файлу, хоча Я вказав конкретні розширення файлів, використовуючи тег pathPattern. Це заходить так далеко, що навіть коли я намагаюся переглянути / відредагувати контакт у своєму списку контактів, Android запитує мене, чи хочу я використовувати свою програму для перегляду контакту, і це лише одна з багатьох ситуацій, коли це трапляється, ДУЖЕ ДУЖО дратує.

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

Отже, від того, що я бачив, пробував і читав, Android просто не може розрізнити розширення файлів, а тег pathPattern - це в основному гігантська втрата часу та енергії. Якщо вам пощастило, що вам потрібні лише файли певного типу mime (скажімо, текст, відео чи аудіо), ви можете використовувати фільтр намірів із mime-типом. Якщо вам потрібно конкретне розширення файлу або тип mime, не відомий Android, проте вам не пощастило.

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

Я міг би написати ще одну сторінку чи дві про те, наскільки подібні речі, здається, є в Android, і про те, наскільки заплутаний досвід розробників, але я врятую вам свої гнівні сказки;). Сподіваюся, я врятував комусь якусь біду.


1
Проголосував за вас, тому що ваша відповідь дає корисне посилання, а голос проти не залишив коментар. Вибачте, ТО може часом бути недружнім таким чином, але не кидайте на цьому.
Джон Хаттон,

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 = " / " його оригінальний приклад ідеальний.
Nick

Цей допис, якщо давно, але жодного "/" не встановлюється. Вам потрібно "* / *", який відповідатиме будь-якому типу файлу (не впевнений, якщо ви мали намір сказати це). Тож вашу програму можуть попросити відкрити відео або mp3-файли. Я ще не знайшов рішення цього.
Рене

Ви повинні використовувати один <data>тег із чотирма атрибутами. Ваше рішення може працювати з Android 2 - але правила стали більш суворими: stackoverflow.com/questions/20650378/…
Мартін,

Що з дивним шляхомPattern ? І hostі schemeпотрібні!
ІгорГанапольський

3

На Android 4 правила стали більш суворими, ніж були раніше. Використання:

    <data
      android:host=""
      android:mimeType="*/*"
      android:pathPattern=".*\\.ext"
      android:scheme="file"
    ></data>

3

Я сам боровся з цим досить багато для власного розширення файлу. Після довгих пошуків я знайшов цю веб-сторінку, де плакат виявив, що клас patternMatcher Android (який використовується для відповідності pathPattern у Intent-Filters) має несподівану поведінку, коли ваш шлях містить перший символ шаблону збігу в іншому місці шляху (наприклад, якщо ви намагаєтеся зіставити "* .xyz", клас patternMatcher зупиняється, якщо на вашому шляху раніше було "x"). Ось що він знайшов для обхідного шляху і працював у мене, хоча це трохи хак:

PatternMatcher використовується для pathPattern в IntentFilter, але алгоритм PatternMatcher для мене досить дивний. Ось алгоритм Android PatternMatcher.

Якщо в середині рядка є "наступний символ" шаблону ". *", PatternMatcher зупиняє цикл у цій точці. (Див. PatternMatcher.java платформи Android.)

Напр. рядок: "це мій вкладення" шаблон: ". att. ". Вхідний цикл Android PatternMatcher для відповідності '. 'pattern до зустрічі наступного символу шаблону (у цьому прикладі,' a ') Отже,'. 'цикл узгодження зупиняється на індексі 8 -' a 'між' є 'та' мій '. Тому результат цього збігу повертає 'false'.

Цілком дивно, чи не так. Щоб обійти це - насправді зменшити можливість - розробник повинен використовувати надокучливий дурний pathPattern.

Напр. Мета: відповідність шляху 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

Жодне з вищезазначеного не працює належним чином для дій ПЕРЕГЛЯНУТИ або НАДІСЛАТИ, якщо суфікс не зареєстровано з типом MIME у системі Android = широка база даних MIME. Єдині налаштування, які я виявив, включають пожежу для вказаного суфіксу 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/ - це програма, призначена для прийому всіх намірів і дозволяє перевірити наміри. Я довідався, що нерозпізнані розширення файлів, відкриті через Простий менеджер файлів, постачаються із типом 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>

1

Якщо ви хочете, щоб файли відкривалися безпосередньо з Gmail, dropbox або будь-якого з інструментів файлів buildin 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 все ще відкриває мій файл у текстовому вікні. Це власний тип 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?
Ігор Ганапольський

1

Оновлення 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, і додав їх до мого фільтра намірів.

Застереження / Gotchas

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

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

Заключні думки

  • В даний час не існує елегантного рішення для пов’язання вашої програми з певним типом розширення в Android. Це було найкраще, що я міг зробити в моїй ситуації.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.