Milan Mishra
Milan Mishra

Reputation: 11

Does the Connectivity Manager or HttpUrl Connection block Roaming networks from downloading files?

I have been trying to edit a template Application. It is a wallpaper Application that downloads images from a JSON uploaded online.

The files download fine when on WIFI or Mobile Network. But once the network changes it's state to Roaming, the files do not download.

I'm very new to this and do not understand where to look for in the code to Modify it and get rid of this problem.

The application uses the regular ConnectivityManager, SSLSocketFactory and HttpUrlConnection to get access to the internet and to download the file.

If someone could guide me to what I should aiming at to solve this problem. Thank you.

This is where it begins -

  if (downloadable && isNetworkAvailable && actuallyComplies) {
            findViewById<RelativeLayout>(R.id.download_container).setOnClickListener {
                doItemClick(DOWNLOAD_ACTION_ID)
            }
}

When WIFI is connected, tapping on the download button, opens a progress dialog box and the file downloads. In Roaming Network, the dialog box opens Up but nothing loads, nothing is downloaded, It stays there forever.

'downloadable' and 'actuallyComplies' variable have nothing to do with internet connectivity.

isNetworkAvailable is linked to an external library that has the following code.

inline val Context.isNetworkAvailable: Boolean
    @SuppressLint("MissingPermission")
    get() {
        val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val activeNetworkInfo = connectivityManager.activeNetworkInfo
        return activeNetworkInfo?.isConnectedOrConnecting ?: false
    }

doItemClick(DOWNLOAD_ACTION_ID), leads to this code -

abstract class BaseWallpaperActionsActivity : ActivityWFragments() {

companion object {
    const val DOWNLOAD_ACTION_ID = 1
    const val APPLY_ACTION_ID = 2
}

private var actionDialog: MaterialDialog? = null
internal var wallActions: WallpaperActionsDialog? = null

internal abstract var wallpaper: Wallpaper?
internal abstract val allowBitmapApply: Boolean

override fun autoTintStatusBar(): Boolean = true
override fun autoTintNavigationBar(): Boolean = true

private val request by lazy {
    permissionsBuilder(Manifest.permission.WRITE_EXTERNAL_STORAGE).build()
}

override fun onDestroy() {
    super.onDestroy()
    try {
        request.detachAllListeners()
    } catch (e: Exception) {
    }
}

open fun doItemClick(actionId: Int) {
    when (actionId) {
        DOWNLOAD_ACTION_ID -> downloadWallpaper(false)
        APPLY_ACTION_ID -> downloadWallpaper(true)
    }
}

fun requestStoragePermission(explanation: String, whenAccepted: () -> Unit) {
    try {
        request.detachAllListeners()
    } catch (e: Exception) {
    }
    request.listeners {
        onAccepted { whenAccepted() }
        onDenied { showSnackbar(R.string.permission_denied, Snackbar.LENGTH_LONG) }
        onPermanentlyDenied {
            showSnackbar(R.string.permission_denied_completely, Snackbar.LENGTH_LONG)
        }
        onShouldShowRationale { _, nonce -> showPermissionInformation(explanation, nonce) }
    }
    request.send()
}

@SuppressLint("NewApi")
private fun downloadWallpaper(toApply: Boolean) {
    if (isNetworkAvailable) {
        requestStoragePermission(getString(R.string.permission_request, getAppName())) {
            checkIfFileExists(toApply)
        }
    } else {
        if (toApply && allowBitmapApply) showWallpaperApplyOptions(null)
        else showNotConnectedDialog()
    }
}

private fun showPermissionInformation(
    explanation: String,
    nonce: PermissionNonce
                                     ) {
    showSnackbar(explanation, Snackbar.LENGTH_LONG) {
        setAction(R.string.allow) {
            dismiss()
            nonce.use()
        }
    }
}

private fun checkIfFileExists(toApply: Boolean) {
    wallpaper?.let {
        properlyCancelDialog()
        val folder = File(configs.downloadsFolder)
        folder.mkdirs()
        val extension = it.url.substring(it.url.lastIndexOf("."))
        var correctExtension = getWallpaperExtension(extension)
        val fileName = it.name.formatCorrectly().replace(" ", "_")
        if (toApply) correctExtension = "_temp$correctExtension"
        val dest = File(folder, fileName + correctExtension)
        if (dest.exists()) {
            actionDialog = mdDialog {
                content(R.string.file_exists)
                negativeText(R.string.file_replace)
                positiveText(R.string.file_create_new)
                onPositive { _, _ ->
                    val time = getCurrentTimeStamp().formatCorrectly().replace(" ", "_")
                    val newDest = File(folder, fileName + "_" + time + correctExtension)
                    if (toApply) showWallpaperApplyOptions(newDest)
                    else startDownload(newDest)
                }
                onNegative { _, _ ->
                    if (toApply) showWallpaperApplyOptions(dest)
                    else startDownload(dest)
                }
            }
            actionDialog?.show()
        } else {
            if (toApply) showWallpaperApplyOptions(dest)
            else startDownload(dest)
        }
    }
}

private fun startDownload(dest: File) {
    wallpaper?.let {
        properlyCancelDialog()
        wallActions = WallpaperActionsDialog.create(this, it, dest)
        wallActions?.show(this)
    }
}

fun reportWallpaperDownloaded(dest: File) {
    sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(dest)))
    runOnUiThread {
        properlyCancelDialog()
        showSnackbar(
            getString(R.string.download_successful, dest.toString()),
            Snackbar.LENGTH_LONG) {
            setAction(
                R.string.open, {
                dest.getUri(context)?.let { openWallpaper(it) }
            })
        }
    }
}

