Android intent filter for a particular file extension?

android intent-filter: associate app with file extension
types of intent in android
android open file intent
android:scheme
what is data in intent-filter
android manifest intent data
what is intent filter verification service
android:mimetype

I want to be able to download a file with a particular extension from the 'net, and have it passed to my application to deal with it, but I haven't been able to figure out the intent filter. The filetype is not included in the mimetypes, and I tried using

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

but I couldn't get that to work.

Here is how I defined my activity in my AndroidManifest.xml to get this to work.

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

The scheme of file indicates that this should happen when a local file is opened (rather than protocol like HTTP).

mimeType can be set to \*/\* to match any mime type.

pathPattern is where you specify what extension you want to match (in this example .kdb). The .* at the beginning matches any squence of characters. These strings require double escaping, so \\\\. matches a literal period. Then, you end with your file extension. One caveat with pathPattern is that .* is not a greedy match like you would expect if this was a regular expression. This pattern will fail to match paths that contain a . before the .kdb. For a more detailed discussion of this issue and a workaround see here

Finally, according to the Android documentation, both host and scheme attributes are required for the pathPattern attribute to work, so just set that to the wildcard to match anything.

Now, if you select a .kdb file in an app like Linda File Manager, my app shows up as an option. I should note that this alone does not allow you to download this filetype in a browser, since this only registers with the file scheme. Having an app like Linda File Manager on your phone resisters itself generically allowing you to download any file type.

Android intent filter: associate app with file extension, When it meets an unknown file extension it appears to form a file URI intent but instead of launching the intent it calls the operating system to find out which apps can accept the intent. If there is only one app that can accept that file URI it then sends an explicit content URI directly to that app. An intent filter is an expression in an app's manifest file that specifies the type of intents that the component would like to receive. For instance, by declaring an intent filter for an activity, you make it possible for other apps to directly start your activity with a certain kind of intent.

There's a lot of misinformation on this topic, not least from Google's own documentation. The best, and given the strange logic, possibly the only real documentation is the source code.

The intent filter implementation has logic that almost defies description. The parser code is the other relevant piece of the puzzle.

The following filters get pretty close to sensible behaviour. The path patterns do apply, for "file" scheme intents.

The global mime type pattern match will match all types so long as the file extension matches. This isn't perfect, but is the only way to match the behaviour of file managers like ES File Explorer, and it is limited to intents where the URI/file extension matches.

I haven't included other schemes like "http" here, but they will probably work fine on all these filters.

The odd scheme out is "content", for which the extension is not available to the filter. But so long as the provider states your MIME type (E.g. Gmail will pass on the MIME type for the attachment unimpeded), the filter will match.

