#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. Я следил, но результат все равно не удался