如何解决Android 如何打开基于 Chrome 意图的 URI
从 Chrome docs,我了解到可以使用以下 URI 打开应用
intent:
HOST/URI-path // Optional host
#Intent;
package=\[string\];
action=\[string\];
category=\[string\];
component=\[string\];
scheme=\[string\];
end;
我想知道是否可以从我的应用打开这个 URI。
示例 URI
intent:
//qr/json/%7B%22u%22%3A%22https%3A%2F%2Fprivacybydesign.foundation%2Fbackend%2Firma%2Fsession%2FvsRjkZF2B2H17sBWmVZe%22%2C%22irmaqr%22%3A%22disclosing%22%7D
#Intent;
package=org.irmacard.cardemu;
scheme=cardemu;
l.timestamp=1620907855707;
S.browser_fallback_url=https%3A%2F%2Fplay.google.com%2Fstore%2Fapps%2Fdetails%3Fid%3Dorg.irmacard.cardemu
;end
因为它看起来像一个普通的 URI,所以我想我可以这样打开它:
Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("%EXAMPLE_URI%"));
startActivity(intent);
这给了我一个 ActivityNotFoundException
。我错过了什么?
引起:android.content.ActivityNotFoundException:没有找到处理意图的活动{ act=android.intent.action.VIEW dat=intent://qr/json/{"u":"https://privacybydesign.基金会/后端/irma/session/vsRjkZF2B2H17sBWmVZe","irmaqr":"disclosure"} pkg=org.irmacard.cardemu(有额外的)}
解决方法
Chrome docs 中描述的“意图:”语法用于从网页启动应用,Chrome 将处理 href
并检索参数以启动应用通过 Android Intent。
您提供的示例 URI 的方案是 intent://
,默认情况下不处理。
如果要处理 intent://
URI,则需要 create a deep link
如果您想从您的 Android 应用打开网页,您可以使用 ACTION_VIEW 操作并在 Intent 数据中指定网址。
public void openWebPage(String url) {
Uri webpage = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW,webpage);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
// example
// openWebPage("https://privacybydesign.foundation/backend/irma/session/vsRjkZF2B2H17sBWmVZe")
关于Intents and Intent Filters 的更多信息
,您可以尝试以下几件事:
1.确保您要启动的应用程序实现了正确的意图。
<application android:label="@string/app_name">
...
<activity android:name=".PleaseStartThisActivity" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
</intent-filter>
</activity>
...
</application>
2.始终使用新意图,切勿重复使用旧意图。
Intent intent = new Intent(android.content.Intent.ACTION_VIEW); //OK.
// Intent intent = getIntent(); //Not OK.
3.把其他一切都做好。
// If package name and activity are known.
intent.setComponent(new ComponentName("org.irmacard.cardemu","org.irmacard.cardemu.PleaseStartThisActivity"));
// Else
// intent = new Intent(android.content.Intent.ACTION_GET_CONTENT);
// intent.setDataAndType(Uri.parse("file://" + filePath),"text/plain");
4.设置或添加标志可能会有所帮助
intent.setFlags(
android.content.Intent.FLAG_ACTIVITY_FORWARD_RESULT |
android.content.Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP |
android.content.Intent.FLAG_INCLUDE_STOPPED_PACKAGES |
android.content.Intent.FLAG_RECEIVER_FOREGROUND |
android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION |
android.content.Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION |
android.content.Intent.FLAG_GRANT_PREFIX_URI_PERMISSION |
android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION |
android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5.现在您可以安全地开始活动了。
startActivity(intent);
// Or this:
// startActivity(android.content.Intent.createChooser(intent,null));
编辑
* intent.getDataString() - To get intent data (You may have to parse it to get the package name).
* getPackageManager().queryIntentActivities() - To check available activities for that package like the following example:
private final String getActivity(final String packageName,final Intent intent,final Bundle bundle,final String mimeType) {
final String activity;
int activityLen = 0;
final int packageLen = packageName.length();
if(bundle != null && (activity = bundle.getString("activity")) != null) {
activityLen = activity.length();
} else {
activity = null;
}
final List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent,PackageManager.GET_RESOLVED_FILTER);
for(ResolveInfo ri : list) {
final IntentFilter filter = ri.filter;
final String activityName = ri.activityInfo.name;
//Make sure the activity is valid and exist for the package.
//Tolerate with case insensitive
if(activity != null && activity.regionMatches(true,activityName,activityLen)
&& packageName.regionMatches(true,ri.activityInfo.packageName,packageLen)) {
return activityName;
} else if(filter == null) {
Toast.makeText(this,"ERROR: No available ACTIONS to handle this file",1).show();
return null;
//Auto search only if user hasn't specified the activity,else return null. Tolerate with case insensitive
} else if(activity == null && filter.hasAction(intent.getAction()) && filter.hasDataType(mimeType)) {
if(ri.activityInfo.packageName.regionMatches(true,packageName,packageLen)) {
return ri.activityInfo.name;
}
} // Else keep validating next activities
}
if(activity == null) {
Toast.makeText(this,"ERROR: No available ACTIVITIES to open this file",1).show();
} else {
Toast.makeText(this,"ERROR: No such activity found",1).show();
}
return null;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。