не удается загрузить excel в веб-представлении Android с помощью диспетчера загрузки

#android #kotlin #webview #android-download-manager

Вопрос:

Я отображаю веб-адрес в веб-представлении Android. затем в Интернете есть меню отчета о загрузке (.xls).

Я попытался использовать менеджер загрузок, чтобы загрузить его через созданное мной веб-представление. но результат всегда оказывается неудачным.

Если нужно, это мой код

 webview.setDownloadListener(object : DownloadListener {
            override fun onDownloadStart(url: String, userAgent: String, contentDisposition: String, mimetype: String, contentLength: Long) {
                val request = DownloadManager.Request(Uri.parse(url))
                request.setTitle(URLUtil.guessFileName(url, contentDisposition, mimetype))
                request.setDescription("Downloading file...")
                request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
                request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, URLUtil.guessFileName(url, contentDisposition, mimetype))
                val dm = getSystemService(DOWNLOAD_SERVICE) as DownloadManager
                dm.enqueue(request)
                Toast.makeText(applicationContext, "Downloading...", Toast.LENGTH_SHORT).show()
                registerReceiver(onComplete, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
            }


            var onComplete: BroadcastReceiver = object : BroadcastReceiver() {
                override fun onReceive(context: Context, intent: Intent) {
                    Toast.makeText(applicationContext, "Downloading Complete", Toast.LENGTH_SHORT).show()
                }
            }
        })
 

отображение из меню отчета в Интернете

и это мое уведомление о неудачной загрузке

У меня нет других идей, заранее большое вам спасибо за всю помощь ^^

Комментарии:

1. Это из-за .xls? Попробуйте загрузить файл .jpg в качестве теста.

2. @blackapps Я попытался загрузить изображение, и это сработало. Что я должен проверить, чтобы сгенерированный файл Excel можно было загрузить?

Ответ №1:

Вы запрашивали разрешение на запись EXTERNAL_STORAGE перед началом запроса? Если да, попробуйте добавить их в свой запрос (я не могу помочь вам в Котлине, но это мой эквивалент Java). :

 String cookie= CookieManager.getInstance().getCookie(url);
//Add cookie and User-Agent to request
request.addRequestHeader("Cookie",cookie);
request.addRequestHeader("User-Agent",userAgent);
//file scanned by MediaScanner
request.allowScanningByMediaScanner();
 

Если вы не запрашивали разрешения, попробуйте выполнить это при запуске загрузки (обратите внимание на комментарии, которые я написал, они должны быть полезны). :

 //Declare these on top of your class
private String durl, duserAgent, dcontentDisposition, dmimetype;


webView.setDownloadListener(new DownloadListener() {
@Override
   public void onDownloadStart(final String url, final String userAgent, String 
   contentDisposition, String mimetype, long contentLength) {

                //Hold the onDownloadStart parameters to fields so that you can
                //use them inside onRequestPermissionsResult to call the 
                //download method
                durl = url;
                duserAgent = userAgent;
                dcontentDisposition = contentDisposition;
                dmimetype = mimetype;


                //Checking runtime permission for devices above Marshmallow.
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

                    if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                        showRationaleDialog(url, userAgent, contentDisposition, mimetype);
                    } else {
                        AskForPemission(url, userAgent, contentDisposition, mimetype);
                    }
                } else {
                    //Code for devices below API 23 or Marshmallow
                    //Log.v(TAG,"Permission is granted");
                    downloadDialog(url, userAgent, contentDisposition, mimetype);
                }
            }
   });

public void showRationaleDialog(final String url, final String userAgent, final String contentDisposition, final String mimetype){
        AlertDialog.Builder builder = new AlertDialog.Builder(Program_file_webview.this);
        builder.setIcon(R.drawable.icon_attention);
        builder.setTitle("Permission Needed");
        builder.setMessage("You have to grant permission to the app, in order to download the desired file");
        builder.setPositiveButton("OK", new DialogInterface.OnClickListener()
        {
            @Override
            public void onClick(DialogInterface dialog, int which)
            {
                AskForPemission(url,userAgent,contentDisposition,mimetype);
            }
        });
        builder.create().show();
    }

public void AskForPemission(String url, String userAgent, String contentDisposition, String mimetype){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    == PackageManager.PERMISSION_GRANTED) {
                //Log.v(TAG,"Permission is granted");
                downloadDialog(url,userAgent,contentDisposition,mimetype);
            } else {
                //Log.v(TAG,"Permission is revoked");
                //requesting permissions.
                ActivityCompat.requestPermissions(Program_file_webview.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXT_STORAGE);

            }
        }

    }

@Override
    public void onRequestPermissionsResult(int requestCode,
                                           String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case WRITE_EXT_STORAGE: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        amp;amp; grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    downloadDialog(durl,duserAgent,dcontentDisposition,dmimetype);
                    // permission was granted, yay! Do the
                    // contacts-related task you need to do.
                } else {
                    Toast.makeText(Program_file_webview.this, "You need to grant permission in order to download the file. Please allow it and try again.", Toast.LENGTH_SHORT).show();
                    mywebView.loadUrl(cmp_url);
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                }
                return;
            }

            // other 'case' lines to check for other
            // permissions this app might request.
        }
    }
 

Это downloadDialog метод, в котором я просто показываю диалоговое окно «Хотите ли вы сохранить файл», и если пользователь отвечает положительно, я использую в значительной степени то, что вы написали в своем onDownloadStart, где вы создаете свой запрос строки в верхней части моего ответа. Вы можете пропустить часть диалога, если хотите, конечно, а также вы можете использовать поля параметров, которые я удерживал при запуске загрузки, вместо того, чтобы передавать аргументы непосредственно в showRationaleDialog, AskForPemission и downloadDialog

Вкратце, то, что вы делаете, это :

  • Проверьте, нужно ли запрашивать разрешение в зависимости от уровня SDK
  • Проверьте, было ли вам дано разрешение, или пользователь должен увидеть сообщение о том, почему вам нужно его разрешение
  • Если вам это нужно, вы запрашиваете разрешение
  • Вызовите функцию загрузки

Я надеюсь, что это поможет с логикой, хотя это на Java, а не на Котлине!

Комментарии:

1. DownloadManager не нуждается в этих разрешениях.

2. Я следил, но результат все равно не удался