Как я могу проверить из Android WebView, если страница не найдена на странице 404?

Я хочу проверить «страница 404 не найдена» из WebView, и если это 404, я возвращаюсь к предыдущей странице. Ти за вашу помощь

РЕДАКТИРОВАТЬ также веб-страницы, которые я хочу видеть, являются чистыми .jpg 1.jpg 2.jpg 3.jpg, но у меня нет информации о том, сколько изображений существует. Поэтому, если кто-то может предложить другой метод, он может это сделать.


person weakwire    schedule 05.07.2010    source источник
comment
Вы можете просмотреть эту ветку на странице Android. -группа разработчиков.   -  person Tim Kryger    schedule 06.07.2010


Ответы (6)


Начиная с SDK 23 (Android M), вы можете использовать метод onReceivedHttpError для обнаружения 404 и других ошибок HTTP. Просто переопределите внутри своего WebViewClient

@Override
public void onReceivedHttpError (WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
    Toast.makeText(view.getContext(), "HTTP error "+errorResponse.getStatusCode(), Toast.LENGTH_LONG).show();
}
person Alexey Ozerov    schedule 10.04.2016
comment
Имейте в виду, что This callback will be called for any resource (iframe, image, etc), not just for the main page - из документов - person Aba; 03.11.2017
comment
Я пробовал это, но мой код просто пропускает его, когда я получаю 404 на устройстве API 24. - person Zeek Aran; 09.11.2017
comment
Знаете ли вы, можно ли это использовать для обнаружения неудачных запросов AJAX? Или это только для ресурсов, полученных из основного документа? - person macalaca; 10.01.2020

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

В итоге я использовал onReceivedTitle и сравнил заголовок с заголовком страницы (в данном случае «страница не найдена») с сайта, который я пытался открыть.

webview.setWebChromeClient(new WebChromeClient() {
        @Override
        public void onReceivedTitle(WebView view, String title) {
            // TODO Auto-generated method stub
            super.onReceivedTitle(view, title);


            CharSequence pnotfound = "The page cannot be found";
            if (title.contains(pnotfound)) {
                pagenotfound = true;
                view.stopLoading();
                webview.loadUrl("https://www.google.com/search?hl=en&q=stackoverflow");

            }
        }

        public void onProgressChanged(WebView view, int progress) {
            activity.setProgress(progress * 1000);
        }
    });

webview.setWebViewClient(new WebViewClient() {
        @Override
        public void onReceivedError(WebView view, int errorCode,
                String description, String failingUrl) {

            Toast.makeText(activity, "Oh no! " + description,
                    Toast.LENGTH_SHORT).show();

        }

        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);

            return true;
        }

        public void onPageFinished(WebView view, String url) {
            if (dialog.isShowing()) {
                dialog.dismiss();

            }
        }
    });

«pnotfound» будет отличаться от сайта к сайту. Но обычно на одном сайте используется одна и та же «страница не найдена», поэтому вы можете использовать заголовок на сайте. Возможно, вы захотите добавить еще, если вы используете несколько сайтов.

Надеюсь, это поможет кому-то.

person LordMarty    schedule 16.07.2013
comment
Спасибо за предоставленный хак. Кажется, что нет прямого (не хакерского) способа выяснить 404. - person Victor Ionescu; 02.12.2014
comment
Это отличный ответ!! Это определенно сработало для меня и избавило меня от часов биться головой о стену!!! Спасибо, что поделились!!! - person jabobadilla; 06.05.2016
comment
Хотя это умно, это не очень хорошее решение. У вас может возникнуть соблазн просто проверить стандартную веб-страницу Android, недоступную для обнаружения сетевой ошибки, но имейте в виду, что это сломается для любого другого языка (и не говоря уже о том, что ОС может изменить это название в будущем). - person Stephen Kidson; 08.11.2016

Я бы попытался обнаружить загрузку страницы 404. Вы можете сделать это, реализовав метод shouldOverrideUrlLoading в классе WebViewClient.

