javaandroidkotlinandroid-download-manager

Android DownloadManager failed downloading with reason ERROR_TOO_MANY_REDIRECTS, how can I fix this issue for targeting API level 31 or higher?


I am using android.app.DownloadManager for downloading file, but few files failed download, with reason ERROR_TOO_MANY_REDIRECTS,

I got the reason to failed from below code:

val reasonIndex = cursor.getColumnIndex(DownloadManager.COLUMN_REASON)
val reason = cursor.getInt(reasonIndex)

//public final static int ERROR_TOO_MANY_REDIRECTS = 1005;

// I got same reason 1005

Is there any way to increase maxRedirect and what is default redirect count?

How can I fixed this too many redirect issue?

Currently I am using similar to below code:

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

fun downloadFile(url: String, path: String, title: String? = null): Long {
        val downloadUri = Uri.parse(url)
        var downloadId: Long
        try {
            val request = DownloadManager.Request(downloadUri).apply {
                setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI or     DownloadManager.Request.NETWORK_MOBILE)
                    .setAllowedOverRoaming(false)
                    .setTitle(title ?: "")
                    .setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN)
                    .setDestinationUri(Uri.fromFile(File(path)))

            }
            downloadId = downloadManager?.enqueue(request) ?: -1
            scanMedia(path)
        } catch (exception: Exception) {
            downloadId = -1
        }
        return downloadId
}

I want to download file from android.app.DownloadManager even if the url redirect to more then 10, 20 or 30 times


Solution

  • To solve this issue, we have to first get the redirected url and give the final redirected url to donwnload manager to download. This is the way to solve this issue.

    @Throws(IOException::class)
    suspend fun getFinalURL1(url: String, totalTimeOut: Long): String {
        return withContext(Dispatchers.IO) {
            if (totalTimeOut < System.currentTimeMillis()) {
                return@withContext url
            }
    
            delay(10)
    
            val obj = URL(url)
            val con: HttpURLConnection = obj.openConnection() as HttpURLConnection
            con.instanceFollowRedirects = false
            con.connect()
            con.inputStream
            if (con.responseCode == HttpURLConnection.HTTP_MOVED_PERM || con.responseCode == HttpURLConnection.HTTP_MOVED_TEMP) {
                var redirectUrl: String? = con.getHeaderField("Location")
    
                if (redirectUrl == null) {
                    return@withContext url
                } else if (redirectUrl.startsWith("/")) {
                    redirectUrl = obj.protocol.toString() + "://" + obj.host + redirectUrl
                }
    
                if (!redirectUrl.startsWith(startsWith, true)) {
                    return@withContext url
                }
    
                return@withContext getFinalURL1(redirectUrl, totalTimeOut)
            }
            return@withContext url
        }
    }