Intent anchor syntax description

2019-03-30 03:28发布

I'm trying to use the intent anchor to launch my app as described here. I'm able to get it to launch my app using this syntax,

<a href="intent://#Intent;scheme=http;package=com.example.myapp;end">Launch my app</a>

but I have no idea what many of the various elements mean.

The basic syntax for an intent-based URI is as follows:

intent:

HOST/URI-path // Optional host 
#Intent; 
  package=[string]; 
   action=[string]; 
   category=[string]; 
   component=[string]; 
   scheme=[string]; 
end;
  1. what do each of the segments mean (so I know how I may best use take advantage of them)
  2. how/where can I include any extra data (ie, my own parameters)

2条回答
迷人小祖宗
2楼-- · 2019-03-30 03:43

As at android 28, the API has changed. Here is what the toUri code has been changed to:

public String toUri(@UriFlags int flags) {
    StringBuilder uri = new StringBuilder(128);
    if ((flags&URI_ANDROID_APP_SCHEME) != 0) {
        if (mPackage == null) {
            throw new IllegalArgumentException(
                    "Intent must include an explicit package name to build an android-app: "
                    + this);
        }
        uri.append("android-app://");
        uri.append(mPackage);
        String scheme = null;
        if (mData != null) {
            scheme = mData.getScheme();
            if (scheme != null) {
                uri.append('/');
                uri.append(scheme);
                String authority = mData.getEncodedAuthority();
                if (authority != null) {
                    uri.append('/');
                    uri.append(authority);
                    String path = mData.getEncodedPath();
                    if (path != null) {
                        uri.append(path);
                    }
                    String queryParams = mData.getEncodedQuery();
                    if (queryParams != null) {
                        uri.append('?');
                        uri.append(queryParams);
                    }
                    String fragment = mData.getEncodedFragment();
                    if (fragment != null) {
                        uri.append('#');
                        uri.append(fragment);
                    }
                }
            }
        }
        toUriFragment(uri, null, scheme == null ? Intent.ACTION_MAIN : Intent.ACTION_VIEW,
                mPackage, flags);
        return uri.toString();
    }
    String scheme = null;
    if (mData != null) {
        String data = mData.toString();
        if ((flags&URI_INTENT_SCHEME) != 0) {
            final int N = data.length();
            for (int i=0; i<N; i++) {
                char c = data.charAt(i);
                if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
                        || (c >= '0' && c <= '9') || c == '.' || c == '-' || c == '+') {
                    continue;
                }
                if (c == ':' && i > 0) {
                    // Valid scheme.
                    scheme = data.substring(0, i);
                    uri.append("intent:");
                    data = data.substring(i+1);
                    break;
                }

                // No scheme.
                break;
            }
        }
        uri.append(data);

    } else if ((flags&URI_INTENT_SCHEME) != 0) {
        uri.append("intent:");
    }

    toUriFragment(uri, scheme, Intent.ACTION_VIEW, null, flags);

    return uri.toString();
}

This shows that the chosen answer will no longer work.

Check this answer by David Wasser for a working solution.

查看更多
来,给爷笑一个
3楼-- · 2019-03-30 03:44

Here is the method toUri() from the Intent class:

public String toUri(int flags) {
    StringBuilder uri = new StringBuilder(128);
    String scheme = null;
    if (mData != null) {
        String data = mData.toString();
        if ((flags&URI_INTENT_SCHEME) != 0) {
            final int N = data.length();
            for (int i=0; i<N; i++) {
                char c = data.charAt(i);
                if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
                        || c == '.' || c == '-') {
                    continue;
                }
                if (c == ':' && i > 0) {
                    // Valid scheme.
                    scheme = data.substring(0, i);
                    uri.append("intent:");
                    data = data.substring(i+1);
                    break;
                }
                // No scheme.
                break;
            }
        }
        uri.append(data);
    } else if ((flags&URI_INTENT_SCHEME) != 0) {
        uri.append("intent:");
    }
    uri.append("#Intent;");
    if (scheme != null) {
        uri.append("scheme=").append(scheme).append(';');
    }
    if (mAction != null) {
        uri.append("action=").append(Uri.encode(mAction)).append(';');
    }
    if (mCategories != null) {
        for (String category : mCategories) {
            uri.append("category=").append(Uri.encode(category)).append(';');
        }
    }
    if (mType != null) {
        uri.append("type=").append(Uri.encode(mType, "/")).append(';');
    }
    if (mFlags != 0) {
        uri.append("launchFlags=0x").append(Integer.toHexString(mFlags)).append(';');
    }
    if (mPackage != null) {
        uri.append("package=").append(Uri.encode(mPackage)).append(';');
    }
    if (mComponent != null) {
        uri.append("component=").append(Uri.encode(
                mComponent.flattenToShortString(), "/")).append(';');
    }
    if (mSourceBounds != null) {
        uri.append("sourceBounds=")
                .append(Uri.encode(mSourceBounds.flattenToString()))
                .append(';');
    }
    if (mExtras != null) {
        for (String key : mExtras.keySet()) {
            final Object value = mExtras.get(key);
            char entryType =
                    value instanceof String    ? 'S' :
                    value instanceof Boolean   ? 'B' :
                    value instanceof Byte      ? 'b' :
                    value instanceof Character ? 'c' :
                    value instanceof Double    ? 'd' :
                    value instanceof Float     ? 'f' :
                    value instanceof Integer   ? 'i' :
                    value instanceof Long      ? 'l' :
                    value instanceof Short     ? 's' :
                    '\0';
            if (entryType != '\0') {
                uri.append(entryType);
                uri.append('.');
                uri.append(Uri.encode(key));
                uri.append('=');
                uri.append(Uri.encode(value.toString()));
                uri.append(';');
            }
        }
    }
    uri.append("end");
    return uri.toString();
}

If you can read Java code then it should be pretty clear what is going on here. In any case, extras can be put in the URL and they look something like this:

<type>.<key>=<value>;

where <type> is one of the following:

S = String
B = Boolean
b = Byte
c = Character
d = Double
f = Float
i = Integer
l = Long
s = Short

Here are a few examples:

Launch app:

<a href="intent://#Intent;scheme=http;package=com.example.myapp;end"> 

Launch app with one String extra called "foo" containing the value "bar123":

<a href="intent://#Intent;scheme=http;package=com.example.myapp;S.foo=bar123;end"> 

Launch app with a String extra called "foo" containing the value "bar123" and an Integer extra called "number" containing the value "-567":

<a href="intent://#Intent;scheme=http;package=com.example.myapp;S.foo=bar123;i.number=-567;end"> 
查看更多
登录 后发表回答