如何处理intent://在webView URL上?
我目前正在开发一个webView
的Android应用程序。在某些urls
我需要使用shouldOverrideUrlLoading
方法,这是非常简单的:如何处理intent://在webView URL上?
if(url.startsWith("something")){
//do something
return true;
}
我的问题:
一些URLS
,在谷歌搜索的例子,有以下URL
方案:
intent://en.m.wikipedia.org/wiki/Test_cricket#Intent;scheme=http;package=org.wikipedia;S.browser_fallback_url=https%3A%2F%2Fwww.google.pt%2Fsearchurl%2Fr.html%23app%3Dorg.wikipedia%26pingbase%3Dhttps%3A%2F%2Fwww.google.pt%2F%26url%3Dhttps%3A%2F%2Fen.m.wikipedia.org%2Fwiki%2FTest_cricket;S.android.intent.extra.REFERRER_NAME=https%3A%2F%2Fwww.google.pt;launchFlags=0x8080000;end
我试过使用:
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(browserIntent);
但我得到了一个错误:
10-15 15:18:15.546: W/System.err(29086): android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=intent://en.m.wikipedia.org/wiki/Test_cricket }
我应该如何处理这种URL
方案?
UPDATE:
Intent myIntent = new Intent().parseUri(url, Intent.URI_INTENT_SCHEME);
startActivity(myIntent);
:
继@CommonsWare意见,我已经使用上Intent
parseUri()
创建从URL
一个Intent object
,然后尝试startActivity()
,类似尝试但我仍然得到:
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=http://en.m.wikipedia.org/wiki/Test_cricket flg=0x8080000 pkg=org.wikipedia (has extras) }
我可能得到的指示错误或者我根本无法构建@CommonsWare指定的intent
。有关如何构建Intent
的任何提示?
这个intent url的结构在这里描述https://developer.chrome.com/multidevice/android/intents。
所以我们可以处理它内部的WebView这样的:
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("intent://")) {
try {
Context context = view.getContext();
Intent intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
if (intent != null) {
view.stopLoading();
PackageManager packageManager = context.getPackageManager();
ResolveInfo info = packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (info != null) {
context.startActivity(intent);
} else {
String fallbackUrl = intent.getStringExtra("browser_fallback_url");
view.loadUrl(fallbackUrl);
// or call external broswer
// Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(fallbackUrl));
// context.startActivity(browserIntent);
}
return true;
}
} catch (URISyntaxException e) {
if (GeneralData.DEBUG) {
Log.e(TAG, "Can't resolve intent://", e);
}
}
}
return false;
}
完美!最后一个解决方案 –
我设法解决这个问题的方式不是优雅但它的工作原理。
首先,我们检查,如果网址startsWith
与intent://
和含有scheme=http
,如果是这样,我们之后意图获得的价值://everything until#
并将它传递给Intent.ACTION_VIEW
,如果没有,我们return false
(忽略点击) 。
我测试过与谷歌移动搜索的几个结果,如,叽叽喳喳,Facebook的,谷歌地图和*,它完美地工作这一解决方案。
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if(url.startsWith("intent://") && url.contains("scheme=http")){
url = Uri.decode(url);
String bkpUrl = null;
Pattern regexBkp = Pattern.compile("intent://(.*?)#");
Matcher regexMatcherBkp = regexBkp.matcher(url);
if (regexMatcherBkp.find()) {
bkpUrl = regexMatcherBkp.group(1);
Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://"+bkpUrl));
startActivity(myIntent);
return true;
}else{
return false;
}
}
return false;
}
如果您在一个更好的解决办法,我想听听它。
谢谢大家的支持,特别是CommonsWare。
要么赶上'ActivityNotFoundException'或使用'PackageManager'和'resolveActivity()'调用之前检测到这种情况'startActivity()'。在这种情况下,'Uri'是一个应用程序(*),如果该应用程序没有安装,“Intent”将无法解析。您将需要向用户提供某种错误消息,指出这一事实。 – CommonsWare
@CommonsWare如果点击一个带有'intent:// ...'的链接,一些浏览器(Firefox,Chrome,Opera)成功打开该应用程序,是否有办法将uri转发到默认浏览器并让它处理它呢? –
默认浏览器没有处理它 - *应用程序应该这样做。尽管现在我想到了,但“ACTION_VIEW”可能不是正确的答案。使用'Intent'上的'parseUri()'从URL创建一个'Intent'对象,然后在'Intent'上尝试'startActivity()'。 – CommonsWare