Android WebView 无法在 UIDAI/Aadhaar 网站上的 DownloadStart 上下载文件

Sag*_*iri 5 android download-manager webview webclient-download

我正在使用 Webview 从 UIDAI 网站在我的应用程序中下载 .zip 文件。但是,当 DownloadListener 被调用时,它会返回正确的数据,但会在该 .zip 文件中下载该 HTML 网页,而不是下载实际文件。而当我尝试通过 chrome 下载相同的 zip 时。它正在下载正确的 zip 文件。请帮我解决这个问题。为什么在这个特定网站 ( https://resident.uidai.gov.in/offline-kyc) 的webview 中会发生这种情况,而使用相同的下载侦听器我可以在其他网站上下载文件?

我的代码:

public class wvDownloadFile extends AppCompatActivity {

private static final int MY_PERMISSION_REQUEST_CODE = 123;
String QT_TAG = "download test";

String fileName = "test";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    WebView wv = findViewById(R.id.web_view);

    checkPermission();
    String url = "https://resident.uidai.gov.in/offline-kyc";
    wv.loadUrl(url);
    wv.getSettings().setJavaScriptEnabled(true);
    wv.getSettings().setSupportMultipleWindows(true);
    wv.getSettings().setAllowContentAccess(true);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        wv.getSettings().setAllowUniversalAccessFromFileURLs(true);
    }

    wv.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
    wv.getSettings().setBuiltInZoomControls(false);
    wv.getSettings().setJavaScriptEnabled(true);
    wv.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
    wv.getSettings().setAllowFileAccess(true);
    wv.getSettings().setAllowContentAccess(true);
    wv.getSettings().setAllowFileAccess(true);
    wv.getSettings().setAllowFileAccessFromFileURLs(true);
    wv.getSettings().setAllowUniversalAccessFromFileURLs(true);
    wv.getSettings().setDomStorageEnabled(true);

    // userAgent:  downloadlistener: Mozilla/5.0 (Linux; Android 7.1.2; Redmi Y1 Lite Build/N2G47H; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.132 Mobile Safari/537.36
    // mimeType: application/zip
    // contentLength: 5445
    // contentDispostition: attachment; filename=offlineaadhaar20190925055612130.zip
    // url: https://resident.uidai.gov.in/offline-kyc

    wv.setDownloadListener(new DownloadListener() {
        @Override
        public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) {


            fileName = URLUtil.guessFileName(url, contentDisposition, mimeType);

            Log.i(QT_TAG, "downloadlistener0: " + userAgent + " " + mimeType + " " + contentLength + " " + contentDisposition + " " + url);
            DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));

            request.setMimeType(mimeType);
            //------------------------COOKIE!!------------------------
            String cookies = CookieManager.getInstance().getCookie(url);
            request.addRequestHeader("cookie", cookies);
            //------------------------COOKIE!!------------------------
            request.addRequestHeader("User-Agent", userAgent);
            request.setDescription("Downloading file...");
            request.setTitle(URLUtil.guessFileName(url, contentDisposition, mimeType));
            request.allowScanningByMediaScanner();
            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
            request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, URLUtil.guessFileName(url, contentDisposition, mimeType));
            DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
            dm.enqueue(request);
            Toast.makeText(getApplicationContext(), "Downloading File0 ", Toast.LENGTH_LONG).show();
        }
    });

    wv.setWebViewClient(new WebViewClient() {

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            Log.i(QT_TAG, "listener  overide url ");
            view.loadUrl(url);
            return true;
        }
    });
}

protected void checkPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                // show an alert dialog
                AlertDialog.Builder builder = new AlertDialog.Builder(wvDownloadFile.this);
                builder.setMessage("Write external storage permission is required.");
                builder.setTitle("Please grant permission");
                builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        ActivityCompat.requestPermissions(
                                wvDownloadFile.this,
                                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                                MY_PERMISSION_REQUEST_CODE
                        );
                    }
                });
                builder.setNeutralButton("Cancel", null);
                AlertDialog dialog = builder.create();
                dialog.show();
            } else {
                // Request permission
                ActivityCompat.requestPermissions(
                        wvDownloadFile.this,
                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        MY_PERMISSION_REQUEST_CODE
                );
            }
        } else {
            // Permission already granted
        }
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSION_REQUEST_CODE: {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission granted
            } else {
                // Permission denied
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

}

Vij*_*jay 1

问题是我们没有从 downloadListener 获取从 Web 视图到 downloadManager 的链接

wv.setDownloadListener(new DownloadListener() {

    @Override
    public void onDownloadStart(String url, String userAgent, 
                       String contentDisposition, String mimeType, long contentLength) {

             Log.d(TAG, "onDownloadStart: " + url); // taking debug log

    }
Run Code Online (Sandbox Code Playgroud)

结果将类似于 url = https://resident.uidai.gov.in/offline-kyc。由于 cookie 会话(出于 UIDAI 的安全原因),这不是文件的下载链接。错误不是来自 downloadManager,错误是 OnDownloadListener 没有使用 cookie 会话获取链接。

我必须这样做,所以这是另一种方法,

  1. 使用 chromeCustomTabs链接
  2. 用户下载 zip 文件后,我告诉他们共享共享代码。
  3. 之后使用 string.compareTo 方法查找最新(按字母顺序排列顶部)下载的文件,其中包含“offlineaadhaar”和“zip”
  4. 之后使用共享代码解压缩并创建同名文件夹
  5. 从该文件夹获取 XML 文件的路径
  6. 解析 XML,然后将其用于您的任务

如果有人使用 webView 找到解决方案,请分享