android:pathPattern 用于单个文件

标签 android android-manifest mime-types intentfilter

我需要为名为 myfile.ext 的单个文件定义 IntentFilter。目前我的 list 看起来像:

        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <action android:name="android.intent.action.EDIT" />
            <category android:name="android.intent.category.DEFAULT" />
            <data
                android:scheme="file"
                android:mimeType="*/*"
                android:host="*"
                android:pathPattern=".*\\myfile\\.ext"
            />
        </intent-filter>

我也尝试过其他变体,例如:android:pathPattern=".*\\myfile.ext" 等等 - 但它仍然无法处理我的文件。

有什么线索吗?

最佳答案

Android 模式细节:

  • .匹配任何字符。
  • *匹配其前面字符的 0 次或多次出现。
  • .*匹配任何字符的 0 次或多次出现。
  • \用于转义模式中的特殊字符。 \当从 XML 文件中读取字符串时,也用作转义字符。因此,为了转义模式中的特殊字符,双斜杠 \\必须使用。

问题: 在这种模式中 ".*\\myfile\\.ext" , 你正试图转义字符 m这是一个正常的字符。因此,它没有任何区别。相当于".*myfile\\.ext" . Intent 的数据 uri 部分是 file:///mnt/sdcard/tmp/myfile.ext .该模式与 /mnt/sdcard/tmp/myfile.ext 匹配,但它失败了。

.*尝试匹配任何字符,直到第一次出现 m ,恰好是第二个字符,即 /mnt . 模式期望下一个字符为 y , 但它得到 n因此模式匹配失败。

解决方案: 对于上述路径,模式 /.*/.*/.*/myfile\\.ext有效。

对于 /mnt/sdcard/myfile.ext路径、图案 /.*/.*/myfile\\.ext作品。如果您不确定子目录级别,则必须添加多个 <data>不同的元素 pathPattern值(value)观。

<data
    android:scheme="file"
    android:mimeType="*/*"
    android:host="*" />

<data android:pathPattern="/.*/.*/.*/myfile\\.ext" /> <!-- matches file:///mnt/sdcard/tmp/myfile.ext -->

<data android:pathPattern="/.*/.*/myfile\\.ext" /> <!-- matches file:///mnt/sdcard/myfile.ext -->

这是 PatternMatcher.matchPattern用于模式匹配的方法:

   static boolean matchPattern(String pattern, String match, int type) {
        if (match == null) return false;
        if (type == PATTERN_LITERAL) {
            return pattern.equals(match);
        } if (type == PATTERN_PREFIX) {
            return match.startsWith(pattern);
        } else if (type != PATTERN_SIMPLE_GLOB) {
            return false;
        }

        final int NP = pattern.length();
        if (NP <= 0) {
            return match.length() <= 0;
        }
        final int NM = match.length();
        int ip = 0, im = 0;
        char nextChar = pattern.charAt(0);
        while ((ip<NP) && (im<NM)) {
            char c = nextChar;
            ip++;
            nextChar = ip < NP ? pattern.charAt(ip) : 0;
            final boolean escaped = (c == '\\');
            if (escaped) {
                c = nextChar;
                ip++;
                nextChar = ip < NP ? pattern.charAt(ip) : 0;
            }
            if (nextChar == '*') {
                if (!escaped && c == '.') {
                    if (ip >= (NP-1)) {
                        // at the end with a pattern match, so
                        // all is good without checking!
                        return true;
                   }
                    ip++;
                    nextChar = pattern.charAt(ip);
                    // Consume everything until the next character in the
                    // pattern is found.
                    if (nextChar == '\\') {
                        ip++;
                        nextChar = ip < NP ? pattern.charAt(ip) : 0;
                    }
                    do {
                        if (match.charAt(im) == nextChar) {
                            break;
                        }
                        im++;
                    } while (im < NM);
                    if (im == NM) {
                        // Whoops, the next character in the pattern didn't
                        // exist in the match.
                        return false;
                    }
                    ip++;
                    nextChar = ip < NP ? pattern.charAt(ip) : 0;
                    im++;
                } else {
                    // Consume only characters matching the one before '*'.
                    do {
                        if (match.charAt(im) != c) {
                            break;
                        }
                        im++;
                    } while (im < NM);
                    ip++;
                    nextChar = ip < NP ? pattern.charAt(ip) : 0;
                }
            } else {
                if (c != '.' && match.charAt(im) != c) return false;
                im++;
            }
        }

        if (ip >= NP && im >= NM) {
            // Reached the end of both strings, all is good!
            return true;
        }

        // One last check: we may have finished the match string, but still
        // have a '.*' at the end of the pattern, which should still count
        // as a match.
        if (ip == NP-2 && pattern.charAt(ip) == '.'
            && pattern.charAt(ip+1) == '*') {
            return true;
        }

        return false;
    }

关于android:pathPattern 用于单个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25619946/

相关文章:

react-native - 引入闪屏后无法同步gradle,为什么?

android - 使用 Android makefile 构建系统构建 Android 应用程序测试代码时,编译器找不到 AndroidInstrumentationTestCase2

PHP 图像生成器因任何典型原因而失败

node.js - gridfs-stream 总是用 "contentType: binary/octet-stream"存储文件

android - 无法加载库 : dlopen failed: library "libboost.so" not found

android - 我可以在 Android 的 XML 中使用变量吗?

android - 拨出电话无回铃音

android - 如何以正确的方式将 Activity 添加到 manifest.xml?

android - 如何定位特定的 Calabash 功能文件?

email - 如何发送行超过 990 个字符的 csv 附件?