android:pathPattern for single file

前端 未结 1 1487
暖寄归人
暖寄归人 2021-01-16 01:27

I need to define IntentFilter for single file named myfile.ext. At the moment my manifest looks like:

                 


        
相关标签:
1条回答
  • 2021-01-16 02:08

    Android Pattern specifics :

    • . matches any character.
    • * matches 0 or more occurrences of the character preceding it.
    • .* matches 0 or more occurrences of any character.
    • \ is used to escape special characters in pattern. \ is also used as an escape character when the string is read from the XML file. Hence to escape special character in a pattern, double-slash \\ has to be used.

    Issue: In this pattern ".*\\myfile\\.ext", you are trying to escape character m which is a normal character. Hence it does not make any difference. It is equivalent to ".*myfile\\.ext". The data uri part of intent is file:///mnt/sdcard/tmp/myfile.ext. The pattern is matched against /mnt/sdcard/tmp/myfile.ext, but it fails.

    .* tries to match any character until the first occurrence of m, which happens to be the 2nd char i.e. /mnt. Pattern expects the next char to be y, but it gets n and hence the pattern match fails.

    Solution: For above path, the pattern /.*/.*/.*/myfile\\.ext works.

    For /mnt/sdcard/myfile.ext path, pattern /.*/.*/myfile\\.ext works. If you are not sure the sub-directory level, you will have to add multiple <data> element with different pathPattern values.

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

    Here is the PatternMatcher.matchPattern method used for pattern matching:

       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;
        }
    
    0 讨论(0)
提交回复
热议问题