Android: связать приложение с настраиваемым типом файла

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

Вот как выглядит мой манифест (обратите внимание, что я не включил в него другие действия, но есть 4 других, у которых нет фильтров намерений).

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/RFtheme" >
    <activity
        android:name=".activity.MainActivity"
        android:screenOrientation="landscape"
        android:windowSoftInputMode="adjustPan" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </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"/>
            <category android:name="android.intent.category.OPENABLE"/>
            <data android:scheme="file"/>
            <data android:mimeType="*/*"/>

            <data android:pathPattern="\\.rfts$"/>
            <data android:host="*"/>
        </intent-filter>
    </activity>

    <provider
        android:name=".model.FileProvider"
        android:authorities="com.rockfordcorp.app3sixty.provider"
        android:enabled="true"
        android:exported="true" >
    </provider>
</application>

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

Когда я пытаюсь открыть вложение .rfts в Gmail, он сообщает мне: "У вас нет приложения, которое может открыть этот файл (.rfts). Попробуйте поискать в Google Play такое, которое может"

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

РЕДАКТИРОВАТЬ успех, но еще не совсем.

Вопросы, предлагаемые в качестве исправлений, неуместны, и причина в том, что требуемая схема на самом деле является "содержимым", а не "файлом".

Действующий фильтр намерений

<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:mimeType="*/*" android:pathPattern=".*\\.rfts"/>
            <data android:scheme="content" android:pathPattern=".*\\.rfts" android:mimeType="application/octet-stream" />
            <!-- <data android:host="*"/> -->
        </intent-filter>

Без android: sceheme = "content" это не работает.

Однако возникает новая проблема. Gmail теперь открывает все типы файлов, которые ранее не были связаны с другим приложением. Например, если бы я попытался открыть файл .rfff, он использовал бы мое приложение. Если вы попытаетесь открыть файл .txt, откроется окно выбора для просмотра Chrome или HTML.

Это близко, но открыть другие типы файлов проблематично. Android: pathPattern явно не влияет на тип файла, с которым связано мое приложение.

Поскольку этот вопрос был отмечен как возможный дубликат, я хочу указать, что предлагаемое решение не работает для открытия файла из g-mail, а не из Интернета, а также не распространяется на открытие настраиваемого тип файла. Использование этого «решения» с замененным типом файла приводит к тому, что g-mail продолжает настаивать на том, что на устройстве нет приложения, способного открыть этот тип файла.

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


person Magic Marbles    schedule 15.12.2015    source источник
comment
Я считаю, что ответ на этот вопрос направит вас на правильный путь: stackoverflow.com/questions/1733195/   -  person alzee    schedule 16.12.2015
comment
Возможный дубликат фильтра намерений Android: связать приложение с расширением файла   -  person Tristan Wiley    schedule 16.12.2015
comment
Обратите внимание, что предлагаемый вами вопрос - дубликат для открытия из сети, а мой - для открытия из Gmail. Решение этого вопроса не помогло.   -  person Magic Marbles    schedule 17.12.2015
comment
Также обратите внимание, что я не открываю установленный тип файла из браузера. Оказывается, для связывания приложения с типами файлов, открываемых через Gmail, требуется совершенно другое решение. Я обновил свой вопрос, чтобы отразить это.   -  person Magic Marbles    schedule 18.12.2015
comment
привет @MagicMarbles, я тоже застрял в той же проблеме. Скажите, пожалуйста, есть ли у вас какое-нибудь решение?   -  person karanatwal.github.io    schedule 16.12.2016
comment
Боюсь, что нет, Android продолжал связывать с моим приложением всевозможные типы файлов, поэтому я отказался от этого и пошел в другом направлении.   -  person Magic Marbles    schedule 18.12.2016


Ответы (1)


Обновление 2020

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

Проблема

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

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

Gmail -> content://com.google.android.gm.sapi/[email protected]/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:scheme="file".

  • Я тестировал это на Samsung Galaxy S10 на Android 10.

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

  • В настоящее время нет элегантного решения для связывания вашего приложения с определенным типом расширения в Android. Это было лучшее, что я мог сделать в своей ситуации.
person alexander antaya    schedule 20.04.2020