@SuppressLint("SimpleDateFormat")
private fun getCurrentTimeStamp(): String {
    val sdfDate = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
    return sdfDate.format(Date())
}

private fun getWallpaperExtension(currentExt: String): String {
    val validExtensions = arrayOf(".jpg", ".jpeg", ".png")
    validExtensions.forEach {
        if (currentExt.contains(it, true)) return it
    }
    return ".png"
}

private fun showWallpaperApplyOptions(dest: File?) {
    properlyCancelDialog()
    val options = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        arrayListOf(
            getString(R.string.home_screen),
            getString(R.string.lock_screen),
            getString(R.string.home_lock_screen))
    } else {
        arrayListOf(getString(R.string.home_lock_screen))
    }
    if (isNetworkAvailable && dest != null)
        options.add(getString(R.string.apply_with_other_app))

    actionDialog = mdDialog {
        title(R.string.apply_to)
        items(options)
        itemsCallback { _, _, position, _ ->
            val rightPosition =
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) position + 2 else position
            if (dest != null) {
                applyWallpaper(
                    dest, rightPosition == 0, rightPosition == 1, rightPosition == 2,
                    rightPosition == 3)
            } else {
                if (allowBitmapApply)
                    applyBitmapWallpaper(
                        rightPosition == 0, rightPosition == 1, rightPosition == 2,
                        rightPosition == 3)
            }
        }
    }
    actionDialog?.show()
}

abstract fun applyBitmapWallpaper(
    toHomeScreen: Boolean, toLockScreen: Boolean, toBoth: Boolean,
    toOtherApp: Boolean
                                 )

private fun applyWallpaper(
    dest: File,
    toHomeScreen: Boolean, toLockScreen: Boolean, toBoth: Boolean,
    toOtherApp: Boolean
                          ) {
    wallpaper?.let {
        properlyCancelDialog()
        wallActions = WallpaperActionsDialog.create(
            this, it, dest, arrayOf(toHomeScreen, toLockScreen, toBoth, toOtherApp))
        wallActions?.show(this)
    }
}

fun showWallpaperAppliedSnackbar(
    toHomeScreen: Boolean, toLockScreen: Boolean,
    toBoth: Boolean
                                ) {
    properlyCancelDialog()
    showSnackbar(
        getString(
            R.string.apply_successful,
            getString(
                when {
                    toBoth -> R.string.home_lock_screen
                    toHomeScreen -> R.string.home_screen
                    toLockScreen -> R.string.lock_screen
                    else -> R.string.empty
                }).toLowerCase()), Snackbar.LENGTH_LONG)
}

private var file: File? = null

