'I had this crash several times now, I have seen a few ways to solve this issue but first I would like to make this crash happen again

Fatal Exception: android.database.CursorIndexOutOfBoundsException
Index 0 requested, with a size of 0

This is my function that I have in my FileHelper class:

    fun downloadFile(url: String, fileName: String, completion: (DataResponse<File>) -> Unit) {

        val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager

        val uri = Uri.parse(url)

        val request = DownloadManager.Request(uri).apply {
            setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI or DownloadManager.Request.NETWORK_MOBILE)
                .setAllowedOverRoaming(false)
                .setTitle(fileName)
                .setDescription("")
                .setDestinationInExternalFilesDir(
                    context,
                    Environment.DIRECTORY_DOWNLOADS,
                    fileName
                )
        }

        val downloadId = downloadManager.enqueue(request)

        val query = DownloadManager.Query().setFilterById(downloadId)

        Thread {

            var downloading = true
            var downloadRepeatCount = 0
            while (downloading) {
                val cursor: Cursor = downloadManager.query(query)
                cursor.moveToFirst()

                val status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
                if (status == DownloadManager.STATUS_SUCCESSFUL) {
                    val file =
                        File("${context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)}${fileName}")
                    downloading = false
                    completion(getSuccessResponseData(file))
                } else if (status == DownloadManager.STATUS_FAILED) {
                    downloading = false
                    sendFirebaseError("status STATUS_FAILED", url, fileName, uri)
                    completion(getErrorResponseData())
                } else {
                    if (downloadRepeatCount < 10 && status == DownloadManager.STATUS_PAUSED) {
                        Thread.sleep(1000)
                        downloadRepeatCount++
                    } else if (status == DownloadManager.PAUSED_QUEUED_FOR_WIFI) {
                        downloading = false
                        sendFirebaseError("status PAUSED_QUEUED_FOR_WIFI", url, fileName, uri)
                        completion(getErrorResponseData())
                    } else if (status == DownloadManager.ERROR_INSUFFICIENT_SPACE && status == DownloadManager.ERROR_DEVICE_NOT_FOUND) {
                        downloading = false
                        sendFirebaseError("status ERROR_INSUFFICIENT_SPACE and ERROR_DEVICE_NOT_FOUND", url, fileName, uri)
                        completion(getErrorResponseData())
                    } else if (status > 10) {
                        downloading = false
                        sendFirebaseError("status > 10", url, fileName, uri)
                        completion(getErrorResponseData())
                    } else {
                        downloading = true
                    }
                }
                cursor.close()
            }

        }.start()

    }

When I searched for this crash I have received the information about how to fix this issue. However, I want to make that crash in purpose in order to be sure about the reason of it. In addition I wonder that if possible, cursor did not crash but the non fatal error would cause download manager to go the DownloadManager.STATUS_FAILED condition. I want to discuss about those topics.



Solution 1:[1]

Your query matched no rows. You need to check the return value of cursor.moveToFirst() and call cursor.getInt() only if it returned true.

Solution 2:[2]

You can check cursor's size using this method :

if (cursor != null && cursor.getCount() > 0){
    // Do your stuff
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 laalto
Solution 2 Dev4Life