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)
            }
        }
    }
}

.

  Último código fuente de versión de análisis de negocio de nombre de dominio secundario completo código abierto

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 *