Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android WebView unable to download file on DownloadStart on UIDAI/Aadhaar Website

I am using Webview to download .zip file in my app from UIDAI website. But when DownloadListener is getting called It returns the correct data, but downloads that HTML webpage in that .zip file instead of downloading the actual file. whereas when I try downloading the same zip via chrome. It is downloading the correct zip file. Please help me with this problem. why is this happening in webview on this particular website (https://resident.uidai.gov.in/offline-kyc) whereas with the use of same download listener I am able to download files on other websites?

My code:

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

}

like image 422
Sagar Giri Avatar asked Nov 07 '22 13:11

Sagar Giri


1 Answers

Problem is that we are not getting the link from the web view to downloadManager from downloadListener

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

    }

the result will be like, url = https://resident.uidai.gov.in/offline-kyc . which is not a downloading link for the file, because of cookie session (for security reason from UIDAI). The fault is not from downloadManager, the fault is that the OnDownloadListener is not taking the link using cookie session.

I had to do it so here is an alternative way,

  1. Used chromeCustomTabs Link
  2. After user download the zip file, I tell them to share the share code.
  3. After that finding the lastest (means alphabetically top) downloaded file using string.compareTo method which contains "offlineaadhaar" and "zip"
  4. After that unzip it using share code and creating the same name folder
  5. Getting the path of the XML file from that folder
  6. parse the XML and then use it for your task

If someone finds the solution using webView then please share

like image 199
Vijay Avatar answered Nov 09 '22 23:11

Vijay