Categorías
Otros

Descarga de archivos de coroutine Retrofit+

// service write
interface UrlService {
    @Streaming
    @GET
    suspend fun downloadFile(@Url url:String): Response<ResponseBody>
}


 / / Open the level of the assistance and download, in order to easily call, download the method I encapsulate into DSL, refer to DowloadBuild
 lifecycleScope.launch() {
    val response = RetrofitUtils.create()
                 .downloadfile ("File Download Address")
    dowload(response){
        success { uri ->  
                         // Download success URI: Download file URI
                         // URI to File, you can refer to: https://blog.csdn.net/jingzz1/Article/details/106188462
        }
        error {throwable ->
                         //download failed 
        }
        process { downloadedSize, length, process ->
                         // Download progress
                         // DownloadedSize: Downloaded Size
                         // Length: Document size
                         // process: Download progress

        }
                 / / Set the file name, if not set, will be automatically obtained
                 // setFileName = {"xxxxx. suffix"}

                 / / In order to be compatible with Android10, if you need to download the file to the shared folder, you can call seruri.
        /* setUri = {
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                 val values = ContentValues().apply {
                                           PUT (MediaStore.Mediacolumns.Display_name, "xxxx.apk") // file name
                                           Put (MediaStore.Mediacolumns.mime_type, response.body () ?. contenttype (). TOSTRING ()) // File Type
                                           PUT (MediaStore.Mediacolumns.Rlative_path, Environment.directory_downloads) // Shared folder, fixed writing
                 }
                 context.contentResolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values)
             } else
                 Uri.fromFile(File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)?.absolutePath+File.separator+"xxxxx.apk"))
         }*/

         } .startdowload () // call .Startdowload () Open Download

}
DowloadBuild code:
import android.content.Context
import android.net.Uri
import android.os.Environment
import android.webkit.MimeTypeMap
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.ResponseBody
import retrofit2.Response
import java.io.BufferedInputStream
import java.io.File
import java.io.FileOutputStream

/**
 * Created by jingzz on 2020/7/9.
 */
typealias DOWLOAD_ERROR = (Throwable) -> Unit
typealias DOWLOAD_PROCESS = (downloadedSize: Long, length: Long, process: Float) -> Unit
typealias DOWLOAD_SUCCESS = (uri: Uri) -> Unit

suspend fun dowload(response: Response<ResponseBody>,block:DowloadBuild.()->Unit):DowloadBuild{
    val build = DowloadBuild(response)
    build.block()
    return build
}

class DowloadBuild(val response: Response<ResponseBody>) {
         Private var error: download_error = {} // Error greeting
         Private var process: download_process = {DownloadedSize, Length, Process ->} // Progress
         PRIVATE VAR SUCCESS: Dowload_suCcess = {} // Download completion
         Private Val Context: context = myapplication.context // Global Context
         Var seturi: () -> URI? = {null} // Set the downloaded URI
         Var setFileName: () -> string? = {null} // set file name

    fun process(process: DOWLOAD_PROCESS) {
        this.process = process
    }

    fun error(error: DOWLOAD_ERROR) {
        this.error = error
    }

    fun success(success: DOWLOAD_SUCCESS) {
        this.success = success
    }

    suspend fun startDowload() {
        withContext(Dispatchers.IO) {
            try {
                                 Val body = response.body ()?: throw runtimeException ("Download error")
                                 // File total length
                val length = body.contentLength()
                                 // File MineType
                val contentType = body.contentType()?.toString()
                val ios = body.byteStream()
                var uri: Uri? = null
                var file: File? = null
                val ops = kotlin.run {
                    setUri()?.let {
                                                 // URL turn OutputStream
                        uri = it
                        context.contentResolver.openOutputStream(it)
                    } ?: kotlin.run {
                        val fileName = setFileName() ?: kotlin.run {
                                                         // If you don't even give it, you will generate a file name.
                            "${System.currentTimeMillis()}.${MimeTypeMap.getSingleton()
                                .getExtensionFromMimeType(contentType)}"
                        }
                        file =
                            File("${context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)}${File.separator}$fileName")
                        FileOutputStream(file)
                    }
                }
                                 // Download the length
                var currentLength: Int = 0
                                 // Write file
                val bufferSize = 1024 * 8
                val buffer = ByteArray(bufferSize)
                val bufferedInputStream = BufferedInputStream(ios, bufferSize)
                var readLength: Int = 0
                while (bufferedInputStream.read(buffer, 0, bufferSize)
                        .also { readLength = it } != -1
                ) {
                    ops.write(buffer, 0, readLength)
                    currentLength += readLength
                    process(
                        currentLength.toLong(),
                        length,
                        currentLength.toFloat() / length.toFloat()
                    )
                }
                bufferedInputStream.close()
                ops.close()
                ios.close()
                if (uri != null) {
                    success(uri!!)
                } else if (file != null) {
                    success(Uri.fromFile(file))
                }

            } catch (e: Exception) {
                error(e)
            }
        }
    }
}

.

  Estructura de datos de Redis y el principio de los tipos de datos básicos

Por Programación.Click

Más de 20 años programando en diferentes lenguajes de programación. Apasionado del code clean y el terminar lo que se empieza. ¿Programamos de verdad?

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *