Android WebView“tel:”链接显示未找到网页

时间:2010-12-02 18:11:02

标签: android android-webview

我想让我的android webview应用程序打开tel:电话链接。每次打开电话链接时,它都能很好地打开电话。然而,一旦我完成了我的通话并返回应用程序,它就会出现在“未找到网页电话:0000000000”的页面上。然后我必须再次点击后退按钮才能进入我点击电话号码的页面。

有没有办法让它打开TEL链接而不试图在webview中找到该页面并在手机上打开它?

这是我在WebView中使用的代码,用于覆盖其对TEL和Mailto链接的处理:

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

任何帮助将不胜感激。我花了最近2个小时来搜索goodle并且没有得到任何答案。

11 个答案:

答案 0 :(得分:100)

好的,所以我解决了我认为的问题。我只需要按如下方式分隔URL覆盖:

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

    view.loadUrl(url);
    return true;
}

现在我的常规链接和tel链接一样。我还可以在那里添加地理位置:链接,如果我需要,它不会给我以前在手机上打开地图时遇到的问题。

答案 1 :(得分:52)

不要调用loadUrl(url),而只是为不应该覆盖的网址返回false:

public boolean shouldOverrideUrlLoading(WebView view, String url) {
    if( URLUtil.isNetworkUrl(url) ) {
        return false;
    }

    // Otherwise allow the OS to handle it
    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
    startActivity( intent ); 
    return true;
}

我发现VIEWing tel:在我们尝试过的所有手机上按预期工作。由于DIAL的行动,不需要特殊情况。

我注意到YouTube视频等在WebView中不起作用,因此您可能也想要检测这些视频。

整个过程可能会被querying the PackageManager for Activities that handle your URI的各种URI推广,这些URI也不是嵌入式浏览器。这可能是过度的,并被其他已安装的浏览器搞糊涂了。

答案 2 :(得分:17)

根据documentation并根据我的经验,Intent.ACTION_VIEW 完全正常来解析tel:sms:,{{1} },smsto:mms:链接。

这是一个5合1:

mmsto:

答案 3 :(得分:7)

注意: - Android Nouget shouldOverrideUrlLoading已弃用

您需要使用shouldOverrideUrlLoadingshouldOverrideUrlLoading来获得更好的支持。您还可以检查网址是否包含mailto:tel:,这些网址在HTML5中分别用于触发邮件客户端和电话拨号。

现在,完整的解决方案将如下所示

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

答案 4 :(得分:3)

如果没有为WebView分配WebViewClient,默认情况下,WebView会要求活动管理器为URL选择正确的处理程序。如果提供了WebViewClient,您应该自己处理不同的URL并在WebViewClient.shouldOverrideUrlLoading()中返回true,否则它将尝试向URL发送请求并获取错误,然后触发onReceiveError()。

Check document: WebViewClient.shouldOverrideUrlLoading

     @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if (url.startsWith("tel:")) { 
            // ...TODO: launch a Dial app or send SMS or add to contact, etc...
            return true;
        }
        else if (url.startsWith("mailto:")) {
            // ...TODO: send email to someone or add to contact, etc...
            return true;
        }
        else {
            // ...TODO: Handle URL here
            boolean handled = yourHandleUrlMethod(url);
            return handled;
        }
    }

答案 5 :(得分:3)

SELECT *, A + B + C + D + E + F + G + H + I + J + K + L + M AS Total
FROM Table1
ORDER BY Total DESC
LIMIT 30;

这是我发现的修复。你必须使用这种方法。

public class MainActivity extends Activity {

private static final String HTML ="<!DOCTYPE html><html><body><a 
href='tel:867-5309'>Click here to call!</a></body></html>";
private static final String TEL_PREFIX = "tel:";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    WebView wv = (WebView) findViewById(R.id.webview);
    wv.setWebViewClient(new CustomWebViewClient());
    wv.loadData(HTML, "text/html", "utf-8");
}

private class CustomWebViewClient extends WebViewClient {

