Webview email link (mailto)

30,628

Solution 1

You have to create a subclass of WebViewClient and override mailto URL loading. Example:

public class MyWebViewClient extends WebViewClient {
  private final WeakReference<Activity> mActivityRef;

  public MyWebViewClient(Activity activity) {
    mActivityRef = new WeakReference<Activity>(activity);
  }

  @Override
  public boolean shouldOverrideUrlLoading(WebView view, String url) {
    if (url.startsWith("mailto:")) {
      final Activity activity = mActivityRef.get();
      if (activity != null) {
        MailTo mt = MailTo.parse(url);
        Intent i = newEmailIntent(activity, mt.getTo(), mt.getSubject(), mt.getBody(), mt.getCc());
        activity.startActivity(i);
        view.reload();
        return true;
      }
    } else {
      view.loadUrl(url);
    }
    return true;
  }

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

Then you have to set this custom WebViewClient to your WabView:

webView.setWebViewClient(new MyWebViewClient(activity);

Solution 2

You should update your's WebViewClient with the following:

@SuppressWarnings("deprecation") 
@Override 
public boolean shouldOverrideUrlLoading(WebView view, String url) {
    proceedUrl(view, Uri.parse(url))
    return true; 
} 

@TargetApi(Build.VERSION_CODES.N)
@Override 
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
    proceedUrl(view, request.getUrl());
    return true; 
}

private void proceedUrl(View view, Uri uri){  
    if (uri.toString().startsWith("mailto:")) {
        startActivity(new Intent(Intent.ACTION_SENDTO, uri));
    } else if (uri.toString().startsWith("tel:")) {
        startActivity(new Intent(Intent.ACTION_DIAL, uri));
    } else { 
        view.loadUrl(uri.toString());
    } 
} 

Solution 3

Note : - After Android Nougat shouldOverrideUrlLoading is Deprecated

You need to use shouldOverrideUrlLoading along with shouldOverrideUrlLoading for better support.

Also, you might want to check if URL have mailto: or tel:, which are used in HTML5 to trigger mail client and phone dial respectively.

A complete solution will look like this now

@SuppressWarnings("deprecation") 
@Override 
public boolean shouldOverrideUrlLoading(WebView view, String url) {
    if (url.startsWith("mailto:")) {  
        //Handle mail Urls 
        startActivity(new Intent(Intent.ACTION_SENDTO, Uri.parse(url)));
    } else if (url.startsWith("tel:")) {
        //Handle telephony Urls 
        startActivity(new Intent(Intent.ACTION_DIAL, Uri.parse(url)));
    } else { 
        view.loadUrl(url);
    } 
    return true; 
} 

@TargetApi(Build.VERSION_CODES.N)
@Override 
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
    final Uri uri = request.getUrl();
    if (uri.toString().startsWith("mailto:")) {
        //Handle mail Urls 
        startActivity(new Intent(Intent.ACTION_SENDTO, uri));
    } else if (uri.toString().startsWith("tel:")) {
        //Handle telephony Urls 
        startActivity(new Intent(Intent.ACTION_DIAL, uri));
    } else { 
        //Handle Web Urls 
        view.loadUrl(uri.toString());
    } 
    return true; 
} 
Share:
30,628
omer341
Author by

omer341

Updated on March 02, 2021

Comments

  • omer341
    omer341 about 3 years

    I have a view and view the site has malito code to send email. When I open the link opens in an error. I want that when I open the link opens Gmail app or another email application. Thanks to all helpers.

    public class teacher extends Activity implements OnClickListener {
        WebView webView;
        final Activity activity = this;    
        @Override
        public void onCreate(Bundle savedInstanceState) {    
            super.onCreate(savedInstanceState);
            this.getWindow().requestFeature(Window.FEATURE_PROGRESS);
            setContentView(R.layout.teacher);
            webView = (WebView) findViewById(R.id.webView145);    
            webView.getSettings().setJavaScriptEnabled(true);           webView.loadUrl("https://dl.dropboxusercontent.com/u/233211/%D7%A8%D7%A9%D7%99%D7%95%D7%9F/iWebKit%20demo/ther.html");    
            webView.setWebChromeClient(new WebChromeClient() {
                public void onProgressChanged(WebView view, int progress) {
                    activity.setTitle("Loading...");
                    activity.setProgress(progress * 100);    
                    if (progress == 100)
                    activity.setTitle(R.string.app_name); 
                }       });    
            webView.setWebViewClient(new WebViewClient() {
                @Override
                public void onReceivedError(WebView view, int errorCode,
                String description, String failingUrl) {
                // Handle the error
                }
                @Override
                public boolean shouldOverrideUrlLoading(WebView view, String url) {
                    view.loadUrl(url);
                    return true;            }           });}
            public void onBackPressed() {    
            if (webView.canGoBack()) {
                webView.goBack();
            } else {
                Intent B = new Intent(this, MainActivity.class);
                startActivity(B);
            }}    
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                switch (keyCode) {
                case KeyEvent.KEYCODE_BACK:
                    if (webView.canGoBack() == true) {
                        webView.goBack();
                    } else {
                        finish();
                }return true;}          }
            return super.onKeyDown(keyCode, event);
        }
        @Override
        public void onClick(View arg0) {
            // TODO Auto-generated method stub
    
        }}
    
  • omer341
    omer341 over 10 years
    I'am can't add this: "webView.setWebViewClient(new WestwingWebViewClient(activity);" to my webview. Because westwingWebViewClient cannot be resolved
  • Tomas Žemaitis
    Tomas Žemaitis over 10 years
    Updated answer. You should set your new created custom WebViewClient, which is MyWebViewClient
  • Glenn85
    Glenn85 about 8 years
    Why the view.loadUrl(url); in the else? Wouldn't it be possible to simply return false; after the if and not have the else?
  • Quentin G.
    Quentin G. over 7 years
    I suggest replacing the last line of "newEmailIntent" with return Intent.createChooser(intent, "THE TITLE OF THE CHOOSER");