Gotchas to be aware of:

  1. Be aware that nothing behaves consistently in the filters, it's a maze of specal cases, and treats violation of the principle of least surprise as a design goal. None of the pattern matching algorithms follow the same syntax or behaviour. Absence of a field sometimes is a wildcard and sometimes isn't. Attributes within a data element sometimes must go together and sometimes ignore grouping. It really could have been done better.
  2. The scheme AND the host must be specified for path rules to match (contrary to Google's API guide, currently).
  3. At least ES File Explorer generates intents with a MIME type of "", which is filtered very differently to null, is impossible to match explicitly, and can only be matched by the risky "*/*" filter.
  4. The "*/*" filter will NOT match Intents with a null MIME type - that requires a separate filter for this specific case with no MIME type at all.
  5. The "content" scheme can only be matched by MIME type, because the original file name isn't available in the intent (at least with Gmail).
  6. The grouping of attributes in separate "data" elements is (almost) irrelevant to the interpretation, with the specific exception of host and port - which do pair together. Everything else has no specific association within a "data" element or between "data" elements.

With all this in mind, here's an example with comments:

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

Intents and Intent Filters, You can't assign an application to open a specific file extension ( .notes or .md in this case) if the application has no explicit intent filter declared  The file itself has a custom extension of "tgtp", but it is basically just an xml file. The problem I am having is that although this intent filter works, it also appears to add my app to every chooser for every type of file on my phone.

How to assign default app to unlisted file type, android · intentfilter. I'm creating an app that has to appear on the Share menu, but I only want it to appear when the file that is being shared has  Android intent filter for a particular file extension? (8) I want to be able to download a file with a particular extension from the 'net, and have it passed to my application to deal with it, but I haven't been able to figure out the intent filter. The filetype is not included in the mimetypes, and I tried using

Brian's answer above got me 90% of the way there. To finish it off, for mime type I used

android:mimeType="*/*"

I suspect that previous posters have attempted to post the same detail, but the withough qoting the star slash star as code, stackoverflow diplays it as just a slash.

Android SEND action intent filter for a particular file extension?, on an app that registers itself as a handler for a given file extension, let's call it <intent-filter> <action android:name="android.intent.action. You will notice that the action, category, and MIME type are the same in all three <intent-filter> stanzas; only the android:scheme attribute varies. Now, the file scheme for this Music app example will only work if some local file manager attaches the appropriate MIME type to the Intent ; Music does not attempt to use android:pathPattern to match file extensions.

Rather than android:path, try android:mimeType, with a value of the MIME type of this particular piece of content. Also, android:path does not accept wildcards -- use android:pathPattern for that.

Registering Your Android App for File Types and Email Attachments , craziness because of Android limitations in their regex parser. https://​stackoverflow.com/questions/1733195/android-intent-filter-for-a-particular-file-​extension. How do I handle Android IntentFilter ActionView in a Xamarin.Forms-App? Here is my FormsApplicationActivity. IntentFilter is defined to enable the app to open *.gpx files from web-pages or file. The problem is, that whenever a gpx-file opened, OnCreate() is called and a new instance of the app is created, even if the app is already started.

securereader/AndroidManifest.xml at master · guardianproject , Hi, I am trying to associate a file extension with my air app on Android. stackoverflow.com/questions/1733195/android-intent-filter-for-a-particular-file-​extension. Welcome to B4X forum! B4X is a set of simple and powerful cross platform RAD tools: B4A (free) - Android development; B4J (free) - Desktop and Server development; B4i - iOS development

Associate file extension with air app on Android, I expected to be able to do this by specifying an android:mimeType filter for my custom mime type or an android:pathPattern filter for my specific file extension. When an app is created it usually has various intent categories and intent filters for particular file extension(s) that makes android to recognise the capability to open a file extension. If the declared intent filter matches that of a particular file say .pdf then android populates and lists all available applications capable of handling that file type, otherwise if no application contains thie specific intents to open/browse etc the particular file extension (.md or .notes in this case

Is it just me or are intent filters completely broken? : androiddev, I can't seem to get my intent-filter to open both from an http and a content scheme. I have my intent-filter setup to look for a certain file extension (ex: ".riley"), but  Registering Your Android App for File Types and Email Attachments. I’ve recently finished work on an app that registers itself as a handler for a given file extension, let’s call it “.mytype”, so if the user attempts to open a file named “file1.mytype” our app would launch and receive an Intent containing the informati….

Comments
  • This doesn't work here. First with mimeType="", the package doesn't install on Android 2.1, I get a MalformedMimeTypeException. Using "*/" fixes this, but then, this filter has no effect. I am currently testing with the Skyfire browser, which doesn't preserve the mime type of downloads, as the standard Android browser do. And when clicking on a file in the Skyfire downloads list, a simplistic VIEW intent is broadcasted with file data. And this intent filter doesn't match.
  • @Brian Pellin: I was actually searching for a way to bind a mime-type to the .kdbx extension to allow ES file explorer to open kdbx files when I was pointed to this post. Apparently if the intent has an empty MIME type, this intent filter will not work!! Also, it's possible to have an intent with an EMPTY string as the action and just a URI. Google Docs responded to that intent, so it must be valid.
  • Just to be clear, mimeType should be "*/*" I think some people forgot to escape their *s
  • That won't work with Android 4. You should use on <data> tag with four attributes. Having 4 tags is logical OR — Which worked with Android 2 — but Android 4 is more strict. See stackoverflow.com/questions/20650378/…
  • if \\\\. matches a literal period, why does you not use it to form .kdb extension like this: \\\\.kdb?
  • Great that you stand up to the many evidenced need for \\.. over and over and other quirks. Google should have fixed this by 4.2, what the hell. Alas, I still have cases that your example doesn't seem to fix. Is there some issue with 6 cha extensions like ".gblorb" that my code works fine with 3 letters or less?
  • Best answer to this question and similar questions in my opinion! Sadly, as long as it is not possible to match content intents by file extension (as you point out in 5.), it is not possible to reliably filter for ALL correct intents without also matching wrong ones. This is for the case where you can not use a custom mime type. So as long as Android does not provide a solution for this it's going to be a file-chooser within the app for me... I don't want to confuse the user with inconsistent behaviour.
  • Thanks a lot.. You just made my day.. In my case I had to change MimeType as <data android:mimeType="*/*" /> in all three options and it worked like charm for all apps including Google Drive and Gmail.
  • This is a working solution for me. Registering a separate <intent-filter> for Content-Scheme and File-Scheme did the trick! Thanks!
  • Thanks! Worked for me. Both Gmail app and Samsung My Files app on Galaxy S6 were able to open file with my app using your solution!