Ссылки "tel:" на Android WebView показывают, что веб-страница не найдена - PullRequest
61 голосов
/ 02 декабря 2010

Я пытаюсь заставить мое приложение для веб-обозревателя Android открывать ссылки на телефон. Каждый раз, когда я открываю телефонную связь, она прекрасно работает и открывает телефон. Однако, как только я закончу свой звонок и вернусь к приложению, он появится на странице с надписью «Веб-страница не найдена», тел .: 0000000000 Затем мне нужно нажать кнопку «Назад» еще раз, чтобы перейти на страницу, на которой я щелкнул номер телефона.

Есть ли способ заставить его открыть ссылку TEL, не пытаясь найти страницу в веб-просмотре, а также открыть ее на телефоне?

Это код, который я использую в 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 часа, обыскивая Гудла, и не смог дать никаких ответов.

Ответы [ 8 ]

101 голосов
/ 02 декабря 2010

ОК, поэтому я решил проблему, я думаю. Мне просто нужно было разделить переопределения 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;
}

Теперь мои обычные ссылки работают так же, как и тел-ссылки. Я также могу добавить туда ссылки для гео: если нужно, и это не даст мне проблемы, с которой я сталкивался раньше при открытии карт на телефоне.

52 голосов
/ 05 апреля 2011

Вместо вызова loadUrl(url), просто верните false для URL, которые не должны быть переопределены:

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 и тому подобное не работают в WebViews, поэтому вы можете их также обнаружить.

Весь процесс, вероятно, можно обобщить для всех видов URI, запрашивая PackageManager для действий, которые обрабатывают ваш URI , которые также не являются встроенным браузером. Это может быть излишним и привести в замешательство другие установленные браузеры.

17 голосов
/ 16 октября 2015

Согласно документации и исходя из моего опыта, Intent.ACTION_VIEW - это отлично для анализа tel:, sms:, smsto:, mms: и mmsto: ссылки.

Вот 5 в 1:

@Override
    public boolean shouldOverrideUrlLoading(WebView webview, String url)
    {
     if (url.startsWith("tel:") || url.startsWith("sms:") || url.startsWith("smsto:") || url.startsWith("mms:") || url.startsWith("mmsto:"))
       { 
         Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse(url)); 
         startActivity(intent); 
         return true;
       }
    return false;
   }
8 голосов
/ 13 апреля 2017

Примечание: - После того, как Android Nouget shouldOverrideUrlLoading устарел

Вам необходимо использовать shouldOverrideUrlLoading вместе с shouldOverrideUrlLoading для лучшей поддержки.Также вы можете проверить, есть ли в URL 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;
    }
3 голосов
/ 01 февраля 2018
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;
    }
}

}

Это было исправление, которое я нашел.Вы должны использовать этот метод.

wv.setWebViewClient(new CustomWebViewClient());
3 голосов
/ 12 февраля 2016

Если WebViewClient не назначен для WebView, по умолчанию WebView попросит Activity Manager выбрать подходящий обработчик для URL.Если предоставляется WebViewClient, вы должны обрабатывать разные URL-адреса самостоятельно и возвращать true в WebViewClient.shouldOverrideUrlLoading (), в противном случае он попытается отправить запрос на URL-адрес и получить ошибку, затем активирует onReceiveError ().

Проверьте документ: 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;
        }
    }
1 голос
/ 11 августа 2011
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;
       }
0 голосов
/ 20 февраля 2018
@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 {
    @SuppressWarnings("deprecated")
    @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;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...