Предотвратить показ веб-страницы "веб-страница недоступна"
У меня есть приложение, которое широко использует 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 фактически не очищает представление.
Ответы
Ответ 1
Сначала создайте свою собственную страницу ошибок в 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");
}
});
Ответ 2
Лучшее решение, которое я нашел, - загрузить пустую страницу в событие OnReceivedError следующим образом:
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
view.loadUrl("about:blank");
}
Ответ 3
Наконец, я решил это. (Он работает до сих пор..)
Мое решение такое...
-
Подготовьте макет, чтобы показать, когда произошла ошибка вместо веб-страницы (грязная страница, не найденная сообщение). В макете есть одна кнопка "RELOAD" с некоторыми сообщениями руководства.
-
Если возникла ошибка, запомните использование логического значения и покажите макет, который мы подготовим.
- Если пользователь нажмет кнопку "RELOAD", установите для mbErrorOccured значение false. И установите mbReloadPressed в true.
- Если 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>
Ответ 4
Ознакомьтесь с обсуждением в Android WebView onReceivedError(). Это довольно долго, но, похоже, консенсус заключается в том, что: а) вы не можете остановить страницу "недоступная страница", но б) вы всегда можете загрузить пустую страницу после получения onReceivedError
Ответ 5
Когда веб-просмотр встроен в какой-то пользовательский вид, так что пользователь почти уверен, что он видит собственное представление, а не веб-просмотр. В таком сценарии, показывающем, что "страница не может быть загружена", ошибка нелепая, что я обычно делаю в такой ситуации, я загружаю пустую страницу и показываю тост-сообщение, как показано ниже
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);
}
});
Ответ 6
Вы можете использовать запрос GET
, чтобы получить содержимое страницы, а затем отобразить эти данные с помощью Webview
, таким образом, вы не используете несколько вызовов сервера. Альтернативу вы можете использовать Javascript
, чтобы проверить объект DOM
на достоверность.
Ответ 7
Возможно, я неправильно понимаю вопрос, но похоже, что вы говорите, что получаете обратный вызов с ошибкой, и вы просто спрашиваете, что является лучшим способом не показывать ошибку? Почему бы вам просто не удалить веб-представление с экрана и/или показать еще один вид поверх него?
Ответ 8
Я полагаю, что если вы настаиваете на этом, вы можете просто проверить, есть ли ресурс до вызова функции 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)
Ответ 9
Я бы просто изменил веб-страницу на все, что вы используете для обработки ошибок:
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
Ответ 10
Я работаю над этой проблемой, чтобы вырезать эти раздражительные страницы ошибок 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 - мой. Вы можете не хотеть этого.
Ответ 11
Попробуйте это
@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());
}
}
Ответ 12
Мы можем установить видимость 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());
}
Ответ 13
Здесь я нашел самое легкое решение. проверьте это..
@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;
}
Ответ 14
Мне пришлось столкнуться с этой проблемой, а также попытался решить ее с разных точек зрения. Наконец, я нашел решение, используя один флаг, чтобы проверить, произошла ли ошибка.
... extends WebViewClient {
boolean error;
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
showLoading(true);
super.onPageStarted(view, url, favicon);
error = false; // IMPORTANT
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if(!error) {
Observable.timer(100, TimeUnit.MICROSECONDS, AndroidSchedulers.mainThread())
.subscribe((data) -> view.setVisibility(View.VISIBLE) );
}
showLoading(false);
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
view.stopLoading();
view.setVisibility(View.INVISIBLE)
error = true;
// Handle the error
}
@Override
@TargetApi(android.os.Build.VERSION_CODES.M)
public void onReceivedError(WebView view,
WebResourceRequest request,
WebResourceError error) {
this.onReceivedError(view, error.getErrorCode(),
error.getDescription().toString(),
request.getUrl().toString());
}
}
Таким образом, я скрываю страницу каждый раз, когда появляется ошибка, и показываю ее, когда страница загрузилась правильно.
Также добавлена небольшая задержка в случае.
Я избежал решения по загрузке пустой страницы, так как она не позволяет вам делать webview.reload() позже из-за того, что добавляет эту новую страницу в историю навигации.
Ответ 15
попробуйте shouldOverrideUrlLoading, прежде чем перенаправлять на другую проверку URL-адреса для подключения к интернету на этой странице должно быть загружено или нет.
Ответ 16
переопределить метод WebViewClient
@Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
view.clearView();
}
view.loadUrl('about:blank')
имеет побочные эффекты, поскольку он отменяет исходную загрузку URL-адреса.