handling links in a webview
Asked Answered
A

3

38

I have my WebView loading all links inside the webview - but when I select an email link it tries to load it in the webview instead of launching an email app on the phone. How do I resolve that? the links are mailto://[email protected]

Here is my code - the WebView itself works right and everything loads inside the webview, including mailto:, etc. Need the mailto links to load elsewhere

package com.apps.jerdog.crcc;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.WebView;
import android.webkit.WebViewClient;

@SuppressWarnings("unused")
public class mainActivity extends Activity {
    /** Called when the activity is first created. */
    /**@Override */
    WebView webview;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        webview = (WebView) findViewById(R.id.webview);
        webview.getSettings().setJavaScriptEnabled(true);
        webview.getSettings().setSupportZoom(true);
        webview.getSettings().setBuiltInZoomControls(true);
        webview.setWebViewClient(new WebViewClient());
        webview.loadUrl("http://www.cedarridge.cc");
        }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack()) {
            webview.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
    private class myWebViewClient extends WebViewClient {
        public boolean shouldOverrideUrlLoading(WebView view, String url) 
        {
            if (url.startsWith("mailto:") || url.startsWith("tel:")) { 
                    Intent intent = new Intent(Intent.ACTION_VIEW,
                            Uri.parse(url)); 
                    startActivity(intent); 
                    } 
            view.loadUrl(url);
            return true;
        }
    }}
Acicular answered 24/1, 2011 at 23:36 Comment(1)
Try this: https://mcmap.net/q/410531/-mailto-links-unsupported-in-androidPrivity
S
80

I assume you are already overriding shouldOverrideUrlLoading, you just need to handle this special case.

mWebClient = new WebViewClient(){

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if(url.startsWith("mailto:")){
                MailTo mt = MailTo.parse(url);
                Intent i = newEmailIntent(MyActivity.this, mt.getTo(), mt.getSubject(), mt.getBody(), mt.getCc());
                startActivity(i);
                view.reload();
                return true;
            }

                else{
                    view.loadUrl(url);
                }
                return true;
            }
       };
    mWebView.setWebViewClient(mWebClient);

    public static Intent newEmailIntent(Context context, String address, String subject, String body, String cc) {
      Intent intent = new Intent(Intent.ACTION_SEND);
      intent.putExtra(Intent.EXTRA_EMAIL, new String[] { address });
      intent.putExtra(Intent.EXTRA_TEXT, body);
      intent.putExtra(Intent.EXTRA_SUBJECT, subject);
      intent.putExtra(Intent.EXTRA_CC, cc);
      intent.setType("message/rfc822");
      return intent;
}
Steelyard answered 24/1, 2011 at 23:46 Comment(16)
I get "IntentSupport cannot be resolved" on the 'IntentSupport.' statement I also get "Syntax error on token "mWebClient", VariableDeclaratorId expected after this token" on the 'mWebView.setWebViewClient(mWebClient);' code....Acicular
IntentSupport is my own utility class that makes commonly used intents. sorry about that edited with the missing code.Steelyard
still getting the "IntentSupport cannot be resolved" error message and MIME_TYPE_EMAIL is coming up with "MIME_TYPE_EMAIL cannot be resolved to a variable"Acicular
oh geez the mimetype is "message/rfc822"Steelyard
Intent support can't be resolved because you don't have a class named IntentSupport sorry I confused you. I will edit above.Steelyard
I have put my whole code in - hopefully that helps figure out what I need to do.Acicular
you arent using the WebClient you extended, you have webview.setWebViewClient(new WebViewClient()); where is it you are using the webview client you defined below?Steelyard
so I should be using "webview" which I created...? makes sense.... so this (private class myWebViewClient extends WebViewClient) should be (private class myWebViewClient extends webview)?Acicular
when I change (private class myWebViewClient extends WebViewClient) to be (private class myWebViewClient extends webview) it doesn't like it - suggests I set it back to be WebViewClient....Acicular
i am completely a noob to Java - my brain isn't clicking in the transfer from asp.net vb to here....Acicular
take a closer look at my code above, I extend WebViewClient in the same line that I pass it as a parameter to my WebView. This is a common pattern you will see in java.Steelyard
so in my full code in my post - what would I change around? sorry for just completely missing how this worksAcicular
I just told you in my last comment you need to set the proper WebViewClient for your webview. In this case you would use your improperly named myWebViewClient. webview.setWebViewClient(new myWebViewClient());Steelyard
ok - my apologies - I got it now. Thanks so much for your help.Acicular
you can leave out the Context parameter from that function as it is not used at all.Borisborja
view.reload(); is much helpful.Tenorrhaphy
K
9

Going off of the answer provided by @schwiz, here is a cleaner example. Assuming the WebView is named webView:

webView.setWebViewClient(new WebViewClient() {
    // shouldOverrideUrlLoading makes this `WebView` the default handler for URLs inside the app, so that links are not kicked out to other apps.
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        // Use an external email program if the link begins with "mailto:".
        if (url.startsWith("mailto:")) {
            // We use `ACTION_SENDTO` instead of `ACTION_SEND` so that only email programs are launched.
            Intent emailIntent = new Intent(Intent.ACTION_SENDTO);

             // Parse the url and set it as the data for the `Intent`.
            emailIntent.setData(Uri.parse(url));

            // `FLAG_ACTIVITY_NEW_TASK` opens the email program in a new task instead as part of this application.
            emailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            // Make it so.
            startActivity(emailIntent);
            return true;
        } else {  
            // Returning false causes WebView to load the URL while preventing it from adding URL redirects to the WebView history.
            return false;
        }
    }
});

I have tested this with all the mailto: options: multiple email addresses, CC, BCC, subject, and body.

Keeler answered 18/8, 2016 at 0:18 Comment(0)
D
0
::::
::::   

    webViewTerms = (WebView) v
            .findViewById(R.id.webview_termsAndCond);
    webViewTerms.setWebViewClient(new Client());
    webViewTerms.getSettings().setJavaScriptEnabled(true);
    //webViewTerms.getSettings().setBuiltInZoomControls(true);
    webViewTerms.loadUrl(getUrl()); //.loadUrl("https://www.google.com/");
::::
::::
::::
    private class Client extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);

            return true;
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            // TODO Auto-generated method stub
            super.onPageFinished(view, url);


        }

    }
Debrief answered 22/10, 2015 at 6:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.