mGenericWebClient = new GenericWebClient();
mWebView.setWebViewClient(mGenericWebClient);

public class GenericWebClient extends WebViewClient {
    public boolean shouldOverrideUrlLoading(WebView view, String url)
    {
        if (url=="your404page.html") {
            view.goBack();
            return true;
        }
        return false;
   }
}

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

person Dariusz Bacinski    schedule 05.07.2010
comment
Что делать, если страница 404 НЕ контролируется мной? Посещение какого-то анонимного сайта возвращает 404? - person ; 29.04.2013

Вам не нужно полностью загружать страницу, чтобы проверить, не приводит ли она к ошибке 404:

private int getRange() {
    try {
        HttpURLConnection.setFollowRedirects(false);
        int Count = 1;
        URL testURL;
        while (true) {
            testURL = new URL(
                    (myURL + "/" + Integer.toString(Count++) + ".jpg"));
            HttpURLConnection con = (HttpURLConnection) testURL
                    .openConnection();
            con.setRequestMethod("HEAD");
            if (con.getResponseCode() == 404) {
                return Count - 2;
            }
            Log.e("RESPONCE", Integer.toString(con.getResponseCode()));
        }
    } catch (Exception e) {

    }
    return 1;
}
person weakwire    schedule 06.07.2010
comment
Это не имеет ничего общего с WebView, который был исходным вопросом. - person Jay Soyer; 01.11.2012
comment
Я прошу не согласиться с отрицательными голосами этого ответа. Через три года после публикации этого ответа Android WebView по-прежнему не предлагает никаких средств проверки состояния HTTP текущей загруженной страницы. Это оставляет разработчику внешние решения, такие как вклад @weakwire. Следует понимать, что предлагаемое решение должно использоваться в качестве шага предварительной проверки, прежде чем (и если) делегировать загрузку URL-адреса WebView. Однако я решил оставить качество кода без комментариев. - person dbm; 27.10.2015
comment
Кажется, это все еще так в апреле 2017 года, а? @дбм - person AlexioVay; 01.04.2017

Я мог бы очень поздно для этой темы, но вот как я решил это. Поскольку мое приложение имеет дело с динамическими URL-адресами и многоязычными веб-сайтами, ни одно из вышеперечисленных решений не сработало для меня. И onReceivedHttpError может вызываться для любого ресурса (iframe, изображения и т. д.), а не только для главной страницы, поэтому я решил добавить проверку для mainPage.

Итак, вот как я это сделал:

 @Override
public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
    if (request !=null && request.getUrl() !=null)
        if (request.getUrl().toString().equals(dynamicURL) && errorResponse.getStatusCode()==404) {
            //Handle the error
        }
}

Здесь dynamicURL — это основной URL-адрес, который загружается в активность webview. Добавив эту проверку, я теперь получаю ошибку только в том случае, если главная страница выдает 404.

PS: Это может не сработать для вас, если URL-адрес вашей страницы не возвращает 404.

person Mustansir    schedule 27.03.2021

Если вы являетесь веб-мастером страницы, которая загружается в веб-просмотре, вы можете установить заголовок страницы, например «404». Затем, после загрузки вашей страницы, вы можете получить заголовок страницы с помощью метода getTitle(). Затем, если он содержит 404 или отличается от заголовка вашей страницы, вы можете делать то, что хотите.

Пример:

myView.setWebViewClient(new WebViewClient(){
    @Override  
        public void onPageFinished(WebView view, String url) {  
           String pageTitle = myView.getTitle();
           Toast.makeText(getBaseContext(), pageTitle, Toast.LENGTH_SHORT).show();
        }
});
person themaster33    schedule 06.09.2012
comment
Возвращенный заголовок может быть или не быть 404 в нем. Различные платформы и/или устройства могут возвращать разные названия заголовков. - person Jay Soyer; 01.11.2012
comment
Я отредактировал свой ответ, как будто пользователь является веб-мастером страницы. - person themaster33; 13.02.2014