Нажатие на ссылку в Android WebView не запускает загрузку файла - PullRequest
0 голосов
/ 27 июня 2019

Мне нужно скачать файл, когда пользователь нажимает на ссылку в WebView. Действие работает правильно, когда я выполняю то же действие в приложении Chrome, но не работает в веб-просмотре Я ответил на несколько вопросов и попытался реализовать предоставленные решения, но это не работает.

Упомянутые вопросы Stackoverflow и упомянутые пробные решения.

Загрузка файла в WebView

Android Webview не вызывает загрузку файла href

Как скачать файлы с веб-браузера Android?

Код WebView, который я использовал,

    wv_main.getSettings().setJavaScriptEnabled(true);
    wv_main.getSettings().setDomStorageEnabled(true);
    wv_main.getSettings().setAllowFileAccess(true);
    wv_main.getSettings().setAllowFileAccessFromFileURLs(true);
    wv_main.getSettings().setAllowUniversalAccessFromFileURLs(true);
    wv_main.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
    wv_main.getSettings().setBlockNetworkLoads(false);
    wv_main.getSettings().setAllowContentAccess(true);
    wv_main.getSettings().setPluginState(WebSettings.PluginState.ON);
    wv_main.setDownloadListener(new DownloadListener() {
        @Override
        public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
            DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));

            request.setDescription("Download file...");
            request.setTitle(URLUtil.guessFileName(url, contentDisposition, mimetype));
            request.allowScanningByMediaScanner();
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); //Notify client once download is completed!
            request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, URLUtil.guessFileName(url, contentDisposition, mimetype));
            DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
            dm.enqueue(request);
            Toast.makeText(getApplicationContext(), "Downloading File", Toast.LENGTH_LONG).show();
        }
    });

    wv_main.setWebViewClient(new WebViewClient() {

        private int webViewPreviousState;
        private final int PAGE_STARTED = 0x1;
        private final int PAGE_REDIRECTED = 0x2;

        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
            // Get cert from SslError
            SslCertificate sslCertificate = error.getCertificate();
            Certificate cert = getX509Certificate(sslCertificate);
            if (cert != null && certificate != null) {
                try {
                    // Reference: https://developer.android.com/reference/java/security/cert/Certificate.html#verify(java.security.PublicKey)
                    cert.verify(certificate.getPublicKey()); // Verify here...
                    handler.proceed();
                } catch (CertificateException | NoSuchAlgorithmException | InvalidKeyException | NoSuchProviderException | SignatureException e) {
                    super.onReceivedSslError(view, handler, error);
                    e.printStackTrace();
                }
            } else {
                super.onReceivedSslError(view, handler, error);
            }
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String urlNewString) {
            webViewPreviousState = PAGE_REDIRECTED;
            wv_main.loadUrl(urlNewString);
            return true;
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            webViewPreviousState = PAGE_STARTED;
            Log.e("Start Loading", "Start Loading.........");
            /*if (dialog == null || !dialog.isShowing())
            dialog = ProgressDialog.show(MainActivity.this, "", "Loading", true, true);*/
        }

        @Override
        public void onPageFinished(WebView view, String url) {

            if (webViewPreviousState == PAGE_STARTED) {
                //dialog.dismiss();
                Log.e("Loading Done", "Loading Done.........");
            }
        }

        @Override
        public void onReceivedError(WebView view, WebResourceRequest request,
                                    WebResourceError error) {
            super.onReceivedError(view, request, error);
            Toast.makeText(SecretLinkBrowserActivity.this, "Error:" + error.toString(), Toast.LENGTH_SHORT).show();
        }
    });
    wv_main.setWebChromeClient(new WebChromeClient() {
        @Override
        public void onPermissionRequest(final PermissionRequest request) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                request.grant(request.getResources());
            }
        }

        @Override
        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {

            Log.d("LogTag", message);
            result.confirm();
            return true;
        }
    });

Во время отладки я заметил, что при нажатии на ссылку shouldOverrideUrlLoading() не вызывается. Сайт загружает только то, что он использовал doPostBack(), который генерировал URL-адрес динамически и загружал файл.

1 Ответ

0 голосов
/ 27 июня 2019

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

wv_main.setDownloadListener(new DownloadListener() {
public void onDownloadStart(String url, String userAgent,
            String contentDisposition, String mimetype,
            long contentLength) {
    Intent i = new Intent(Intent.ACTION_VIEW);
    i.setData(Uri.parse(url));
    startActivity(i);
}
});

Но я полагаю, вы хотите использовать менеджер загрузок, вам не хватает вызова метода setDestinationUri, должно быть что-то вроде этого

DownloadManager.Request request=new DownloadManager.Request(Uri.parse(url))
           .setTitle("Dummy File")// Title of the Download Notification
           .setDescription("Downloading")// Description of the Download Notification
           .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)// Visibility of the download Notification
           .setDestinationUri(Uri.fromFile(file))// Uri of the destination file
           .setRequiresCharging(false)// Set if charging is required to begin the download
           .setAllowedOverMetered(true)// Set if download is allowed on Mobile network
           .setAllowedOverRoaming(true);// Set if download is allowed on roaming network
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...