In this feature, I download the file from the URL and after completing the download I open that file from intent but it shows the file is corrupted and not open
here is my code for downloading the file and opening the file from intent
fun downloadFile(activity: Activity, url: String?, fileName: String?) {
try {
if (url != null && !url.isEmpty()) {
val uri: Uri = Uri.parse(url)
activity.registerReceiver(
attachmentDownloadCompleteReceive, IntentFilter(
DownloadManager.ACTION_DOWNLOAD_COMPLETE
)
)
val request: DownloadManager.Request = DownloadManager.Request(uri)
request.setMimeType(getMimeType(uri.toString()))
request.setTitle(fileName)
request.setDescription("Downloading attachment..")
request.allowScanningByMediaScanner()
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)
val dm: DownloadManager =
getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
dm.enqueue(request)
}
} catch (e: IllegalStateException) {
Toast.makeText(
activity,
"Please insert an SD card to download file",
Toast.LENGTH_SHORT
).show()
}
}
private fun getMimeType(url: String): String? {
var type: String? = null
val extension: String = MimeTypeMap.getFileExtensionFromUrl(url)
if (extension != null) {
val mime: MimeTypeMap = MimeTypeMap.getSingleton()
type = mime.getMimeTypeFromExtension(extension)
}
return type
}
var attachmentDownloadCompleteReceive: BroadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val action = intent.action
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE == action) {
val downloadId = intent.getLongExtra(
DownloadManager.EXTRA_DOWNLOAD_ID, 0
)
openDownloadedAttachment(context, downloadId)
}
}
}
private fun openDownloadedAttachment(context: Context, downloadId: Long) {
val downloadManager: DownloadManager =
context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
val query: DownloadManager.Query = DownloadManager.Query()
query.setFilterById(downloadId)
val cursor: Cursor = downloadManager.query(query)
if (cursor.moveToFirst()) {
val downloadStatus: Int =
cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
val downloadLocalUri: String =
cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI))
val downloadMimeType: String =
cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_MEDIA_TYPE))
if (downloadStatus == DownloadManager.STATUS_SUCCESSFUL && downloadLocalUri != null) {
openDownloadedAttachment(context, Uri.parse(downloadLocalUri), downloadMimeType)
}
}
cursor.close()
}
private fun openDownloadedAttachment(
context: Context,
attachmentUri: Uri,
attachmentMimeType: String
) {
var attachmentUri: Uri? = attachmentUri
if (attachmentUri != null) {
// Get Content Uri.
if (ContentResolver.SCHEME_FILE == attachmentUri.scheme) {
// FileUri - Convert it to contentUri.
val file = File(attachmentUri.path)
attachmentUri =
FileProvider.getUriForFile(
this,
BuildConfig.APPLICATION_ID ".fileprovider",
file
)
}
val openAttachmentIntent = Intent(Intent.ACTION_VIEW)
openAttachmentIntent.setDataAndType(attachmentUri, attachmentMimeType)
openAttachmentIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
try {
this.startActivity(openAttachmentIntent)
} catch (e: ActivityNotFoundException) {
Toast.makeText(
this,
"false",
Toast.LENGTH_LONG
).show()
}
}
}
So can tell me where I made mistake on this, why it shows the file is corrupted after downloading it and I check that file by opening it from the file manager and it's working fine.
CodePudding user response:
You should get a content scheme from download manager instead of that file scheme.
Try:
Uri downloadmanageruri = ( (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE))
.getUriForDownloadedFile(downloadId);
That should be a content scheme and you would not need FileProvider. `
CodePudding user response:
What is going wrong?
I see that in the downloadFile method > inside try, you are creating the Uri of the url by parsing it. But, the url cannot be converted to Uri as it does not exist on the device!
How to solve?
Replace
fun downloadFile(activity: Activity, url: String?, fileName: String?) {
try {
if (url != null && !url.isEmpty()) {
val uri: Uri = Uri.parse(url)
activity.registerReceiver(
attachmentDownloadCompleteReceive, IntentFilter(
DownloadManager.ACTION_DOWNLOAD_COMPLETE
)
)
val request: DownloadManager.Request = DownloadManager.Request(uri)
request.setMimeType(getMimeType(uri.toString()))
request.setTitle(fileName)
request.setDescription("Downloading attachment..")
request.allowScanningByMediaScanner()
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)
val dm: DownloadManager =
getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
dm.enqueue(request)
}
} catch (e: IllegalStateException) {
Toast.makeText(
activity,
"Please insert an SD card to download file",
Toast.LENGTH_SHORT
).show()
}
}
With
fun downloadFile(activity: Activity, url: String?, fileName: String?) {
try {
if (url != null && !url.isEmpty()) {
activity.registerReceiver(
attachmentDownloadCompleteReceive, IntentFilter(
DownloadManager.ACTION_DOWNLOAD_COMPLETE
)
)
val request: DownloadManager.Request = DownloadManager.Request(url)
request.setMimeType(getMimeType(uri.toString()))
request.setTitle(fileName)
request.setDescription("Downloading attachment..")
request.allowScanningByMediaScanner()
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName)
val dm: DownloadManager =
getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
dm.enqueue(request)
}
} catch (e: IllegalStateException) {
Toast.makeText(
activity,
"Please insert an SD card to download file",
Toast.LENGTH_SHORT
).show()
}
}
Hope it helps
