Kliknięcie adresów URL otwiera domyślną przeglądarkę

209

Załadowałem zewnętrzny adres URL do mojego WebView. Teraz potrzebuję tego, że kiedy użytkownik kliknie linki na załadowanej stronie, musi działać jak zwykła przeglądarka i otworzyć link w tym samym WebView. Ale otwiera domyślną przeglądarkę i ładuje tam stronę?

Włączyłem JavaScript. Ale nadal nie działa. Zapomniałem czegoś?

JaVadid
źródło

Odpowiedzi:

353

Jeśli używasz WebView, musisz przechwycić kliknięcia, jeśli nie chcesz domyślnego zachowania Androida.

Możesz monitorować zdarzenia za WebViewpomocą WebViewClient. Metoda, którą chcesz, to shouldOverrideUrlLoading(). Pozwala to na wykonanie własnej akcji po wybraniu określonego adresu URL.

Ci ustawić WebViewClientz listy WebViewza pomocą setWebViewClient()metody .

Jeśli spojrzysz na WebViewpróbkę w zestawie SDK , jest przykład, który robi dokładnie to, co chcesz. To tak proste, jak:

private class HelloWebViewClient extends WebViewClient {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        view.loadUrl(url);
        return true;
    }
}
Dave Webb
źródło
97
Wygląda na to, że jest to domyślne zachowanie WebViewClienti nie wymaga ono podklasowania, jeśli to wszystko, co robisz. Sprawiłem, że zadziałałomyWebView.setWebViewClient(new WebViewClient());
Adam
7
@ dave-webb proszę zaktualizować próbkę, aby nie wywoływała loadUrl. Wszyscy czytający to - nie powielaj kodu (zwróć false z wywołania zwrotnego zamiast wywoływać view.loadUrl). Wywołanie loadUrl wprowadza subtelny błąd polegający na tym, że jeśli masz dowolną ramkę iframe na stronie z niestandardowym adresem URL schematu (powiedzmy <iframe src = "tel: 123" />), przekieruje główną ramkę aplikacji do tego adresu URL, najprawdopodobniej powodując uszkodzenie aplikacji jako efekt uboczny.
marcin.kosiba
1
@Adam ++ - tak, też to zauważyłem - nie mogłem zrozumieć, dlaczego jeden z moich widoków WWW NIE korzystał z przeglądarki systemowej, a to dlatego, że dodałem do niego nowy klient internetowy, który tylko zastępował INNĄ metodę. Debugowanie zajęło mi trochę czasu.
Peter Ajtai
Czy możemy zaimplementować coś takiego: onLongClick, otwieranie linków w zewnętrznej przeglądarce?
TheOnlyAnil
54

w niektórych przypadkach możesz potrzebować zastąpienia onLoadResource, jeśli otrzymasz przekierowanie, które nie wyzwala metody ładowania adresu URL. w tym przypadku próbowałem:

@Override
public void onLoadResource(WebView view, String url)
{
    if (url.equals("http://redirectexample.com"))
    {
        //do your own thing here
    }
    else
    {
        super.onLoadResource(view, url);
    }           
}
realgt
źródło
To jest świetne! Zaoszczędziło mi wiele godzin próbowania, jak odtworzyć plik MP3 z linku w widoku internetowym. Wielkie dzięki!
Brigante
25

Oficjalna dokumentacja mówi, że kliknij link w WebView uruchomi aplikację, która obsługuje adresy URL. Musisz zastąpić to domyślne zachowanie

    myWebView.setWebViewClient(new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            return false;
        }
    });

lub jeśli w metodzie nie ma logiki warunkowej, po prostu zrób to

myWebView.setWebViewClient(new WebViewClient());
Abbas
źródło
15

Dodaj te 2 wiersze do swojego kodu -

mWebView.setWebChromeClient(new WebChromeClient()); 
mWebView.setWebViewClient(new WebViewClient());
Dezorientować
źródło
9

Ta metoda boolean shouldOverrideUrlLoading(WebView view, String url)została wycofana z interfejsu API 24. Jeśli wspierasz nowe urządzenia, powinieneś użyć boolean shouldOverrideUrlLoading (WebView view, WebResourceRequest request).

Możesz użyć obu, robiąc coś takiego:

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    newsItem.setWebViewClient(new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
            view.loadUrl(request.getUrl().toString());
            return true;
        }
    });
} else {
    newsItem.setWebViewClient(new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }
    });
}
Chris Stillwell
źródło
6

Odpowiedź Arulx Z była dokładnie tym, czego szukałem.

Piszę aplikację z Szufladą nawigacji z widokiem recyklera i przeglądarkami internetowymi, aby umożliwić przeglądanie stron internetowych w aplikacji bez względu na kliknięte hiperłącza (nie uruchamiając zewnętrznej przeglądarki internetowej). W tym celu wystarczy wstawić następujące 2 wiersze kodu:

mWebView.setWebChromeClient(new WebChromeClient()); mWebView.setWebViewClient(new WebViewClient());

dokładnie pod wyciągiem WebView.

Oto przykład mojego zaimplementowanego kodu WebView:

public class WebView1 extends AppCompatActivity {

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

    WebView wv = (WebView) findViewById(R.id.wv1); //webview statement
    wv.setWebViewClient(new WebViewClient());    //the lines of code added
    wv.setWebChromeClient(new WebChromeClient()); //same as above

    wv.loadUrl("http://www.google.com");
}}

w ten sposób każdy link kliknięty w witrynie zostanie załadowany do twojego WebView. (Korzystanie z Android Studio 1.2.2 ze zaktualizowanymi wszystkimi pakietami SDK)

Samuele Bolognini
źródło