MailTo在Android WebView中无法工作。

6
我正在处理一个网站的Android Webview,其中包括“联系我们”和“发送电子邮件给朋友”的mailto。 网站端的代码如下:
联系我们:<a href="mailto:contact@example.com">contact@example.com</a> 发送电子邮件给朋友:<a href="mailto:?subject=Check out this product&amp;body=I found this awesome product%20http://www.example.com/product-detail/61/" title="Email to a Friend" class=""><span>Email to a Friend</span></a> 我在Android端的shouldOverrideUrlLoading方法中包含了以下代码片段:
@Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if( url.startsWith("http:") || url.startsWith("https:") ) {
            return false;
        }

        else if (url.startsWith("tel:")) {
            Intent tel = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
            startActivity(tel);
            return true;
        }
        else if(url.startsWith("mailto:")) {
            MailTo mailTo = MailTo.parse(url);
            String emailAddress = mailTo.getTo();
            String subject = mailTo.getSubject();
            String body = mailTo.getBody();
            String cc = mailTo.getCc();
            Intent mail = new Intent(Intent.ACTION_SEND,Uri.parse(url));
            mail.setType("application/octet-stream");
            mail.putExtra(Intent.EXTRA_EMAIL, new String[]{emailAddress});
            mail.putExtra(Intent.EXTRA_SUBJECT, subject);
            mail.putExtra(Intent.EXTRA_TEXT, body);
            mail.putExtra(Intent.EXTRA_CC, cc);
            startActivity(mail);
            return true;
        }
        return false;
    }

这在与联系人一起工作得很好。但是,它在发送电子邮件给朋友时无法正常工作。主题和组成电子邮件字段中有空白,但“收件人”字段中包含必须为空的“/product-detail/105/”。当我在移动浏览器中打开网站时,它可以正常工作。那么,在上述代码中,我需要做什么才能处理此问题?该怎么做才能解决这个问题?


你尝试过这个 mail.setType("message/rfc822"); 吗?如果没有,请尝试使用它来替换 mail.setType("application/octet-stream"); - Sunil Sunny
我已经使用过这个:mail.setType("application/octet-stream");。请参见上面的代码片段。如何处理多个 mailto - Satan Pandeya
我建议你尝试使用 mail.setType("message/rfc822"); - Sunil Sunny
我不知道,但这个不起作用。 - Satan Pandeya
2个回答

19

我通过使用以下内容解决了我的问题:

 public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if (url.startsWith("tel:")) {
            Intent tel = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
            startActivity(tel);
            return true;
        }
        else if (url.contains("mailto:")) {
             view.getContext().startActivity(
                    new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
            return true;

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

1
在我的情况下,不需要单独处理 tel:。这个 view.getContext().startActivity(new Intent("android.intent.action.VIEW", Uri.parse(url))); 可以正确地处理 mailto:tel: - mikep

0

针对Java

public class MainActivity extends AppCompatActivity {
private Context mContext;
private Activity mActivity;

private WebView mWebView;
private TextView mTextView;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Get the application context
    mContext = getApplicationContext();
    mActivity = MainActivity.this;

    // Get the widget reference from xml layout
    mWebView = findViewById(R.id.web_view);
    mTextView = findViewById(R.id.text_view);

    // Toast the current api level
    Toast.makeText(mContext,"API LEVEL: "+Build.VERSION.SDK_INT,Toast.LENGTH_SHORT).show();

    // Set the web view client
    mWebView.setWebViewClient(new WebViewClient(){

        // For api level below 24
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url){
            Toast.makeText(mContext, "Old Method",Toast.LENGTH_SHORT).show();

            if(url.startsWith("http")){
                Toast.makeText(mContext,"Page link",Toast.LENGTH_SHORT).show();
                // Return false means, web view will handle the link
                return false;
            }else if(url.startsWith("mailto")){
                // Handle the mailto link
                handleMailToLink(url);

                // Return true means, leave the current web view and handle the url itself
                return true;
            }

            return false;
        }

        // From api level 24
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request){
            Toast.makeText(mContext, "New Method",Toast.LENGTH_SHORT).show();

            // Get the mailto url
            String url = request.getUrl().toString();

            if(url.startsWith("http")){
                Toast.makeText(mContext,"Page link",Toast.LENGTH_SHORT).show();
                // Return false means, web view will handle the link
                return false;
            }else if(url.startsWith("mailto")){
                // Handle the mailto link
                handleMailToLink(url);

                // Return true means, leave the current web view and handle the url itself
                return true;
            }

            return false;
        }
    });

    // Load the url into web view
    mWebView.loadUrl("http://www.rapidtables.com/web/html/mailto.htm");
}


