FileDocCategorySizeDatePackage
Uri.javaAPI DocAndroid 5.1 API75179Thu Mar 12 22:22:10 GMT 2015android.net

Uri

public abstract class Uri extends Object implements Comparable, android.os.Parcelable
Immutable URI reference. A URI reference includes a URI and a fragment, the component of the URI following a '#'. Builds and parses URI references which conform to RFC 2396.

In the interest of performance, this class performs little to no validation. Behavior is undefined for invalid input. This class is very forgiving--in the face of invalid input, it will return garbage rather than throw an exception unless otherwise specified.

Fields Summary
private static final String
LOG
Log tag.
private static final String
NOT_CACHED
NOTE: EMPTY accesses this field during its own initialization, so this field *must* be initialized first, or else EMPTY will see a null value! Placeholder for strings which haven't been cached. This enables us to cache null. We intentionally create a new String instance so we can compare its identity and there is no chance we will confuse it with user data.
public static final Uri
EMPTY
The empty URI, equivalent to "".
private static final int
NOT_FOUND
Index of a component which was not found.
private static final int
NOT_CALCULATED
Placeholder value for an index which hasn't been calculated yet.
private static final String
NOT_HIERARCHICAL
Error message presented when a user tries to treat an opaque URI as hierarchical.
private static final String
DEFAULT_ENCODING
Default encoding.
private static final int
NULL_TYPE_ID
Identifies a null parcelled Uri.
public static final Parcelable.Creator
CREATOR
Reads Uris from Parcels.
private static final char[]
HEX_DIGITS
Constructors Summary
private Uri()
Prevents external subclassing.


            
      
Methods Summary
public abstract android.net.Uri$BuilderbuildUpon()
Constructs a new builder, copying the attributes from this Uri.

