69 votes

Les liens "tel :" des WebViews Android affichent une page web non trouvée

J'essaie de faire en sorte que mon application Android webview ouvre les liens tel : sur le téléphone. Chaque fois que j'ouvre un lien téléphonique, cela fonctionne très bien et ouvre le téléphone. Cependant, une fois que j'ai terminé mon appel et que je reviens à l'application, celle-ci se trouve sur une page qui dit "Web Page Not Found tel:0000000000". Je dois alors appuyer une nouvelle fois sur le bouton Précédent pour revenir à la page où j'ai cliqué sur le numéro de téléphone.

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

C'est le code que j'utilise dans WebView pour remplacer sa gestion 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 à parcourir Goodle et je n'ai trouvé aucune réponse.

1 votes

Essayez ACTION_DIAL pour le lien tel: ?

0 votes

Attendez, la documentation dit en fait que ACTION_VIEW est bien : developer.Android.com/reference/Android/content/Intent.html Peu importe alors...

0 votes

Question stupide : As-tu configuré le WebViewClient correctement ? Est-ce que tout le reste fonctionne ?

117voto

Jeff Thomas Points 1640

OK, j'ai résolu le problème, je pense. J'avais juste besoin de séparer les URLs prioritaires 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 habituels fonctionnent aussi bien que les liens tel. Je peux également ajouter des liens géo : si nécessaire et je n'aurai pas le problème que j'avais auparavant pour ouvrir les cartes sur le téléphone.

2 votes

Duh. Je viens de réaliser que tu appelles view.LoadUrl(url) sur ton lien tel :. Tu pourrais tout aussi bien ajouter un return true après startActivity() .

6 votes

Ajouter <uses-permission Android:name="Android.permission.CALL_PHONE" /> au manifeste.

9 votes

@jasonflaherty En fait, la permission CALL_PHONE est pour ACTION_CALL et non ACTION_DIAL. Donc le code ci-dessus fonctionne bien même sans la permission.

56voto

Anm Points 1689

Plutôt que d'appeler loadUrl(url) pour les URL qui ne doivent pas être remplacées, il suffit de renvoyer 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;
}

J'ai constaté que VIEWing tel : fonctionne comme prévu sur tous les téléphones avec lesquels nous l'avons essayé. Il n'est pas nécessaire de le mettre en majuscule à cause de l'action DIAL.

J'ai remarqué que les vidéos YouTube et autres ne fonctionnent pas dans les WebViews, vous pouvez donc les détecter également.

L'ensemble du processus pourrait probablement être généralisé pour toutes sortes d'URI en recherche dans le PackageManager des activités qui gèrent votre URI qui ne sont pas non plus le navigateur intégré. Cela pourrait être excessif et être confondu avec d'autres navigateurs installés.

2 votes

Vous pouvez utiliser URLUtil.isNetworkUrl(url) pour vérifier http/https (et autres)

2 votes

Excellente suggestion, @xnagyg. J'ai mis à jour mon extrait de code.

2 votes

C'est beaucoup plus pratique que d'ajouter des schémas d'URL individuels.

19voto

Pedro Lobito Points 6794

Selon le documentation et basé sur mon expérience, Intent.ACTION_VIEW est parfaitement bien pour analyser tel: , sms: , smsto: , mms: et mmsto: liens.

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

15voto

Hitesh Sahu Points 12561

Note : - Après Android Nouget shouldOverrideUrlLoading est déprécié

Vous devez utiliser shouldOverrideUrlLoading ainsi que shouldOverrideUrlLoading pour un meilleur soutien. Vous pourriez également vérifier si url a mailto: ou tel qui sont utilisés en HTML5 pour déclencher respectivement le client de messagerie et la numérotation téléphonique.

Une solution complète ressemblera maintenant à ceci

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

0 votes

Parfait... Gère le pré-nougat et le nougat. Merci

0 votes

Merci ! Utilisez @Suppress("DEPRECATION") au lieu de @SuppressWarnings("deprecation") . Vous pouvez créer une méthode pour les deux événements. Utilisez view.getContext() à insérer avant startActivity() .

0 votes

Quelqu'un peut-il m'expliquer ce qu'il faut faire exactement si j'obtiens : "error : method startActivity in class ContextCompat cannot be applied to given types ; startActivity(new Intent(Intent.ACTION_SENDTO, uri)) ; ^ required : Context,Intent,Bundle trouvé : Intent reason : actual and formal argument lists differ in length" J'ai implémenté la solution dans une autre classe

4voto

Vimukthi Sineth Points 60
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'est la solution que j'ai trouvée. Vous devez utiliser cette méthode.

wv.setWebViewClient(new CustomWebViewClient());

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X