I'm currently developing an android app with a webView
. On some urls
I need to use the shouldOverrideUrlLoading
method, which is pretty straight forward :
if(url.startsWith("something")){
//do something
return true;
}
My problem:
Some URLS
, on google search for example, have the following URL
scheme :
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
I've tried using :
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(browserIntent);
But I got an error:
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 }
How should I handle this kind of URL
scheme ?
UPDATE:
Following @CommonsWare comments, I've tried using parseUri()
on Intent
to create an Intent object
from the URL
and then try startActivity()
, something like:
Intent myIntent = new Intent().parseUri(url, Intent.URI_INTENT_SCHEME);
startActivity(myIntent);
But I still get :
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) }
I may have got the instructions wrong or I'm simply unable to construct the intent
as @CommonsWare specified. Any tips on how to construct the Intent
?
To open a URL/website you do the following: String url = "http://www.example.com"; Intent i = new Intent(Intent. ACTION_VIEW); i. setData(Uri.
WebView is a view that display web pages inside your application. You can also specify HTML string and can show it inside your application using WebView. WebView makes turns your application to a web application. In order to add WebView to your application, you have to add <WebView> element to your xml layout file.
If you want to override certain methods, you have to create a custom WebView class which extends WebView . Also, when you are inflating the WebView , make sure you are casting it to the correct type which is CustomWebView . CustomWebView webView = (CustomWebView) findViewById(R. id.
webView. setWebViewClient(new WebViewClient(){ public void onPageStarted(WebView view, String url, Bitmap favicon) { super. onPageStarted(view, url, favicon); } public boolean shouldOverrideUrlLoading(WebView view, String url) { webView. postUrl(Base_Url, postData.
Structure of this intent url is described here https://developer.chrome.com/multidevice/android/intents.
So we can handle it in internal WebView like this:
@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; }
The way I managed to solve this isn't elegant but it works.
First we check if the url startsWith
with intent://
and contains scheme=http
, if so, we get the value right after intent://everything until#
and pass it to Intent.ACTION_VIEW
, if not, we return false
(ignore click).
I've tested this solution with several results from google mobile search, such as, twitter, facebook, google maps and wikipedia and it worked flawlessly.
@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; }
If you've a better solution, I would like to hear it.
Thank you all for the support, specially CommonsWare.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With