pathPattern to match file extension does not work if a period exists elsewhere in the file name?
Asked Answered
H

3

42

I see numerous examples of using pathPattern to define an intent-filter for a specific file extension/type; for example, pathPattern=".*\\.xyz".

Unfortunately, this does not appear to work properly if the file in question has a period elsewhere in the path; for example "my.filename.xyz".

Is there a pathPattern syntax that will match both "myfilename.xyz" and "my.filename.xyz"?

Hesterhesther answered 3/8, 2010 at 19:28 Comment(0)
O
46

The android team chose an unfortunate way to implement pathPattern. You can take a look at how the pattern matching is implemented in the android.os.PatternMatch class:

https://github.com/android/platform_frameworks_base/blob/master/core/java/android/os/PatternMatcher.java

We're used to .* working like it does in a regular expression, where the * match is greedy and will match as many characters as possible. In PatterMatch's implementation, the match is not greedy. The .* will match as many characters as it can, until it finds a match for the next character in the string.

Example:

String: "/mnt/my.file.mytype"
pathPattern: ".*\\.mytype"

The ".*" in the pathPattern will match the substring "/mnt/my", and hence will fail to match the string.

Given this limitation, I don't see a way to write a pathPattern that can match any string that ends in ".mytype". The best you can do is follow Jason's solution to add additional patterns to match paths with as many dots as you are willing to specify patterns.

Odisodium answered 22/12, 2011 at 5:53 Comment(0)
T
50

Ran into the same problem trying to open a file in a dot folder. I found I could just add multiple "data" elements, depending on how many dots I expected to have in my paths:

<data android:pathPattern=".*\\.mytype"/>
<data android:pathPattern=".*\\..*\\.mytype"/>
<data android:pathPattern=".*\\..*\\..*\\.mytype"/>
<data android:pathPattern=".*\\..*\\..*\\..*\\.mytype"/>

Ugly, though. Anyone know a better way?

Tuantuareg answered 6/1, 2011 at 23:56 Comment(5)
Well.. it doesn't matter if a cat is black or white, so long as it catches mice. Thanks for this!Prolongate
How about <data android:pathPattern="[.*\\.]+mytype"/>? Will this work? If it works exactly like a regex then maybe this might work too: <data android:pathPattern="\\.mytype$"/>?Nobe
even if it works, it's not documented (-> not supported), therefore we are stuck with Jason's solution... (kudos!)Franchescafranchise
Why do you need double slashes in the pattern?Margret
Many thanks, not a fan of brute force approaches in general but this likewise was the only way to solve a similar issue we ran into.Nez
O
46

The android team chose an unfortunate way to implement pathPattern. You can take a look at how the pattern matching is implemented in the android.os.PatternMatch class:

https://github.com/android/platform_frameworks_base/blob/master/core/java/android/os/PatternMatcher.java

We're used to .* working like it does in a regular expression, where the * match is greedy and will match as many characters as possible. In PatterMatch's implementation, the match is not greedy. The .* will match as many characters as it can, until it finds a match for the next character in the string.

Example:

String: "/mnt/my.file.mytype"
pathPattern: ".*\\.mytype"

The ".*" in the pathPattern will match the substring "/mnt/my", and hence will fail to match the string.

Given this limitation, I don't see a way to write a pathPattern that can match any string that ends in ".mytype". The best you can do is follow Jason's solution to add additional patterns to match paths with as many dots as you are willing to specify patterns.

Odisodium answered 22/12, 2011 at 5:53 Comment(0)
E
6

I used this:

<activity
   android:name=".activity.GifActivity"
   android:label="Cool Player ^_^">
   <intent-filter>
       <action android:name="android.intent.action.VIEW" />
       <category android:name="android.intent.category.DEFAULT" />
       <data android:scheme="http"/>
       <data android:scheme="https" />
       <data android:host="*"/>
       <data android:pathPattern="/.*\\.mp4"/>
   </intent-filter>
</activity>

This will open up following url:

Will not open up for the following:

I think the key here is host="*". I haven't done thorough study on this. But it works for me, hope it helps someone out there too.

Epiphenomenon answered 29/10, 2015 at 6:41 Comment(3)
I tried to match umaplay.com/2322-tingo_fuse-odg-mp3 using "/.*-mp3" but it doesn't seem to match. Is there something I am missing?Fieldfare
I figured it out by step debugging the pattern matcher. The first "-" as in "-tingo" makes it fail. Luckily, I know there are going to be only 3 hypens so my solution became "/.*-.*-.*-mp3"Fieldfare
What's the purpose of the first forward slash?Margret

© 2022 - 2024 — McMap. All rights reserved.