无法使用下载管理器在 android webview 中下载 excel
Posted
技术标签:
【中文标题】无法使用下载管理器在 android webview 中下载 excel【英文标题】:can't download excel in android webview using Download Manager 【发布时间】:2021-12-29 22:26:31 【问题描述】:我在 android webview 中显示 web url。然后在网上有一个下载报告菜单(.xls)
我尝试使用下载管理器,以便可以通过我创建的 web 视图下载它。但结果总是失败。
如果需要,这是我的代码
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()
)
我没有其他想法,提前非常感谢您的所有帮助^^
【问题讨论】:
是因为.xls吗?尝试下载 .jpg 文件作为测试。 @blackapps 我尝试下载该图像,并且成功了。我应该检查什么才能下载生成的 excel 文件? 【参考方案1】:在开始请求之前,您是否已请求 WRITE_EXTERNAL_STORAGE 的权限?如果是,请尝试将这些添加到您的请求中(我无法在 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();
如果您没有请求权限,请尝试在 onDownload start 上执行此操作(注意我写的 cmets,它们应该会有所帮助):
//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.
downloadDialog
是一种方法,在该方法中我只显示“你想保存文件”对话框,如果用户积极响应,我会使用你在 onDownloadStart 中创建的请求 + 行中所写的内容在我的答案的顶部。当然,如果您愿意,您可以跳过对话框部分,也可以使用我在下载开始时保存的参数字段,而不是将参数直接传递给 showRationaleDialog、AskForPemission 和 downloadDialog
总而言之,您所做的是:
根据SDK级别检查是否需要请求权限 检查您是否已获得许可,否则用户应该会看到一条消息,说明您为什么需要他的许可 如果需要,请请求许可 调用下载函数我希望它对逻辑有所帮助,即使它是在 Java 中而不是 Kotlin 中!
【讨论】:
DownloadManager 不需要这些权限。 我关注了,结果还是下载不成功以上是关于无法使用下载管理器在 android webview 中下载 excel的主要内容,如果未能解决你的问题,请参考以下文章
Android SDK 管理器在选择存储库时出现“无法获取 URL https://dl-ssl.google.com/android/repository/repository.xml”错误
android studio 4.0 中的 AVD 管理器在哪里
我可以使用 Android Studio Avd 管理器在 Windows 上运行 iOS 模拟器吗?
使用 Android 帐户管理器在我的服务器上验证使用 FB 登录的用户