下载管理器下载后从 Intent 打开文件时显示文件已损坏 android
File is corrupted showing when open it from intent after download by download Manager android
在此功能中,我从 URL 下载文件,完成下载后我从 intent 打开该文件,但它显示文件已损坏且无法打开
这是我下载文件并从 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()
}
}
}
所以可以告诉我我在哪里弄错了,为什么它在下载后显示文件已损坏,我通过从文件管理器打开它来检查该文件,它工作正常。
出了什么问题?
我看到在 downloadFile
方法中 > 在 try
中,您正在通过解析创建 url 的 Uri
。但是,url 无法转换为 Uri
,因为它在设备上不存在!
如何解决?
替换
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()
}
}
有
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()
}
}
希望对您有所帮助。
您应该从下载管理器中获取内容方案,而不是该文件方案。
尝试:
Uri downloadmanageruri = ( (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE))
.getUriForDownloadedFile(downloadId);
那应该是一个内容方案,您不需要 FileProvider。 `
在此功能中,我从 URL 下载文件,完成下载后我从 intent 打开该文件,但它显示文件已损坏且无法打开
这是我下载文件并从 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()
}
}
}
所以可以告诉我我在哪里弄错了,为什么它在下载后显示文件已损坏,我通过从文件管理器打开它来检查该文件,它工作正常。
出了什么问题?
我看到在 downloadFile
方法中 > 在 try
中,您正在通过解析创建 url 的 Uri
。但是,url 无法转换为 Uri
,因为它在设备上不存在!
如何解决?
替换
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()
}
}
有
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()
}
}
希望对您有所帮助。
您应该从下载管理器中获取内容方案,而不是该文件方案。
尝试:
Uri downloadmanageruri = ( (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE))
.getUriForDownloadedFile(downloadId);
那应该是一个内容方案,您不需要 FileProvider。 `