Frage Verhindern, dass WebView "Webseite nicht verfügbar" anzeigt


Ich habe eine App, die einen WebView ausgiebig nutzt. Wenn der Benutzer dieser App keine Internetverbindung hat, wird eine Seite mit der Aufschrift "Webseite nicht verfügbar" und anderer Text angezeigt. Gibt es eine Möglichkeit, diesen generischen Text nicht in meinem WebView anzuzeigen? Ich möchte meine eigene Fehlerbehandlung anbieten.

private final Activity activity = this;

private class MyWebViewClient extends WebViewClient
 public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
  // I need to do something like this:
  activity.webView.wipeOutThePage();
  activity.myCustomErrorHandling();
  Toast.makeText(activity, description, Toast.LENGTH_LONG).show();
 }
}

ich fand heraus WebView-> clearView reinigt die Sicht nicht wirklich.


75
2017-07-01 18:58


Ursprung


Antworten:


Erstellen Sie zuerst Ihre eigene Fehlerseite in HTML und legen Sie sie in Ihren Assets-Ordner, nennen wir sie myerrorpage.html Dann mit onReceivedError:

mWebView.setWebViewClient(new WebViewClient() {
    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
        mWebView.loadUrl("file:///android_asset/myerrorpage.html");

    }
});

88
2017-09-23 00:12



Die beste Lösung, die ich gefunden habe, ist, eine leere Seite im OnReceivedError-Ereignis wie folgt zu laden:

@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
    super.onReceivedError(view, errorCode, description, failingUrl);

    view.loadUrl("about:blank");
}

23
2017-07-16 13:23



Schließlich habe ich das gelöst. (Es funktioniert bis jetzt ..)

Meine Lösung ist so ...

  1. Bereiten Sie das Layout so vor, dass es angezeigt wird, wenn ein Fehler anstelle der Webseite aufgetreten ist (eine schmutzige Meldung, dass die Seite nicht gefunden wurde). Das Layout hat eine Schaltfläche "RELOAD" mit einigen Leitbotschaften.

  2. Wenn ein Fehler aufgetreten ist, denken Sie daran, boolean zu verwenden und zeigen Sie das von uns vorbereitete Layout an.

  3. Wenn Benutzer auf "RELOAD" klicken, setzen Sie mbErrorOccured auf false. Und setze mbReloadPressed auf true.
  4. Wenn mbErrorOccured falsch ist und mbReloadPressed true ist, bedeutet dies, dass die webview-Seite erfolgreich geladen wurde. Wenn der Fehler erneut aufgetreten ist, wird mbErrorOccured für onReceivedError (...) auf true gesetzt.

Hier ist meine vollständige Quelle. Sieh dir das an.

public class MyWebViewActivity extends ActionBarActivity implements OnClickListener {

    private final String TAG = MyWebViewActivity.class.getSimpleName();
    private WebView mWebView = null;
    private final String URL = "http://www.google.com";
    private LinearLayout mlLayoutRequestError = null;
    private Handler mhErrorLayoutHide = null;

    private boolean mbErrorOccured = false;
    private boolean mbReloadPressed = false;

    @SuppressLint("SetJavaScriptEnabled")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_webview);

        ((Button) findViewById(R.id.btnRetry)).setOnClickListener(this);
        mlLayoutRequestError = (LinearLayout) findViewById(R.id.lLayoutRequestError);
        mhErrorLayoutHide = getErrorLayoutHideHandler();

        mWebView = (WebView) findViewById(R.id.webviewMain);
        mWebView.setWebViewClient(new MyWebViewClient());
        WebSettings settings = mWebView.getSettings();
        settings.setJavaScriptEnabled(true);
        mWebView.setWebChromeClient(getChromeClient());
        mWebView.loadUrl(URL);
    }

    @Override
    public boolean onSupportNavigateUp() {
        return super.onSupportNavigateUp();
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();

        if (id == R.id.btnRetry) {
            if (!mbErrorOccured) {
                return;
            }

            mbReloadPressed = true;
            mWebView.reload();
            mbErrorOccured = false;
        }
    }

    @Override
    public void onBackPressed() {
        if (mWebView.canGoBack()) {
            mWebView.goBack();
            return;
        }
        else {
            finish();
        }

        super.onBackPressed();
    }

    class MyWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            return super.shouldOverrideUrlLoading(view, url);
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
        }

        @Override
        public void onLoadResource(WebView view, String url) {
            super.onLoadResource(view, url);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            if (mbErrorOccured == false && mbReloadPressed) {
                hideErrorLayout();
                mbReloadPressed = false;
            }

            super.onPageFinished(view, url);
        }

        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            mbErrorOccured = true;
            showErrorLayout();
            super.onReceivedError(view, errorCode, description, failingUrl);
        }
    }

    private WebChromeClient getChromeClient() {
        final ProgressDialog progressDialog = new ProgressDialog(MyWebViewActivity.this);
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setCancelable(false);

        return new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                super.onProgressChanged(view, newProgress);
            }
        };
    }

    private void showErrorLayout() {
        mlLayoutRequestError.setVisibility(View.VISIBLE);
    }

    private void hideErrorLayout() {
        mhErrorLayoutHide.sendEmptyMessageDelayed(10000, 200);
    }

    private Handler getErrorLayoutHideHandler() {
        return new Handler() {
            @Override
            public void handleMessage(Message msg) {
                mlLayoutRequestError.setVisibility(View.GONE);
                super.handleMessage(msg);
            }
        };
    }
}

