Основные внутренние ссылки не работают в сотовом приложении?

Внутренние ссылки, похоже, не работают в Android версии 3 в моем опубликованном приложении. На данный момент мое приложение нацелено на Froyo.

Приложение отлично работает на тоннах телефонов, но моя новая Galaxy Tab не может обрабатывать внутренние ссылки! Он может обрабатывать их на странице html, то есть:

<a href="#faq">Go to faq</a>  <!-- goes to FAQ link -->

Переход к тегу ниже на той же странице:

<a name="faq" id="faq"></a>  

Однако из другого html файла, то есть страницы индекса, ссылка больше не работает в Honeycomb:

<a href="mainpage.html#faq">FAQ</a>  <!-- goes to error page -->

Кроме того, если я перейду во внутреннюю ссылку и оттуда перейду по ссылке на другую страницу, а затем нажмите кнопку "Назад" (она переопределена для перехода на предыдущую страницу веб-просмотра), вы получите ту же ошибку, что:

The webpage at file:///android_asset/folder/mainpage.html#faq might be temporarily    down or it may have moved permanently to a new web address

WTF! Веб-просмотр был только на странице, но вы ударили назад на 1 секунду позже, и он не может его найти. Он также не может ссылаться на другую страницу html, но все работает отлично в 1.x, 2.x, просто не 3.1 (не пробовал 3.0)

ПРИМЕЧАНИЕ. Я видел этот почти идентичный вопрос: android_asset не работает на Honeycomb? Но в моем пути к ресурсам нет пробелов.

Я пробовал с веб-клиентом и без него, и попробовал настройки DOM и кеша безрезультатно. Вот пример того, что у меня есть в oncreate:

        browser = new WebView(this);
//  browser = (WebView) findViewById(R.id.webkit);  // tried with XML and without
    browser.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
    browser.getSettings().setJavaScriptEnabled(true);
    browser.getSettings().setPluginsEnabled(true);
//  browser.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
//  browser.getSettings().setUseWideViewPort(true);
    browser.setBackgroundColor(Color.parseColor("#333333"));
    browser.setInitialScale(1);
    browser.getSettings().setBuiltInZoomControls(true);


    final Activity MyActivity = this;
    browser.setWebChromeClient(new WebChromeClient() {

        public void onProgressChanged(WebView view, int progress) {
            // Make the bar disappear after URL is loaded, and changes
            // string to Loading...

            setProgressBarIndeterminateVisibility(true);

            MyActivity.setTitle("  Loading . . . " + progress + "%");
            MyActivity.setProgress(progress * 100); // Make the bar

            if (progress == 100) {
                setTitle("  APP TITLE YADA YADA");
                setProgressBarIndeterminateVisibility(false);
            }
        }
    });
    browser.setWebViewClient(new WebViewClient() {
        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
        {
            // Handle the error
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url)
        {
            view.loadUrl(url);  // note I tried with and without overriding this 
            return true;
        }

    });
    setContentView(browser);

    browser.loadUrl("file:///android_asset/folder/page.html");

Ответ 1

Вот мой код обхода, чтобы ошибка была прозрачной для пользователя.
Определите WebViewClient для браузера и включите что-то вроде следующего для onReceivedError:

        @Override
    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
    {
        if (failingUrl.contains("#")) {
            Log.v("LOG", "failing url:"+ failingUrl);
            final int sdkVersion = Integer.parseInt(Build.VERSION.SDK);
            if (sdkVersion > Build.VERSION_CODES.GINGERBREAD) {
                String[] temp;
                temp = failingUrl.split("#");
                view.loadUrl(temp[0]); // load page without internal link

                try {
                    Thread.sleep(400);
                } catch (InterruptedException e) {

                    e.printStackTrace();
                }
            }

            view.loadUrl(failingUrl);  // try again
        } else {
             view.loadUrl("file:///android_asset/tableofcontents.html");
        }
    }
    });

Это приводит к тому, что веб-просмотр сначала загружает страницу без # ссылки, затем засыпает за .4 секунды, а затем снова загружает полный URL. Я решил сделать этот трюк для планшетов только с помощью sdkVersion. Если есть другая ошибка, я загружаю другую страницу, tableofcontents.html. Это работает, чтобы исправить проблему на моей вкладке Galaxy.

Ответ 2

Вот решение, которое я использую. Работает одинаково на всех платформах Android (протестировано на всех 1.6 до 4.0.1)

Загрузить файл, как обычно, без точки привязки. Например:.

webview.loadUrl("file:///android_asset/file.html");

Загрузка URL без точки привязки (например, файл:///android_asset/file.html), и добавьте:

webview.setWebViewClient(new WebViewClient()
{
    public void onPageFinished(WebView view, String url)
    {
        if (this.anchor != null)
        {
            view.loadUrl("javascript:window.location.hash='" + this.anchor + "'");
            this.anchor = null;
        }
    }
});

где якорь - это точка привязки, к которой вы хотите перейти.

вы должны убедиться, что javascript включен:

WebSettings webSettings = webview.getSettings();
webSettings.setJavaScriptEnabled(true);

Это для загрузки файла в веб-просмотр. Теперь, если вы хотите поймать внутренние ссылки, которые теперь сломаны, как это предлагается в другом ответе, переопределите метод onReceivedError и вставьте что-то вроде:

    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
    {
        int found = failingUrl.indexOf('#');

        if (found > 0)
        {
            anchor = failingUrl.substring(found + 1, failingUrl.length());
            view.loadUrl(failingUrl.substring(0, found));
        }
    }