/*
    Variables in mailto links:
        mailto: recipient, or recipients, separate with comma
        &cc= cc recipient(s)
        &bcc= bcc recipient(s)
        &subject= mail subject
        &body= mail body
*/

// Custom method to handle web view mailto link
protected void handleMailToLink(String url){
    // Initialize a new intent which action is send
    Intent intent = new Intent(Intent.ACTION_SENDTO);

    // For only email app handle this intent
    intent.setData(Uri.parse("mailto:"));

    // Empty the text view
    mTextView.setText("");

    // Extract the email address from mailto url
    String to = url.split("[:?]")[1];
    if(!TextUtils.isEmpty(to)){
        String[] toArray = to.split(";");
        // Put the primary email addresses array into intent
        intent.putExtra(Intent.EXTRA_EMAIL,toArray);
        mTextView.append("TO : " + to);
    }

    // Extract the cc
    if(url.contains("cc=")){
        String cc = url.split("cc=")[1];
        if(!TextUtils.isEmpty(cc)){
            //cc = cc.split("&")[0];
            cc = cc.split("&")[0];
            String[] ccArray = cc.split(";");
            // Put the cc email addresses array into intent
            intent.putExtra(Intent.EXTRA_CC,ccArray);
            mTextView.append("\nCC : " + cc );
        }
    }else {
        mTextView.append("\n" + "No CC");
    }

    // Extract the bcc
    if(url.contains("bcc=")){
        String bcc = url.split("bcc=")[1];
        if(!TextUtils.isEmpty(bcc)){
            //cc = cc.split("&")[0];
            bcc = bcc.split("&")[0];
            String[] bccArray = bcc.split(";");
            // Put the bcc email addresses array into intent
            intent.putExtra(Intent.EXTRA_BCC,bccArray);
            mTextView.append("\nBCC : " + bcc );
        }
    }else {
        mTextView.append("\n" + "No BCC");
    }

    // Extract the subject
    if(url.contains("subject=")){
        String subject = url.split("subject=")[1];
        if(!TextUtils.isEmpty(subject)){
            subject = subject.split("&")[0];
            // Encode the subject
            try{
                subject = URLDecoder.decode(subject,"UTF-8");
            }catch (UnsupportedEncodingException e){
                e.printStackTrace();
            }
            // Put the mail subject into intent
            intent.putExtra(Intent.EXTRA_SUBJECT,subject);
            mTextView.append("\nSUBJECT : " + subject );
        }
    }else {
        mTextView.append("\n" + "No SUBJECT");
    }

    // Extract the body
    if(url.contains("body=")){
        String body = url.split("body=")[1];
        if(!TextUtils.isEmpty(body)){
            body = body.split("&")[0];
            // Encode the body text
            try{
                body = URLDecoder.decode(body,"UTF-8");
            }catch (UnsupportedEncodingException e){
                e.printStackTrace();
            }
            // Put the mail body into intent
            intent.putExtra(Intent.EXTRA_TEXT,body);
            mTextView.append("\nBODY : " + body );
        }
    }else {
        mTextView.append("\n" + "No BODY");
    }

    // Email address not null or empty
    if(!TextUtils.isEmpty(to)){
        if(intent.resolveActivity(getPackageManager())!=null){
            // Finally, open the mail client activity
            startActivity(intent);
        }else {
            Toast.makeText(mContext,"No email client found.",Toast.LENGTH_SHORT).show();
        }
    }

}

}

对于 Kotlin

private var mActivityRef: WeakReference<Activity>? = null
        override fun shouldOverrideUrlLoading(view: WebView?, request: 
         WebResourceRequest?): Boolean {
          //If you have url then you can use that otherwise get url from selected url from website
            if (request!!.url.toString().startsWith("mailto:")) {
                val activity: Activity? = mActivityRef!!.get()
                if (activity != null) {
                    val mt = MailTo.parse(request.url.toString())
                    val i: Intent = newEmailIntent( mt.to, mt.getSubject(), mt.getBody(), mt.getCc() )
                    activity.startActivity(i)
                    view!!.reload()
                    return true
                }
            } else {
                view!!.loadUrl(request.url.toString())
            }
            return true
        }

    }


}
 private fun newEmailIntent(address: String, subject: String, body: String, cc: String): Intent {
    val intent = Intent(Intent.ACTION_SEND)
    intent.putExtra(Intent.EXTRA_EMAIL, arrayOf(address))
    intent.putExtra(Intent.EXTRA_TEXT, body)
    intent.putExtra(Intent.EXTRA_SUBJECT, subject)
    intent.putExtra(Intent.EXTRA_CC, cc)
    intent.type = "message/rfc822"
    return intent
}

参考链接


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接