Предотвратить показ веб-страницы «веб-страница недоступна»

У меня есть приложение, которое широко использует WebView. Когда пользователь этого приложения не имеет подключения к Интернету, появляется страница с сообщением «веб-страница недоступна» и другой текст. Есть ли способ не показывать этот общий текст в моем WebView? Я хотел бы предоставить свою собственную обработку ошибок.

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

Я обнаружил, что WebView-> clearView фактически не очищает представление.

Solutions Collecting From Web of "Предотвратить показ веб-страницы «веб-страница недоступна»"

Сначала создайте свою собственную страницу ошибок в HTML и поместите ее в свою папку с ресурсами. Назовем ее myerrorpage.html. Затем с помощью onReceivedError:

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

Лучшее решение, которое я нашел, – загрузить пустую страницу в событие OnReceivedError следующим образом:

 @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { super.onReceivedError(view, errorCode, description, failingUrl); view.loadUrl("about:blank"); } 

Наконец, я решил это. (Он работает до сих пор ..)

Мое решение такое …

  1. Подготовьте макет, чтобы показать, когда произошла ошибка вместо веб-страницы (грязная страница, не найденное сообщение). В макете есть одна кнопка «RELOAD» с некоторыми направляющими сообщениями.

  2. Если произошла ошибка, запомните использование логического значения и покажите макет, который мы подготовим.

  3. Если пользователь нажмет кнопку «RELOAD», установите для mbErrorOccured значение false. И установите mbReloadPressed в true.
  4. Если mbErrorOccured является false и mbReloadPressed имеет значение true, это означает, что страница с загруженным веб-сайтом прошла успешно. Причина в том, что ошибка повторяется снова, mbErrorOccured будет установлен true на onReceivedError (…)

Вот мой полный источник. Проверь это.

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

Дополнение: Вот макет ….

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

Ознакомьтесь с обсуждением в Android WebView onReceivedError () . Это довольно долго, но, похоже, консенсус заключается в том, что: а) вы не можете остановить страницу «недоступна страница», но б) вы всегда можете загрузить пустую страницу после получения onReceivedError

Когда webview встроен в какой-то пользовательский вид, так что пользователь почти считает, что он видит собственное представление, а не веб-просмотр. В таком сценарии, показывающем, что «страница не может быть загружена», ошибка нелепо, что я обычно делаю в такой ситуации: я загружаю пустую страницу и показываю тост-сообщение, как показано ниже

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

Вы можете использовать запрос GET для получения содержимого страницы, а затем отображать эти данные с помощью Webview , таким образом, вы не используете несколько вызовов сервера. Альтернативу вы можете использовать Javascript для проверки объекта DOM на достоверность.

Возможно, я неправильно понимаю вопрос, но похоже, что вы говорите, что получаете обратный вызов с ошибкой, и вы просто спрашиваете, что является лучшим способом не показывать ошибку? Почему бы вам просто не удалить веб-представление с экрана и / или показать еще один вид поверх него?

Я полагаю, что если вы настаиваете на этом, вы можете просто проверить, есть ли ресурс до вызова функции loadURL. Просто просто переопределите функции и сделайте проверку перед вызовом super ()

ЗАМЕЧАНИЕ (возможно, вне темы): В http существует метод HEAD, который описывается следующим образом:

Метод HEAD идентичен GET, за исключением того, что сервер НЕ ДОЛЖЕН возвращать тело сообщения в ответ

Этот метод может быть удобен. В любом случае, как бы вы это реализовали … проверьте этот код:

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

Вы можете попробовать эту проверку, используя

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

Я бы просто изменил веб-страницу на все, что вы используете для обработки ошибок:

 getWindow().requestFeature(Window.FEATURE_PROGRESS); webview.getSettings().setJavaScriptEnabled(true); final Activity activity = this; webview.setWebChromeClient(new WebChromeClient() { public void onProgressChanged(WebView view, int progress) { // Activities and WebViews measure progress with different scales. // The progress meter will automatically disappear when we reach 100% activity.setProgress(progress * 1000); } }); webview.setWebViewClient(new WebViewClient() { public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { Toast.makeText(activity, "Oh no! " + description, Toast.LENGTH_SHORT).show(); } }); webview.loadUrl("http://slashdot.org/"); 

Все это можно найти на http://developer.android.com/reference/android/webkit/WebView.html

Сегодня я работаю над этой проблемой, чтобы избавиться от этих раздражительных страниц ошибок Google. Это возможно с приведенным выше примером кода Android и множеством других форумов (спросите, как я знаю):

 wv.setWebViewClient(new WebViewClient() { public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { if (view.canGoBack()) { view.goBack(); } Toast.makeText(getBaseContext(), description, Toast.LENGTH_LONG).show(); } } }); 

Если вы поместите его в shouldOverrideUrlLoading () как еще один веб-клиент. По крайней мере, это работает на моем устройстве 2.3.6. Посмотрим, где еще он работает позже. Я уверен, что это только меня угнетает. Бит goBack – мой. Вы можете не хотеть этого.

Попробуй это

  @SuppressWarnings("deprecation") @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { // Your handling } @Override public void onReceivedError(WebView view, WebResourceRequest req, WebResourceError rerr) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { onReceivedError(view, rerr.getErrorCode(), rerr.getDescription().toString(), req.getUrl().toString()); } } 

Мы можем установить видимость webView в 0 (view.INVISIBLE) и показать сообщение. Этот код работает для моего приложения, работающего на lolipop.

 @SuppressWarnings("deprecation") @Override public void onReceivedError(WebView webView, int errorCode, String description, String failingUrl) { // hide webView content and show custom msg webView.setVisibility(View.INVISIBLE); Toast.makeText(NrumWebViewActivity.this,getString(R.string.server_not_responding), Toast.LENGTH_SHORT).show(); } @TargetApi(android.os.Build.VERSION_CODES.M) @Override public void onReceivedError(WebView view, WebResourceRequest req, WebResourceError rerr) { // Redirect to deprecated method, so you can use it in all SDK versions onReceivedError(view, rerr.getErrorCode(), rerr.getDescription().toString(), req.getUrl().toString()); } 

Здесь я нашел самое простое решение. Проверьте это ..

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

И вот isInterentConnection () метод …

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

Попробуйте это shouldOverrideUrlLoading , прежде чем перенаправлять на другую проверку URL для подключения к интернету на основе этой страницы, должны быть загружены или нет.

Переопределить метод WebViewClient

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

view.loadUrl('about:blank') имеет побочные эффекты, поскольку он отменяет исходную загрузку URL-адреса.