4

Question:

How can I get my application to open a file and url extension, unconditionally?

I am at my wit's end with setting up my intent-filter as none of it is really making any sense. My end goal is to open up anything that has a path ending in a certain extension. For the sake of an example, let's choose ".riley" as my goal extension.

My Base `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:host="*"
        android:mimeType="*/*"
        android:pathPattern=".*\\.riley" />
</intent-filter>

This currently works to open from file and content.

Issue #1: pathPattern

For starters, it doesn't seem as though the data parameter pathPattern does anything, as I have set:

<data
    android:host="*"
    android:mimeType="*/*"
    android:pathPattern=".*\\.riley" />

.. but I can still open Intents with Uri paths that do not end in ".riley" under the file and content scheme.

A couple example paths that my application opened using this intent-filter are:

Path: /storage/sdcard0/Download/MyApp.apk Path: /messagesByAccount/1

The "Path: " was just my own addition in the log for clarity. The first is from gmail under the file scheme and the second is from gtalk under the content scheme. Given that, I am already confused about how intent-filters work.

The pathPattern is being ignored on file and content schemes.

Issue #2: Opening in a browser

I've tried to get my application to open ".riley" extensions from browsers, however redirecting links don't have a MIME-type, so I removed the mimeType value from the data pattern (I had android:mimeType="*/*" earlier, as the MIME-type isn't consistent) and that allowed me to open from redirecting URLs just fine.

The problem came when I tried to open a direct ".riley" URL from the browser (eg: http://thisisnotarealdomainname.com/myfile.riley) and the option to open from my application was gone. Adding the mimeType value back to my data pattern allowed me to open from a direct URL.

The intent-filter won't let me open both direct and indirect URLs.

Issue #3: scheme

I would like to be able to open from a number of different scheme types (eg: http,file,content), but as soon as I removeschemealtogether, it disqualifies my application from opening thehttpscheme and when I specifyscheme="*", it disqualifies my application from opening ANY scheme. I've also tried adding moredata` patterns, but I get the feeling as though only one is taken into effect, as that doesn't help me at all.

So, specifying http will allow for http, but obviously hasn't allowed either file or content and not specifying the scheme disables http.

I cannot open from all different schemes.

To reiterate, how can I get my application to open a file and url extension, unconditionally, given these complications?

RileyE
  • 10,874
  • 13
  • 63
  • 106

1 Answers1

3

Issue #1: <data android:pathPattern=".*\\.riley" /> is simply invalid. Quoting the documentation:

[pathPattern is] meaningful only if the scheme and host attributes are also specified for the filter.

Issue #2: "however redirecting links don't have a MIME-type" should be incorrect, unless the Web server is seriously broken. An HTTP redirect itself does not have a MIME type, but that should be handled by the browser itself, as until the browser handles the redirection, it has no idea whether the URL points to something that it should handle (e.g., a Web page) or something that should be downloaded. The result of the redirect -- the HTTP 200 OK response -- should have a MIME type. If you are convinced that redirected URLs to downloads do not work, create a sample project demonstrating the error and post it somewhere for review.

Issue #3: "I cannot open from all different schemes." -- use multiple <data> elements with multiple android:scheme attributes, in separate <intent-filter> elements.

For example, the AOSP Music app has:

    <activity android:name="AudioPreview" android:theme="@android:style/Theme.Dialog"
            android:taskAffinity=""
            android:excludeFromRecents="true" android:exported="true" >
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:scheme="file"/>
            <data android:mimeType="audio/*"/>
            <data android:mimeType="application/ogg"/>
            <data android:mimeType="application/x-ogg"/>
            <data android:mimeType="application/itunes"/>
        </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" />
            <data android:mimeType="audio/*"/>
            <data android:mimeType="application/ogg"/>
            <data android:mimeType="application/x-ogg"/>
            <data android:mimeType="application/itunes"/>
        </intent-filter>
        <intent-filter
            android:priority="-1">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="content" />
            <data android:mimeType="audio/*"/>
            <data android:mimeType="application/ogg"/>
            <data android:mimeType="application/x-ogg"/>
            <data android:mimeType="application/itunes"/>
        </intent-filter>
    </activity>

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. In fact, Google rarely uses android:pathPattern. There is one occurrence in the AOSP Calendar app:

        <intent-filter
           android:priority="50">
           <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="www.google.com" android:pathPrefix="/calendar/event" />
           <data android:scheme="https" android:host="www.google.com" android:pathPrefix="/calendar/event" />
           <data android:scheme="http" android:host="www.google.com" android:pathPattern="/calendar/hosted/.*/event" />
           <data android:scheme="https" android:host="www.google.com" android:pathPattern="/calendar/hosted/.*/event" />
        </intent-filter>

But that's pretty much it. Certainly others have tried it -- there are a bunch of questions here on StackOveflow covering its use.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • I hope I can respond cleanly enough in the comments! For issue #1, I will clarify in an edit of my question, when I said "As well as other parameters", I meant that the `data` tag had `scheme` and `host` declared, the same way they were declared in the example above it. Again, I will edit that in. For issue #2, I know one example of a web script that doesn't return a MIME-type is when the web page redirects with Javascript's `window.location`. I can specify a `` `intent-filter` to catch it and verify that the MIME-type is `null`. – RileyE Mar 25 '13 at 23:17
  • As for issue #3, what you've said works wonders and it makes a lot more sense than the documentation did for me. So thank you so much! – RileyE Mar 25 '13 at 23:18
  • Also, the reason that I left out the `scheme` and `host` from my `` snippet was in hopes of cleaning up the question to only show relevant information and making it easier to read through, however, it seems to have had the opposite effect. – RileyE Mar 25 '13 at 23:22
  • @RileyE: "redirects with Javascript's window.location" -- yeah, I am not surprised that this is giving you difficulty, as that's not an HTTP redirection. With respect to issue #1, try to find some open source Android app that uses `pathPattern` (Google Code Search, I miss you so!) and see how it handles it. – CommonsWare Mar 25 '13 at 23:39
  • Google Code Search may be gone, but at least there is still `http://symbolhound.com/`! But I will just have to suffer the loss on the `window.location`. Everything else is working as expected now. So, thank you! – RileyE Mar 25 '13 at 23:42