web-dev-qa-db-fra.com

Android WebView "tel:" liens vers une page Web non trouvée

J'essaie d'obtenir que mon application de visualisation Web Android ouvre tel: des liens vers le téléphone. Chaque fois que j'ouvre une liaison téléphonique, cela fonctionne très bien et ouvre le téléphone. Cependant, une fois que mon appel est terminé et que je retourne à l'application, la page indique "Page introuvable, tel: 0000000000". Ensuite, je dois appuyer sur le bouton de retour une fois de plus pour accéder à la page sur laquelle j'ai cliqué sur le numéro de téléphone.

Existe-t-il un moyen d'obtenir le lien TEL sans essayer de trouver la page dans la visualisation Web et de l'ouvrir au téléphone?

C'est le code que j'utilise dans WebView pour redéfinir le traitement des liens TEL et 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;
        }

Toute aide serait appréciée. J'ai passé les deux dernières heures à nettoyer Goodle et je n'ai pas réussi à obtenir de réponse.

60
Jeff Thomas

OK alors j'ai résolu le problème, je pense. Je devais simplement séparer les remplacements d'URL comme suit:

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

Maintenant, mes liens réguliers fonctionnent aussi bien que les liens tel. Je peux aussi ajouter là pour geo: links si nécessaire et cela ne me donnera pas le problème que j'avais avant d'ouvrir des cartes au téléphone.

99
Jeff Thomas

Plutôt que d'appeler loadUrl(url), renvoyez simplement false pour les URL à ne pas remplacer:

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

J'ai trouvé que VIEWing tel: fonctionne comme prévu sur tous les téléphones avec lesquels nous l'avons essayé. Pas besoin de le cas spécial à cause de l'action DIAL.

J'ai remarqué que les vidéos YouTube et autres ne fonctionnent pas dans WebViews. Vous voudrez peut-être également les détecter.

L'ensemble du processus pourrait probablement être généralisé pour toutes sortes d'URI en interrogeant le PackageManager pour les activités qui gèrent votre URI qui ne sont également pas le navigateur intégré. Cela pourrait être exagéré et être dérouté par les autres navigateurs installés.

52
Anm

D'après le documentation et d'après mon expérience, Intent.ACTION_VIEW est parfaitement correct pour analyser les liens tel:, sms:, smsto:, mms: et mmsto:.

Voici un 5 en 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;
   }
16
Pedro Lobito

Remarque: - Après qu'Android Nouget shouldOverrideUrlLoading soit déconseillé

Vous devez utiliser shouldOverrideUrlLoading avec shouldOverrideUrlLoading pour un meilleur support. Vous pouvez également vérifier si les URL ont mailto: ou tel :, qui sont utilisées dans HTML5 pour déclencher la numérotation du client de messagerie et du téléphone.

Une solution complète ressemblera à ceci maintenant

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

Si WebViewClient n'est pas affecté à WebView, WebView demandera par défaut à Activity Manager de choisir le gestionnaire approprié pour l'URL. Si un WebViewClient est fourni, vous devez gérer vous-même différentes URL et renvoyer true dans WebViewClient.shouldOverrideUrlLoading (), sinon il essaiera d'envoyer une demande à l'URL et obtiendra une erreur, puis déclenchera onReceiveError ().

Vérifier le 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;
        }
    }
3
evanchin
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;
    }
}

}

C'était le correctif que j'ai trouvé. Vous devez utiliser cette méthode.

wv.setWebViewClient(new CustomWebViewClient());
2
Vimukthi Sineth
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;
       }
1
diyism
@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;
    }
0
Naju Mat Isa