fun applyWallpaperWithOtherApp(dest: File) {
    try {
        dest.getUri(this)?.let {
            file = dest
            val setWall = Intent(Intent.ACTION_ATTACH_DATA)
            setWall.setDataAndType(it, "image/*")
            setWall.putExtra("mimeType", "image/*")
            setWall.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            startActivityForResult(
                Intent.createChooser(setWall, getString(R.string.apply_with_other_app)),
                WallpaperActionsDialog.TO_OTHER_APP_CODE)
        } ?: dest.delete()
    } catch (e: Exception) {
        FL.e(e.message)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == WallpaperActionsDialog.TO_OTHER_APP_CODE) {
        try {
            file?.delete()
            file = null
        } catch (e: Exception) {
            FL.e(e.message)
        }
    }
}

private fun showNotConnectedDialog() {
    properlyCancelDialog()
    actionDialog = mdDialog {
        title(R.string.muzei_not_connected_title)
        content(R.string.not_connected_content)
        positiveText(android.R.string.ok)
    }
    actionDialog?.show()
}

internal fun properlyCancelDialog() {
    wallActions?.stopActions()
    wallActions?.dismiss(this)
    wallActions = null
    actionDialog?.dismiss()
    actionDialog = null
}

private fun showSnackbar(
    @StringRes text: Int,
    duration: Int,
    defaultToToast: Boolean = false,
    settings: Snackbar.() -> Unit = {}
                        ) {
    showSnackbar(getString(text), duration, defaultToToast, settings)
}

abstract fun showSnackbar(
    text: String,
    duration: Int,
    defaultToToast: Boolean = false,
    settings: Snackbar.() -> Unit = {}
                         )

override fun startActivityForResult(intent: Intent?, requestCode: Int) {
    intent?.putExtra(REQUEST_CODE, requestCode)
    super.startActivityForResult(intent, requestCode)
}

@SuppressLint("RestrictedApi")
override fun startActivityForResult(intent: Intent?, requestCode: Int, options: Bundle?) {
    intent?.putExtra(REQUEST_CODE, requestCode)
    super.startActivityForResult(intent, requestCode, options)
}

}

This is the URL Request Code -

object FramesUrlRequests { fun requestJson(url: String): String {

    val result = StringBuilder()
    val urlConnection: HttpURLConnection? = buildHttpUrlConnection(url)
    urlConnection ?: return result.toString()

    try {
        val ins = BufferedInputStream(urlConnection.inputStream)
        val reader = BufferedReader(InputStreamReader(ins))
        var line: String? = null
        while ({ line = reader.readLine(); line }() != null) {
            result.append(line)
        }
        ins.close()
        reader.close()
    } catch (e: Exception) {
        FL.e("Error", e)
    } finally {
        urlConnection.disconnect()
    }
    return result.toString()
}

fun requestFileInfo(url: String, onlySize: Boolean): WallpaperInfo {

    var info = WallpaperInfo(0, Dimension(0, 0))
    val urlConnection: HttpURLConnection? = buildHttpUrlConnection(url)
    urlConnection ?: return info

    try {
        info = if (onlySize) {
            WallpaperInfo(urlConnection.contentLength.toLong(), Dimension(0L, 0L))
        } else {
            val options = BitmapFactory.Options()
            options.inJustDecodeBounds = true
            val ins = urlConnection.inputStream
            BitmapFactory.decodeStream(ins, null, options)
            val size = urlConnection.connectTimeout.toLong()
            ins.close()
            WallpaperInfo(
                size, Dimension(options.outWidth.toLong(), options.outHeight.toLong()))
        }
    } catch (e: Exception) {
        FL.e("Error", e)
    } finally {
        urlConnection.disconnect()
    }
    return info
}

private fun buildHttpUrlConnection(url: String): HttpURLConnection? {
    return (if (url.matches("^(https?)://.*$".toRegex())) {
        (URL(url).openConnection() as HttpsURLConnection).apply {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
                sslSocketFactory = FramesSocketFactory()
        }
    } else {
        URL(url).openConnection() as HttpURLConnection
    }).apply {
        connectTimeout = 20000
        readTimeout = 20000
    }
}

}

Obviously the code that is missing like imports and other things have been done correctly. The files are downloading fine on WIFI and even on Mobile Network. But not on Roaming Cellular Network.

This happens only in this APP. Not anywhere else.

So, I just need help to know where might the fault be. Thank you.

Upvotes: 1

Views: 39

Answers (0)

Related Questions