Search code examples
androidwebview

How to handle intent:// on a webView URL?


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?


Solution

  • 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;
    }