1. 核心代码
一句核心代码: intent.toUri(0)
2. 封装为通用函数
特别是方便于在 Framework 中的加日志调试
private void printAllIntentExtras(Intent intent) {
Log.d("JustDebug", "printAllIntentExtras intent=" + intent);
if (intent == null) {
Log.d("JustDebug", "printAllIntentExtras intent is null");
return;
}
Log.d("JustDebug", "printAllIntentExtras intent uri=" + intent.toUri(0));
}
3.源码分析:
看一下 toUri 的源码
public String toUri(@UriFlags int flags) {
StringBuilder uri = new StringBuilder(128);
if ((flags&URI_ANDROID_APP_SCHEME) != 0) {
...
toUriFragment(uri, null, scheme == null ? Intent.ACTION_MAIN : Intent.ACTION_VIEW,
mPackage, flags);
return uri.toString();
}
if (mData != null) {
String data = mData.toString();
if ((flags&URI_INTENT_SCHEME) != 0) {
...
} else if ((flags&URI_INTENT_SCHEME) != 0) {
uri.append("intent:");
}
toUriFragment(uri, scheme, Intent.ACTION_VIEW, null, flags);
return uri.toString();
}
这里会根据 flags 即 UriFlags, 进行预先的添加
UriFlags的类型有(一般传入0即可):
@IntDef(flag = true, prefix = { "URI_" }, value = {
URI_ALLOW_UNSAFE,
URI_ANDROID_APP_SCHEME,
URI_INTENT_SCHEME,
})
@Retention(RetentionPolicy.SOURCE)
public @interface UriFlags {}
上面的toUri 里的分支,都会调用到 toUriFragment
private void toUriFragment(StringBuilder uri, String scheme, String defAction,
String defPackage, int flags) {
StringBuilder frag = new StringBuilder(128);
toUriInner(frag, scheme, defAction, defPackage, flags);
...
if (frag.length() > 0) {
uri.append("#Intent;");
uri.append(frag);
uri.append("end");
}
}
再调用至 toUriInner, 这里将会详细的打印出来
private void toUriInner(StringBuilder uri, String scheme, String defAction,
String defPackage, int flags) {
if (scheme != null) {
uri.append("scheme=").append(Uri.encode(scheme)).append(';');
}
if (mAction != null && !mAction.equals(defAction)) {
uri.append("action=").append(Uri.encode(mAction)).append(';');
}
if (mCategories != null) {
for (int i=0; i<mCategories.size(); i++) {
uri.append("category=").append(Uri.encode(mCategories.valueAt(i))).append(';');
}
}
if (mType != null) {
uri.append("type=").append(Uri.encode(mType, "/")).append(';');
}
if (mIdentifier != null) {
uri.append("identifier=").append(Uri.encode(mIdentifier, "/")).append(';');
}
if (mFlags != 0) {
uri.append("launchFlags=0x").append(Integer.toHexString(mFlags)).append(';');
}
if (mPackage != null && !mPackage.equals(defPackage)) {
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(';');
}
}
}
}
4 参考:
https://stackoverflow.com/questions/5968896/listing-all-extras-of-an-intent
You can do it in one line of code:
Log.d("intent URI", intent.toUri(0));
It outputs something like:
"#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10a00000
;component=com.mydomain.myapp/.StartActivity;sourceBounds=12%20870%20276%201167; l.profile=0; end"
At the end of this string (the part that I bolded) you can find the list of extras (only one extra in this example).
This is according to the toUri documentation: "The URI contains the Intent's data as the base URI,
with an additional fragment describing the action, categories, type, flags, package, component, and extras."
过时函数:
@Deprecated
public String toURI() {
return toUri(0);
}
网友评论