简体   繁体   中英

File is corrupted showing when open it from intent after download by download Manager android

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.

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.

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. `

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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