public voidcheckFileUriExposed(java.lang.String location)
If this is a {@code file://} Uri, it will be reported to {@link StrictMode}.

hide

        if ("file".equals(getScheme())) {
            StrictMode.onFileUriExposed(location);
        }
    
public intcompareTo(android.net.Uri other)
Compares the string representation of this Uri with that of another.

        return toString().compareTo(other.toString());
    
public static java.lang.Stringdecode(java.lang.String s)
Decodes '%'-escaped octets in the given string using the UTF-8 scheme. Replaces invalid octets with the unicode replacement character ("\\uFFFD").

param
s encoded string to decode
return
the given string with escaped octets decoded, or null if s is null

        if (s == null) {
            return null;
        }
        return UriCodec.decode(s, false, StandardCharsets.UTF_8, false);
    
public static java.lang.Stringencode(java.lang.String s)
Encodes characters in the given string as '%'-escaped octets using the UTF-8 scheme. Leaves letters ("A-Z", "a-z"), numbers ("0-9"), and unreserved characters ("_-!.~'()*") intact. Encodes all other characters.

param
s string to encode
return
an encoded version of s suitable for use as a URI component, or null if s is null


                                                              
         
        return encode(s, null);
    
public static java.lang.Stringencode(java.lang.String s, java.lang.String allow)
Encodes characters in the given string as '%'-escaped octets using the UTF-8 scheme. Leaves letters ("A-Z", "a-z"), numbers ("0-9"), and unreserved characters ("_-!.~'()*") intact. Encodes all other characters with the exception of those specified in the allow argument.

param
s string to encode
param
allow set of additional characters to allow in the encoded form, null if no characters should be skipped
return
an encoded version of s suitable for use as a URI component, or null if s is null

        if (s == null) {
            return null;
        }

        // Lazily-initialized buffers.
        StringBuilder encoded = null;

        int oldLength = s.length();

        // This loop alternates between copying over allowed characters and
        // encoding in chunks. This results in fewer method calls and
        // allocations than encoding one character at a time.
        int current = 0;
        while (current < oldLength) {
            // Start in "copying" mode where we copy over allowed chars.

            // Find the next character which needs to be encoded.
            int nextToEncode = current;
            while (nextToEncode < oldLength
                    && isAllowed(s.charAt(nextToEncode), allow)) {
                nextToEncode++;
            }

            // If there's nothing more to encode...
            if (nextToEncode == oldLength) {
                if (current == 0) {
                    // We didn't need to encode anything!
                    return s;
                } else {
                    // Presumably, we've already done some encoding.
                    encoded.append(s, current, oldLength);
                    return encoded.toString();
                }
            }

            if (encoded == null) {
                encoded = new StringBuilder();
            }

            if (nextToEncode > current) {
                // Append allowed characters leading up to this point.
                encoded.append(s, current, nextToEncode);
            } else {
                // assert nextToEncode == current
            }

            // Switch to "encoding" mode.

            // Find the next allowed character.
            current = nextToEncode;
            int nextAllowed = current + 1;
            while (nextAllowed < oldLength
                    && !isAllowed(s.charAt(nextAllowed), allow)) {
                nextAllowed++;
            }

            // Convert the substring to bytes and encode the bytes as
            // '%'-escaped octets.
            String toEncode = s.substring(current, nextAllowed);
            try {
                byte[] bytes = toEncode.getBytes(DEFAULT_ENCODING);
                int bytesLength = bytes.length;
                for (int i = 0; i < bytesLength; i++) {
                    encoded.append('%");
                    encoded.append(HEX_DIGITS[(bytes[i] & 0xf0) >> 4]);
                    encoded.append(HEX_DIGITS[bytes[i] & 0xf]);
                }
            } catch (UnsupportedEncodingException e) {
                throw new AssertionError(e);
            }

            current = nextAllowed;
        }

        // Encoded could still be null at this point if s is empty.
        return encoded == null ? s : encoded.toString();
    
public booleanequals(java.lang.Object o)
Compares this Uri to another object for equality. Returns true if the encoded string representations of this Uri and the given Uri are equal. Case counts. Paths are not normalized. If one Uri specifies a default port explicitly and the other leaves it implicit, they will not be considered equal.

        if (!(o instanceof Uri)) {
            return false;
        }

        Uri other = (Uri) o;

        return toString().equals(other.toString());
    
public static android.net.UrifromFile(java.io.File file)
Creates a Uri from a file. The URI has the form "file://". Encodes path characters with the exception of '/'.

Example: "file:///tmp/android.txt"

throws
NullPointerException if file is null
return
a Uri for the given file

        if (file == null) {
            throw new NullPointerException("file");
        }

        PathPart path = PathPart.fromDecoded(file.getAbsolutePath());
        return new HierarchicalUri(
                "file", Part.EMPTY, path, Part.NULL, Part.NULL);
    
public static android.net.UrifromParts(java.lang.String scheme, java.lang.String ssp, java.lang.String fragment)
Creates an opaque Uri from the given components. Encodes the ssp which means this method cannot be used to create hierarchical URIs.

param
scheme of the URI
param
ssp scheme-specific-part, everything between the scheme separator (':') and the fragment separator ('#'), which will get encoded
param
fragment fragment, everything after the '#', null if undefined, will get encoded
throws
NullPointerException if scheme or ssp is null
return
Uri composed of the given scheme, ssp, and fragment
see
Builder if you don't want the ssp and fragment to be encoded

        if (scheme == null) {
            throw new NullPointerException("scheme");
        }
        if (ssp == null) {
            throw new NullPointerException("ssp");
        }

        return new OpaqueUri(scheme, Part.fromDecoded(ssp),
                Part.fromDecoded(fragment));
    
public abstract java.lang.StringgetAuthority()
Gets the decoded authority part of this URI. For server addresses, the authority is structured as follows: {@code [ userinfo '@' ] host [ ':' port ]}

Examples: "google.com", "bob@google.com:80"

return
the authority for this URI or null if not present

public booleangetBooleanQueryParameter(java.lang.String key, boolean defaultValue)
Searches the query string for the first value with the given key and interprets it as a boolean value. "false" and "0" are interpreted as false, everything else is interpreted as true.

param
key which will be decoded
param
defaultValue the default value to return if there is no query parameter for key
return
the boolean interpretation of the query parameter key

        String flag = getQueryParameter(key);
        if (flag == null) {
            return defaultValue;
        }
        flag = flag.toLowerCase(Locale.ROOT);
        return (!"false".equals(flag) && !"0".equals(flag));
    
public android.net.UrigetCanonicalUri()
If this {@link Uri} is {@code file://}, then resolve and return its canonical path. Also fixes legacy emulated storage paths so they are usable across user boundaries. Should always be called from the app process before sending elsewhere.

hide

        if ("file".equals(getScheme())) {
            final String canonicalPath;
            try {
                canonicalPath = new File(getPath()).getCanonicalPath();
            } catch (IOException e) {
                return this;
            }

            if (Environment.isExternalStorageEmulated()) {
                final String legacyPath = Environment.getLegacyExternalStorageDirectory()
                        .toString();

                // Splice in user-specific path when legacy path is found
                if (canonicalPath.startsWith(legacyPath)) {
                    return Uri.fromFile(new File(
                            Environment.getExternalStorageDirectory().toString(),
                            canonicalPath.substring(legacyPath.length() + 1)));
                }
            }

            return Uri.fromFile(new File(canonicalPath));
        } else {
            return this;
        }
    
public abstract java.lang.StringgetEncodedAuthority()
Gets the encoded authority part of this URI. For server addresses, the authority is structured as follows: {@code [ userinfo '@' ] host [ ':' port ]}

Examples: "google.com", "bob@google.com:80"

return
the authority for this URI or null if not present

public abstract java.lang.StringgetEncodedFragment()
Gets the encoded fragment part of this URI, everything after the '#'.

return
the encoded fragment or null if there isn't one

public abstract java.lang.StringgetEncodedPath()
Gets the encoded path.

return
the encoded path, or null if this is not a hierarchical URI (like "mailto:nobody@google.com") or the URI is invalid

public abstract java.lang.StringgetEncodedQuery()
Gets the encoded query component from this URI. The query comes after the query separator ('?') and before the fragment separator ('#'). This method would return "q=android" for "http://www.google.com/search?q=android".

return
the encoded query or null if there isn't one

public abstract java.lang.StringgetEncodedSchemeSpecificPart()
Gets the scheme-specific part of this URI, i.e. everything between the scheme separator ':' and the fragment separator '#'. If this is a relative URI, this method returns the entire URI. Leaves escaped octets intact.

Example: "//www.google.com/search?q=android"

return
the decoded scheme-specific-part

public abstract java.lang.StringgetEncodedUserInfo()
Gets the encoded user information from the authority. For example, if the authority is "nobody@google.com", this method will return "nobody".

return
the user info for this URI or null if not present

public abstract java.lang.StringgetFragment()
Gets the decoded fragment part of this URI, everything after the '#'.

return
the decoded fragment or null if there isn't one

public abstract java.lang.StringgetHost()
Gets the encoded host from the authority for this URI. For example, if the authority is "bob@google.com", this method will return "google.com".

return
the host for this URI or null if not present

public abstract java.lang.StringgetLastPathSegment()
Gets the decoded last segment in the path.

return
the decoded last segment or null if the path is empty

public abstract java.lang.StringgetPath()
Gets the decoded path.

return
the decoded path, or null if this is not a hierarchical URI (like "mailto:nobody@google.com") or the URI is invalid

public abstract java.util.ListgetPathSegments()
Gets the decoded path segments.

return
decoded path segments, each without a leading or trailing '/'

public abstract intgetPort()
Gets the port from the authority for this URI. For example, if the authority is "google.com:80", this method will return 80.

return
the port for this URI or -1 if invalid or not present

public abstract java.lang.StringgetQuery()
Gets the decoded query component from this URI. The query comes after the query separator ('?') and before the fragment separator ('#'). This method would return "q=android" for "http://www.google.com/search?q=android".

return
the decoded query or null if there isn't one

public java.lang.StringgetQueryParameter(java.lang.String key)
Searches the query string for the first value with the given key.

Warning: Prior to Ice Cream Sandwich, this decoded the '+' character as '+' rather than ' '.

param
key which will be encoded
throws
UnsupportedOperationException if this isn't a hierarchical URI
throws
NullPointerException if key is null
return
the decoded value or null if no parameter is found

        if (isOpaque()) {
            throw new UnsupportedOperationException(NOT_HIERARCHICAL);
        }
        if (key == null) {
            throw new NullPointerException("key");
        }

        final String query = getEncodedQuery();
        if (query == null) {
            return null;
        }

        final String encodedKey = encode(key, null);
        final int length = query.length();
        int start = 0;
        do {
            int nextAmpersand = query.indexOf('&", start);
            int end = nextAmpersand != -1 ? nextAmpersand : length;

            int separator = query.indexOf('=", start);
            if (separator > end || separator == -1) {
                separator = end;
            }

            if (separator - start == encodedKey.length()
                    && query.regionMatches(start, encodedKey, 0, encodedKey.length())) {
                if (separator == end) {
                    return "";
                } else {
                    String encodedValue = query.substring(separator + 1, end);
                    return UriCodec.decode(encodedValue, true, StandardCharsets.UTF_8, false);
                }
            }

            // Move start to end of name.
            if (nextAmpersand != -1) {
                start = nextAmpersand + 1;
            } else {
                break;
            }
        } while (true);
        return null;
    
public java.util.SetgetQueryParameterNames()
Returns a set of the unique names of all query parameters. Iterating over the set will return the names in order of their first occurrence.

throws
UnsupportedOperationException if this isn't a hierarchical URI
return
a set of decoded names

        if (isOpaque()) {
            throw new UnsupportedOperationException(NOT_HIERARCHICAL);
        }

        String query = getEncodedQuery();
        if (query == null) {
            return Collections.emptySet();
        }

        Set<String> names = new LinkedHashSet<String>();
        int start = 0;
        do {
            int next = query.indexOf('&", start);
            int end = (next == -1) ? query.length() : next;

            int separator = query.indexOf('=", start);
            if (separator > end || separator == -1) {
                separator = end;
            }

            String name = query.substring(start, separator);
            names.add(decode(name));

            // Move start to end of name.
            start = end + 1;
        } while (start < query.length());

        return Collections.unmodifiableSet(names);
    
public java.util.ListgetQueryParameters(java.lang.String key)
Searches the query string for parameter values with the given key.

param
key which will be encoded
throws
UnsupportedOperationException if this isn't a hierarchical URI
throws
NullPointerException if key is null
return
a list of decoded values

        if (isOpaque()) {
            throw new UnsupportedOperationException(NOT_HIERARCHICAL);
        }
        if (key == null) {
          throw new NullPointerException("key");
        }

        String query = getEncodedQuery();
        if (query == null) {
            return Collections.emptyList();
        }

        String encodedKey;
        try {
            encodedKey = URLEncoder.encode(key, DEFAULT_ENCODING);
        } catch (UnsupportedEncodingException e) {
            throw new AssertionError(e);
        }

        ArrayList<String> values = new ArrayList<String>();

        int start = 0;
        do {
            int nextAmpersand = query.indexOf('&", start);
            int end = nextAmpersand != -1 ? nextAmpersand : query.length();

            int separator = query.indexOf('=", start);
            if (separator > end || separator == -1) {
                separator = end;
            }

            if (separator - start == encodedKey.length()
                    && query.regionMatches(start, encodedKey, 0, encodedKey.length())) {
                if (separator == end) {
                  values.add("");
                } else {
                  values.add(decode(query.substring(separator + 1, end)));
                }
            }

            // Move start to end of name.
            if (nextAmpersand != -1) {
                start = nextAmpersand + 1;
            } else {
                break;
            }
        } while (true);

        return Collections.unmodifiableList(values);
    
public abstract java.lang.StringgetScheme()
Gets the scheme of this URI. Example: "http"

return
the scheme or null if this is a relative URI

public abstract java.lang.StringgetSchemeSpecificPart()
Gets the scheme-specific part of this URI, i.e. everything between the scheme separator ':' and the fragment separator '#'. If this is a relative URI, this method returns the entire URI. Decodes escaped octets.

Example: "//www.google.com/search?q=android"

return
the decoded scheme-specific-part

public abstract java.lang.StringgetUserInfo()
Gets the decoded user information from the authority. For example, if the authority is "nobody@google.com", this method will return "nobody".

return
the user info for this URI or null if not present

public inthashCode()
Hashes the encoded string represention of this Uri consistently with {@link #equals(Object)}.

        return toString().hashCode();
    
public booleanisAbsolute()
Returns true if this URI is absolute, i.e. if it contains an explicit scheme.

return
true if this URI is absolute, false if it's relative

        return !isRelative();
    
private static booleanisAllowed(char c, java.lang.String allow)
Returns true if the given character is allowed.

param
c character to check
param
allow characters to allow
return
true if the character is allowed or false if it should be encoded

        return (c >= 'A" && c <= 'Z")
                || (c >= 'a" && c <= 'z")
                || (c >= '0" && c <= '9")
                || "_-!.~'()*".indexOf(c) != NOT_FOUND
                || (allow != null && allow.indexOf(c) != NOT_FOUND);
    
public abstract booleanisHierarchical()
Returns true if this URI is hierarchical like "http://google.com". Absolute URIs are hierarchical if the scheme-specific part starts with a '/'. Relative URIs are always hierarchical.

public booleanisOpaque()
Returns true if this URI is opaque like "mailto:nobody@google.com". The scheme-specific part of an opaque URI cannot start with a '/'.

        return !isHierarchical();
    
public booleanisPathPrefixMatch(android.net.Uri prefix)
Test if this is a path prefix match against the given Uri. Verifies that scheme, authority, and atomic path segments match.

hide

        if (!Objects.equals(getScheme(), prefix.getScheme())) return false;
        if (!Objects.equals(getAuthority(), prefix.getAuthority())) return false;

        List<String> seg = getPathSegments();
        List<String> prefixSeg = prefix.getPathSegments();

        final int prefixSize = prefixSeg.size();
        if (seg.size() < prefixSize) return false;

        for (int i = 0; i < prefixSize; i++) {
            if (!Objects.equals(seg.get(i), prefixSeg.get(i))) {
                return false;
            }
        }

        return true;
    
public abstract booleanisRelative()
Returns true if this URI is relative, i.e. if it doesn't contain an explicit scheme.

return
true if this URI is relative, false if it's absolute

public android.net.UrinormalizeScheme()
Return an equivalent URI with a lowercase scheme component. This aligns the Uri with Android best practices for intent filtering.

For example, "HTTP://www.android.com" becomes "http://www.android.com"

All URIs received from outside Android (such as user input, or external sources like Bluetooth, NFC, or the Internet) should be normalized before they are used to create an Intent.

This method does not validate bad URI's, or 'fix' poorly formatted URI's - so do not use it for input validation. A Uri will always be returned, even if the Uri is badly formatted to begin with and a scheme component cannot be found.

return
normalized Uri (never null)
see
{@link android.content.Intent#setData}
see
{@link #setNormalizedData}

        String scheme = getScheme();
        if (scheme == null) return this;  // give up
        String lowerScheme = scheme.toLowerCase(Locale.ROOT);
        if (scheme.equals(lowerScheme)) return this;  // no change

        return buildUpon().scheme(lowerScheme).build();
    
public static android.net.Uriparse(java.lang.String uriString)
Creates a Uri which parses the given encoded URI string.

param
uriString an RFC 2396-compliant, encoded URI
throws
NullPointerException if uriString is null
return
Uri for this given uri string


                                       
         
        return new StringUri(uriString);
    
public java.lang.StringtoSafeString()
Return a string representation of the URI that is safe to print to logs and other places where PII should be avoided.

hide

        String scheme = getScheme();
        String ssp = getSchemeSpecificPart();
        if (scheme != null) {
            if (scheme.equalsIgnoreCase("tel") || scheme.equalsIgnoreCase("sip")
                    || scheme.equalsIgnoreCase("sms") || scheme.equalsIgnoreCase("smsto")
                    || scheme.equalsIgnoreCase("mailto")) {
                StringBuilder builder = new StringBuilder(64);
                builder.append(scheme);
                builder.append(':");
                if (ssp != null) {
                    for (int i=0; i<ssp.length(); i++) {
                        char c = ssp.charAt(i);
                        if (c == '-" || c == '@" || c == '.") {
                            builder.append(c);
                        } else {
                            builder.append('x");
                        }
                    }
                }
                return builder.toString();
            }
        }
        // Not a sensitive scheme, but let's still be conservative about
        // the data we include -- only the ssp, not the query params or
        // fragment, because those can often have sensitive info.
        StringBuilder builder = new StringBuilder(64);
        if (scheme != null) {
            builder.append(scheme);
            builder.append(':");
        }
        if (ssp != null) {
            builder.append(ssp);
        }
        return builder.toString();
    
public abstract java.lang.StringtoString()
Returns the encoded string representation of this URI. Example: "http://google.com/"

public static android.net.UriwithAppendedPath(android.net.Uri baseUri, java.lang.String pathSegment)
Creates a new Uri by appending an already-encoded path segment to a base Uri.

param
baseUri Uri to append path segment to
param
pathSegment encoded path segment to append
return
a new Uri based on baseUri with the given segment appended to the path
throws
NullPointerException if baseUri is null

        Builder builder = baseUri.buildUpon();
        builder = builder.appendEncodedPath(pathSegment);
        return builder.build();
    
public static voidwriteToParcel(android.os.Parcel out, android.net.Uri uri)
Writes a Uri to a Parcel.

param
out parcel to write to
param
uri to write, can be null


                            
           
        if (uri == null) {
            out.writeInt(NULL_TYPE_ID);
        } else {
            uri.writeToParcel(out, 0);
        }