Zusatz: Hier ist Layout ....

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rLayoutWithWebView"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<WebView
    android:id="@+id/webviewMain"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<LinearLayout
    android:id="@+id/lLayoutRequestError"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerInParent="true"
    android:background="@color/white"
    android:gravity="center"
    android:orientation="vertical"
    android:visibility="gone" >

    <Button
        android:id="@+id/btnRetry"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:minWidth="120dp"
        android:text="RELOAD"
        android:textSize="20dp"
        android:textStyle="bold" />
</LinearLayout>


9
2018-04-08 05:39



Schau dir die Diskussion an Android WebView onReceivedError (). Es ist ziemlich lang, aber der Konsens scheint zu sein, dass a) Sie nicht die Seite "nicht verfügbare Webseite" stoppen können, aber b) Sie könnten immer eine leere Seite laden, nachdem Sie einen onReceivedError erhalten haben


6
2017-07-01 19:17



Wenn Webview in eine benutzerdefinierte Ansicht eingebettet ist, ist der Benutzer fast davon überzeugt, dass er eine native Ansicht und keine Webansicht anzeigt. In einem solchen Szenario, das zeigt, dass die Seite nicht geladen werden kann, ist der Fehler absurd. Was ich normalerweise in einer solchen Situation mache, ist das Laden einer leeren Seite und das Anzeigen einer Toast-Nachricht wie unten

webView.setWebViewClient(new WebViewClient() {

            @Override
            public void onReceivedError(WebView view, int errorCode,
                    String description, String failingUrl) {
                Log.e(TAG," Error occured while loading the web page at Url"+ failingUrl+"." +description);     
                view.loadUrl("about:blank");
                Toast.makeText(App.getContext(), "Error occured, please check newtwork connectivity", Toast.LENGTH_SHORT).show();
                super.onReceivedError(view, errorCode, description, failingUrl);
            }
        });

4
2017-11-28 07:52



Du könntest einen benutzen GET Anfrage, um den Seiteninhalt zu erhalten und dann diese Daten anzuzeigen mit der Webview Auf diese Weise verwenden Sie nicht mehrere Serveraufrufe. Alternative, die Sie verwenden können Javascript um das zu überprüfen DOM Objekt für die Gültigkeit.


2
2017-07-11 18:49



Vielleicht missverstehe ich die Frage, aber es klingt, als ob du sagst, du bekommst den Fehler Callback erhalten, und du fragst dich nur, was der beste Weg ist, den Fehler nicht zu zeigen? Warum entfernen Sie nicht einfach entweder die Webansicht vom Bildschirm und / oder zeigen Sie eine andere Ansicht darüber?


2
2017-07-12 11:55



Ich nehme an, wenn Sie darauf bestehen, können Sie einfach überprüfen, ob die Ressource vorhanden ist, bevor Sie die loadURL-Funktion aufrufen. Einfach überschreiben Sie die Funktionen und führen Sie die Überprüfung vor dem Aufruf der super ()

REMARK (vielleicht off-topic): In http gibt es eine Methode namens HEAD, die wie folgt beschrieben wird:

Die HEAD-Methode ist identisch mit GET, außer dass der Server KEINE Nachricht in der Antwort zurückgeben darf

Diese Methode könnte nützlich sein. Wie auch immer Sie es implementieren ... diesen Code überprüfen:

import java.util.Map;

import android.content.Context;
import android.webkit.WebView;

public class WebViewPreLoad extends WebView{

public WebViewPreLoad(Context context) {
super(context);
}
public void loadUrl(String str){
if(//Check if exists)
super.loadUrl(str);
else
//handle error
}
public void loadUrl(String url, Map<String,String> extraHeaders){
if(//Check if exists)
super.loadUrl(url, extraHeaders);
else
//handle error
}
}

Sie können diese Überprüfung mit verwenden

if(url.openConnection().getContentLength() > 0)

1
2017-07-08 10:30



Hier fand ich die einfachste Lösung. Schau dir das an..

   @Override
        public void onReceivedError(WebView view, int errorCode,
                                    String description, String failingUrl) {
//                view.loadUrl("about:blank");
            mWebView.stopLoading();
            if (!mUtils.isInterentConnection()) {
                Toast.makeText(ReportingActivity.this, "Please Check Internet Connection!", Toast.LENGTH_SHORT).show();
            }
            super.onReceivedError(view, errorCode, description, failingUrl);
        }

Und hier ist isInterentConnection () -Methode ...

public boolean isInterentConnection() {
    ConnectivityManager manager = (ConnectivityManager) mContext
            .getSystemService(Context.CONNECTIVITY_SERVICE);
    if (manager != null) {
        NetworkInfo info[] = manager.getAllNetworkInfo();
        if (info != null) {
            for (int i = 0; i < info.length; i++) {
                if (info[i].getState() == NetworkInfo.State.CONNECTED) {
                    return true;
                }
            }
        }
    }
    return false;
}

1
2017-07-11 07:28