    @Override
    public boolean shouldOverrideUrlLoading(WebView wv, String url) {
        if(url.startsWith(TEL_PREFIX)) {
            Intent intent = new Intent(Intent.ACTION_DIAL);
            intent.setData(Uri.parse(url));
            startActivity(intent);
            return true;
        }
        return false;
    }
}

}

答案 6 :(得分:1)

public boolean shouldOverrideUrlLoading(WebView view, String url)
       {Uri query_string=Uri.parse(url);
        String query_scheme=query_string.getScheme();
        String query_host=query_string.getHost();
        if ((query_scheme.equalsIgnoreCase("https") || query_scheme.equalsIgnoreCase("http"))
            && query_host!=null && query_host.equalsIgnoreCase(Uri.parse(URL_SERVER).getHost())
            && query_string.getQueryParameter("new_window")==null
           )
           {return false;//handle the load by webview
           }
        try
           {Intent intent=new Intent(Intent.ACTION_VIEW, query_string);
            String[] body=url.split("\\?body=");
            if (query_scheme.equalsIgnoreCase("sms") && body.length>1)
               {intent=new Intent(Intent.ACTION_VIEW, Uri.parse(body[0]));
                intent.putExtra("sms_body", URLDecoder.decode(body[1]));
               }
            view.getContext().startActivity(intent);//handle the load by os
           }
        catch (Exception e) {}
        return true;
       }

答案 7 :(得分:1)

WebView类中,某些常量是静态的。您应该使用Intent.ACTION_VIEW而不是Intent.ACTION_DIALACTION_SENDTO

@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
    String url = request.getUrl().toString();
    if (url.startsWith(WebView.SCHEME_TEL)
            || url.startsWith("sms:")
            || url.startsWith(WebView.SCHEME_MAILTO)
            || url.startsWith(WebView.SCHEME_GEO)) {
        
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setData(Uri.parse(url));
        startActivity(intent); // view.context.startActivity(intent);
    }
    return true;
}

答案 8 :(得分:0)

public ActionResult Create()
{
    AddressVM model = new AddressVM();
    ConfigureViewModel(model);
    return View(model);
}
[HttpPost]
public ActionResult Create(AddressVM model)
{
    if (!ModelState.IsValid)
    {
        ConfigureViewModel(model);
        return View(model); 
    }
    .... // initailize an Address data model, map its properties from the view model
    .... // save and redirect
}

答案 9 :(得分:0)

对于那些尝试使用@jeff Thomas回答但出现以下错误的人:

cannot find symbol view.startActivity(intent);

您可以使用以下代码:

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

    view.loadUrl(url);
    return true;
}

我刚刚将startActivity(intent)更改为view.getContext().startActivity(intent),这对我有用。

答案 10 :(得分:0)

看着Hitesh Sahukam C的答案,我找到了解决方案。

在API 21中,它引发了一个异常:“ android.util.AndroidRuntimeException:从Activity上下文外部调用startActivity()需要FLAG_ACTIVITY_NEW_TASK标志。这真的是您想要的吗?”

diyism所示,也可能找不到活动。因此,我处理了这些情况。

class MyWebViewClient : WebViewClient() {

    @Suppress("DEPRECATION")
    override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
        if (view != null && url != null) {
            return resolveUri(view.context, Uri.parse(url))
        }
        return super.shouldOverrideUrlLoading(view, url)
    }

    @TargetApi(Build.VERSION_CODES.N)
    override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
        val uri = request?.url
        if (view != null && uri != null) {
            return resolveUri(view.context, uri)
        }
        return super.shouldOverrideUrlLoading(view, request)
    }

    private fun resolveUri(context: Context, uri: Uri): Boolean {
        val url = uri.toString()
        URL_SCHEMES.forEach {
            if (url.startsWith(it)) {
                val intent = Intent(Intent.ACTION_VIEW).apply {
                    data = uri
                    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                }
                try {
                    context.startActivity(intent)
                } catch (e: ActivityNotFoundException) {
                }
                return true
            }
        }
        return false
    }

    companion object {
        private val URL_SCHEMES = arrayOf(WebView.SCHEME_TEL,
            WebView.SCHEME_MAILTO, WebView.SCHEME_GEO, "sms:", "smsto:", "mms:", "mmsto:")
    }
}