2

I am calling below function to download a binary file.

fun downloadFile(
        baseActivity: Context,
        batteryId: String,
        downloadFileUrl: String?,
        title: String?
    ): Long {
        val directory =
            File(Environment.getExternalStorageDirectory().toString() + "/destination_folder")

        if (!directory.exists()) {
            directory.mkdirs()
        }
        //Getting file extension i.e. .bin, .mp4 , .jpg, .png etc..
        val fileExtension = downloadFileUrl?.substring(downloadFileUrl.lastIndexOf("."))
        val downloadReference: Long
        var objDownloadManager: DownloadManager =
            baseActivity.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
        val uri = Uri.parse(downloadFileUrl)
        val request = DownloadManager.Request(uri)

        //Firmware file name as batteryId and extension
        firmwareFileSubPath = batteryId + fileExtension
        request.setDestinationInExternalPublicDir(
            Environment.DIRECTORY_DOWNLOADS,
            "" + batteryId + fileExtension
        )
        request.setTitle(title)
        downloadReference = objDownloadManager.enqueue(request) ?: 0

        return downloadReference
    }

Once the file got downloaded I am receiving it in below onReceive() method of Broadcast receiver:

override fun onReceive(context: Context, intent: Intent) {
                if (intent.action == DownloadManager.ACTION_DOWNLOAD_COMPLETE) {
                    intent.extras?.let {
                        //retrieving the file
                        val downloadedFileId = it.getLong(DownloadManager.EXTRA_DOWNLOAD_ID)
                        val downloadManager =
                            getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
                        val uri: Uri = downloadManager.getUriForDownloadedFile(downloadedFileId)
                        viewModel.updateFirmwareFilePathToFirmwareTable(uri)
                    }
                }
            }

I am downloading the files one by one and wants to know that which file is downloaded. Based on the particular file download, I have to update the entry in my local database.

So, here in onReceive() method how can I identify that which specific file is downloaded?

Thanks.

Jaimin Modi
  • 1,530
  • 4
  • 20
  • 72
  • if(!directory.mkdirs()) return; Display a toast too to inform the user. – blackapps Jul 28 '21 at 09:45
  • You have an uri and that defines the file. Nobody needs more. Why would you? And you have the downloadReference for the source file. – blackapps Jul 28 '21 at 09:47
  • @blackapps How can I check? Please explain in details. – Jaimin Modi Jul 28 '21 at 09:55
  • One way to identify your download is when you enqueue your download, it'll return you id that is unique across the system. So, you'll need to keep that id somewhere when you call this: `objDownloadManager.enqueue(request)` and then on receive method you can compare using that id to identify your download. – Jeel Vankhede Jul 28 '21 at 10:17

2 Answers2

2

One way to identify your multiple downloads simultaneously is to track id returned from DownloadManager to your local db mapped to given entry when you call objDownloadManager.enqueue(request).

Document of DownloadManager.enquque indicates that:

Enqueue a new download. The download will start automatically once the download manager is ready to execute it and connectivity is available.

So, if you store that id mapped to your local database entry for given record then during onReceive() you can identify back to given record.

override fun onReceive(context: Context, intent: Intent) {
            if (intent.action == DownloadManager.ACTION_DOWNLOAD_COMPLETE) {
                intent.extras?.let {
                    //retrieving the file
                    val downloadedFileId = it.getLong(DownloadManager.EXTRA_DOWNLOAD_ID)
                    // Find same id from db that you stored previously
                    val downloadManager =
                        getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
                    val uri: Uri = downloadManager.getUriForDownloadedFile(downloadedFileId)
                    viewModel.updateFirmwareFilePathToFirmwareTable(uri)
                }
            }
        }

Here, it.getLong(DownloadManager.EXTRA_DOWNLOAD_ID) returns you the same id for which download was started previously and enqueue returned.

Document for EXTRA_DOWNLOAD_ID indicates that:

Intent extra included with ACTION_DOWNLOAD_COMPLETE intents, indicating the ID (as a long) of the download that just completed.

Jeel Vankhede
  • 11,592
  • 2
  • 28
  • 58
1

You have the Uri of file, now simply get the file name to identify the file, you can use following function to get file name

fun getFileName(uri: Uri): String?  {
    var result: String? = null
    when(uri.scheme){
        "content" -> {
             val cursor: Cursor? = getContentResolver().query(uri, null, null, null, null)
             cursor.use {
                 if (it != null && it.moveToFirst()) {
                     result = it.getString(it.getColumnIndex(OpenableColumns.DISPLAY_NAME))
                 }
             }
        }
        else -> {
            val lastSlashIndex = uri.path?.lastIndexOf('/')
            if(lastSlashIndex != null && lastSlashIndex != -1) {
                 result = uri.path!!.substring(lastSlashIndex + 1)
            }
        }
    }
    return result
}
mightyWOZ
  • 7,946
  • 3
  • 29
  • 46