简体   繁体   English

无法使用下载管理器在 android webview 中下载 excel

[英]can't download excel in android webview using Download Manager

I display web url in android webview.在android Z5A98E2840FD0141780D854E48C608D中显示web url then on the web have a download report menu (.xls)然后在 web 上有一个下载报告菜单 (.xls)

I've tried to use the download manager so I can download it through the webview that I created.我尝试使用下载管理器,因此我可以通过我创建的 webview 下载它。 but the result is always failed.但结果总是失败。

If needed this is my code如果需要,这是我的代码

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

从网络上的报告菜单显示

这是我下载失败的通知显示

I have no other ideas, In advance thank you very much for all the help ^^我没有其他想法,提前非常感谢您的所有帮助^^

Have you asked for permission to WRITE_EXTERNAL_STORAGE before starting the request?在开始请求之前,您是否请求了WRITE_EXTERNAL_STORAGE权限 If yes, try adding these to your request (I can't help you in Kotlin, but this is my Java equivalent):如果是,请尝试将这些添加到您的请求中(我无法在 Kotlin 中为您提供帮助,但这是我的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();

If you haven't asked for permissions try doing this onDownload start (pay attention to the comments I've written, they should be helpful):如果您没有请求权限,请尝试在 onDownload start 上执行此操作(注意我写的评论,它们应该会有所帮助):

//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
                        && 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.
        }
    }

The downloadDialog is a method in which I just show a "Do you want to save file" dialog and if the user responds positively I use pretty much what you have written inside your onDownloadStart where you create your request + the rows at the top of my answer. downloadDialog是一种方法,在该方法中我只显示“您要保存文件”对话框,如果用户做出积极响应,我会使用您在 onDownloadStart 中编写的内容,您可以在其中创建请求 + 顶部的行回答。 You can skip the dialog part if you want to of course and also you can use the parameter fields I held on download start instead of passing the arguments directly to the showRationaleDialog, AskForPemission and downloadDialog如果您愿意,当然可以跳过对话框部分,也可以使用我在下载开始时保存的参数字段,而不是将 arguments 直接传递给 showRationaleDialog、AskForPemission 和 downloadDialog

In summary what you do is:总之,你要做的是:

  • Check if you need to ask for permission depending on the SDK level根据 SDK 级别检查是否需要请求权限
  • Check if you have been given permission, or the user should see a message on why you need his permission检查您是否已获得许可,或者用户应该会看到一条消息,说明您为什么需要他的许可
  • If you need to, you request for permission如果你需要,你请求许可
  • Call the download function调用下载function

I hope it helps with the logic, even though it's in Java not Kotlin!我希望它对逻辑有所帮助,即使它在 Java 而不是 Kotlin 中!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM