retrofit goes brrrrrr
This commit is contained in:
parent
e670b5764e
commit
1ceb53d2d4
|
@ -31,7 +31,6 @@
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:largeHeap="true"
|
|
||||||
tools:ignore="UnusedAttribute">
|
tools:ignore="UnusedAttribute">
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
|
|
|
@ -2,8 +2,10 @@ package com.vanced.manager.core.downloader
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.vanced.manager.R
|
import com.vanced.manager.R
|
||||||
|
import com.vanced.manager.utils.DownloadHelper.download
|
||||||
import com.vanced.manager.utils.DownloadHelper.downloadProgress
|
import com.vanced.manager.utils.DownloadHelper.downloadProgress
|
||||||
import com.vanced.manager.utils.DownloadHelper.fuelDownload
|
import com.vanced.manager.utils.Extensions.getDefaultPrefs
|
||||||
|
import com.vanced.manager.utils.Extensions.getInstallUrl
|
||||||
import com.vanced.manager.utils.InternetTools.microg
|
import com.vanced.manager.utils.InternetTools.microg
|
||||||
import com.vanced.manager.utils.PackageHelper.install
|
import com.vanced.manager.utils.PackageHelper.install
|
||||||
|
|
||||||
|
@ -14,11 +16,13 @@ object MicrogDownloader {
|
||||||
|
|
||||||
fun downloadMicrog(context: Context) {
|
fun downloadMicrog(context: Context) {
|
||||||
val url = microg.value?.string("url") ?: ""
|
val url = microg.value?.string("url") ?: ""
|
||||||
fuelDownload(url, folderName, fileName, context, onDownloadComplete = {
|
context.getDefaultPrefs().getInstallUrl()?.let {
|
||||||
startMicrogInstall(context)
|
download(url, "$it/", folderName, fileName, context, onDownloadComplete = {
|
||||||
}, onError = {
|
startMicrogInstall(context)
|
||||||
downloadProgress.value?.downloadingFile?.postValue(context.getString(R.string.error_downloading, fileName))
|
}, onError = {
|
||||||
})
|
downloadProgress.value?.downloadingFile?.postValue(context.getString(R.string.error_downloading, fileName))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@ import com.vanced.manager.R
|
||||||
import com.vanced.manager.utils.AppUtils.musicRootPkg
|
import com.vanced.manager.utils.AppUtils.musicRootPkg
|
||||||
import com.vanced.manager.utils.AppUtils.validateTheme
|
import com.vanced.manager.utils.AppUtils.validateTheme
|
||||||
import com.vanced.manager.utils.DeviceUtils.getArch
|
import com.vanced.manager.utils.DeviceUtils.getArch
|
||||||
|
import com.vanced.manager.utils.DownloadHelper.download
|
||||||
import com.vanced.manager.utils.DownloadHelper.downloadProgress
|
import com.vanced.manager.utils.DownloadHelper.downloadProgress
|
||||||
import com.vanced.manager.utils.DownloadHelper.fuelDownload
|
|
||||||
import com.vanced.manager.utils.Extensions.getInstallUrl
|
import com.vanced.manager.utils.Extensions.getInstallUrl
|
||||||
import com.vanced.manager.utils.Extensions.getLatestAppVersion
|
import com.vanced.manager.utils.Extensions.getLatestAppVersion
|
||||||
import com.vanced.manager.utils.InternetTools.getFileNameFromUrl
|
import com.vanced.manager.utils.InternetTools.getFileNameFromUrl
|
||||||
|
@ -42,10 +42,10 @@ object MusicDownloader {
|
||||||
|
|
||||||
private fun downloadApk(context: Context, apk: String = "music") {
|
private fun downloadApk(context: Context, apk: String = "music") {
|
||||||
val url = if (apk == "stock") "$baseurl/stock/${getArch()}.apk" else "$baseurl/$variant.apk"
|
val url = if (apk == "stock") "$baseurl/stock/${getArch()}.apk" else "$baseurl/$variant.apk"
|
||||||
fuelDownload(url, folderName!!, getFileNameFromUrl(url), context, onDownloadComplete = {
|
download(url, baseurl + "/", folderName!!, getFileNameFromUrl(url), context, onDownloadComplete = {
|
||||||
if (variant == "root" && apk != "stock") {
|
if (variant == "root" && apk != "stock") {
|
||||||
downloadApk(context, "stock")
|
downloadApk(context, "stock")
|
||||||
return@fuelDownload
|
return@download
|
||||||
}
|
}
|
||||||
|
|
||||||
when (apk) {
|
when (apk) {
|
||||||
|
|
|
@ -9,8 +9,8 @@ import com.vanced.manager.R
|
||||||
import com.vanced.manager.utils.AppUtils.validateTheme
|
import com.vanced.manager.utils.AppUtils.validateTheme
|
||||||
import com.vanced.manager.utils.AppUtils.vancedRootPkg
|
import com.vanced.manager.utils.AppUtils.vancedRootPkg
|
||||||
import com.vanced.manager.utils.DeviceUtils.getArch
|
import com.vanced.manager.utils.DeviceUtils.getArch
|
||||||
|
import com.vanced.manager.utils.DownloadHelper.download
|
||||||
import com.vanced.manager.utils.DownloadHelper.downloadProgress
|
import com.vanced.manager.utils.DownloadHelper.downloadProgress
|
||||||
import com.vanced.manager.utils.DownloadHelper.fuelDownload
|
|
||||||
import com.vanced.manager.utils.Extensions.getInstallUrl
|
import com.vanced.manager.utils.Extensions.getInstallUrl
|
||||||
import com.vanced.manager.utils.Extensions.getLatestAppVersion
|
import com.vanced.manager.utils.Extensions.getLatestAppVersion
|
||||||
import com.vanced.manager.utils.InternetTools.getFileNameFromUrl
|
import com.vanced.manager.utils.InternetTools.getFileNameFromUrl
|
||||||
|
@ -77,48 +77,50 @@ object VancedDownloader {
|
||||||
else -> throw NotImplementedError("This type of APK is NOT valid. What the hell did you even do?")
|
else -> throw NotImplementedError("This type of APK is NOT valid. What the hell did you even do?")
|
||||||
}
|
}
|
||||||
|
|
||||||
fuelDownload(url, folderName!!, getFileNameFromUrl(url), context, onDownloadComplete = {
|
installUrl?.let {
|
||||||
when (type) {
|
download(url, "$it/", folderName!!, getFileNameFromUrl(url), context, onDownloadComplete = {
|
||||||
"theme" ->
|
when (type) {
|
||||||
if (variant == "root") {
|
"theme" ->
|
||||||
if (validateTheme(downloadPath!!, theme!!, hashUrl, context)) {
|
if (variant == "root") {
|
||||||
if (downloadStockCheck(vancedRootPkg, vancedVersionCode, context))
|
if (validateTheme(downloadPath!!, theme!!, hashUrl, context)) {
|
||||||
downloadSplits(context, "arch")
|
if (downloadStockCheck(vancedRootPkg, vancedVersionCode, context))
|
||||||
else
|
downloadSplits(context, "arch")
|
||||||
startVancedInstall(context)
|
else
|
||||||
|
startVancedInstall(context)
|
||||||
|
} else
|
||||||
|
downloadSplits(context, "theme")
|
||||||
} else
|
} else
|
||||||
downloadSplits(context, "theme")
|
downloadSplits(context, "arch")
|
||||||
} else
|
"arch" -> if (variant == "root") downloadSplits(context, "stock") else downloadSplits(context, "lang")
|
||||||
downloadSplits(context, "arch")
|
"stock" -> downloadSplits(context, "dpi")
|
||||||
"arch" -> if (variant == "root") downloadSplits(context, "stock") else downloadSplits(context, "lang")
|
"dpi" -> downloadSplits(context, "lang")
|
||||||
"stock" -> downloadSplits(context, "dpi")
|
"lang" -> {
|
||||||
"dpi" -> downloadSplits(context, "lang")
|
count++
|
||||||
"lang" -> {
|
succesfulLangCount++
|
||||||
count++
|
if (count < lang.size)
|
||||||
succesfulLangCount++
|
downloadSplits(context, "lang")
|
||||||
if (count < lang.size)
|
else
|
||||||
downloadSplits(context, "lang")
|
startVancedInstall(context)
|
||||||
else
|
|
||||||
startVancedInstall(context)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}, onError = {
|
|
||||||
if (type == "lang") {
|
|
||||||
count++
|
|
||||||
when {
|
|
||||||
count < lang.size -> downloadSplits(context, "lang")
|
|
||||||
succesfulLangCount == 0 -> {
|
|
||||||
lang.add("en")
|
|
||||||
downloadSplits(context, "lang")
|
|
||||||
}
|
}
|
||||||
else -> startVancedInstall(context)
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
}
|
||||||
downloadProgress.value?.downloadingFile?.postValue(context.getString(R.string.error_downloading, getFileNameFromUrl(url)))
|
}, onError = {
|
||||||
}
|
if (type == "lang") {
|
||||||
})
|
count++
|
||||||
|
when {
|
||||||
|
count < lang.size -> downloadSplits(context, "lang")
|
||||||
|
succesfulLangCount == 0 -> {
|
||||||
|
lang.add("en")
|
||||||
|
downloadSplits(context, "lang")
|
||||||
|
}
|
||||||
|
else -> startVancedInstall(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
downloadProgress.value?.downloadingFile?.postValue(context.getString(R.string.error_downloading, getFileNameFromUrl(url)))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startVancedInstall(context: Context, variant: String? = this.variant) {
|
fun startVancedInstall(context: Context, variant: String? = this.variant) {
|
||||||
|
|
|
@ -2,6 +2,8 @@ package com.vanced.manager.model
|
||||||
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import com.github.kittinunf.fuel.core.requests.CancellableRequest
|
import com.github.kittinunf.fuel.core.requests.CancellableRequest
|
||||||
|
import okhttp3.ResponseBody
|
||||||
|
import retrofit2.Call
|
||||||
|
|
||||||
open class ProgressModel {
|
open class ProgressModel {
|
||||||
|
|
||||||
|
@ -9,7 +11,7 @@ open class ProgressModel {
|
||||||
val downloadingFile = MutableLiveData<String>()
|
val downloadingFile = MutableLiveData<String>()
|
||||||
val installing = MutableLiveData<Boolean>()
|
val installing = MutableLiveData<Boolean>()
|
||||||
|
|
||||||
var currentDownload: CancellableRequest? = null
|
var currentDownload: Call<ResponseBody>? = null
|
||||||
|
|
||||||
fun reset() {
|
fun reset() {
|
||||||
downloadProgress.value = 0
|
downloadProgress.value = 0
|
||||||
|
|
|
@ -7,43 +7,106 @@ import android.os.Build
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.core.content.FileProvider
|
import androidx.core.content.FileProvider
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import com.github.kittinunf.fuel.Fuel
|
|
||||||
import com.vanced.manager.R
|
import com.vanced.manager.R
|
||||||
|
import com.vanced.manager.library.network.providers.createService
|
||||||
import com.vanced.manager.model.ProgressModel
|
import com.vanced.manager.model.ProgressModel
|
||||||
import com.vanced.manager.utils.AppUtils.sendCloseDialog
|
import com.vanced.manager.utils.AppUtils.sendCloseDialog
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.io.File
|
import okhttp3.ResponseBody
|
||||||
|
import retrofit2.Call
|
||||||
|
import retrofit2.Callback
|
||||||
|
import retrofit2.Response
|
||||||
|
import retrofit2.http.GET
|
||||||
|
import retrofit2.http.Streaming
|
||||||
|
import retrofit2.http.Url
|
||||||
|
import java.io.*
|
||||||
|
|
||||||
object DownloadHelper : CoroutineScope by CoroutineScope(Dispatchers.IO) {
|
object DownloadHelper : CoroutineScope by CoroutineScope(Dispatchers.IO) {
|
||||||
|
|
||||||
fun fuelDownload(url: String, fileFolder: String, fileName: String, context: Context, onDownloadComplete: () -> Unit, onError: (error: String) -> Unit) = launch {
|
interface DownloadHelper {
|
||||||
try {
|
|
||||||
downloadProgress.value?.downloadingFile?.postValue(context.getString(R.string.downloading_file, fileName))
|
|
||||||
downloadProgress.value?.currentDownload = Fuel.download(url)
|
|
||||||
.fileDestination { _, _ ->
|
|
||||||
File(context.getExternalFilesDir(fileFolder)?.path, fileName)
|
|
||||||
}
|
|
||||||
.progress { readBytes, totalBytes ->
|
|
||||||
downloadProgress.value?.downloadProgress?.postValue((readBytes * 100 / totalBytes).toInt())
|
|
||||||
}
|
|
||||||
.responseString { _, _, result ->
|
|
||||||
result.fold(success = {
|
|
||||||
downloadProgress.value?.downloadProgress?.postValue(0)
|
|
||||||
onDownloadComplete()
|
|
||||||
}, failure = { error ->
|
|
||||||
downloadProgress.value?.downloadProgress?.postValue(0)
|
|
||||||
Log.d("VMDownloader", error.cause.toString())
|
|
||||||
onError(error.errorData.toString())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
downloadProgress.value?.downloadProgress?.postValue(0)
|
|
||||||
Log.d("VMDownloader", "Failed to download file: $url")
|
|
||||||
onError("")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Streaming
|
||||||
|
@GET
|
||||||
|
fun download(@Url url: String): Call<ResponseBody>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun download(
|
||||||
|
url: String,
|
||||||
|
baseUrl: String,
|
||||||
|
fileFolder: String,
|
||||||
|
fileName: String,
|
||||||
|
context: Context,
|
||||||
|
onDownloadComplete: () -> Unit,
|
||||||
|
onError: (error: String) -> Unit
|
||||||
|
) {
|
||||||
|
downloadProgress.value?.downloadingFile?.postValue(context.getString(R.string.downloading_file, fileName))
|
||||||
|
val downloadInterface = createService(DownloadHelper::class, baseUrl)
|
||||||
|
val download = downloadInterface.download(url)
|
||||||
|
downloadProgress.value?.currentDownload = download
|
||||||
|
download.enqueue(object : Callback<ResponseBody> {
|
||||||
|
override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
|
||||||
|
if (response.isSuccessful) {
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
if (response.body()?.let { writeFile(it, context.getExternalFilesDir(fileFolder)?.path + "/" + fileName) } == true) {
|
||||||
|
onDownloadComplete()
|
||||||
|
} else {
|
||||||
|
onError("Could not save file")
|
||||||
|
downloadProgress.value?.downloadProgress?.postValue(0)
|
||||||
|
Log.d("VMDownloader", "Failed to download file: $url")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
onError(response.errorBody().toString())
|
||||||
|
downloadProgress.value?.downloadProgress?.postValue(0)
|
||||||
|
Log.d("VMDownloader", "Failed to download file: $url")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
|
||||||
|
if (call.isCanceled) {
|
||||||
|
Log.d("VMDownloader", "Download canceled")
|
||||||
|
downloadProgress.value?.downloadProgress?.postValue(0)
|
||||||
|
} else {
|
||||||
|
onError(t.stackTraceToString())
|
||||||
|
downloadProgress.value?.downloadProgress?.postValue(0)
|
||||||
|
Log.d("VMDownloader", "Failed to download file: $url")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun writeFile(body: ResponseBody, filePath: String): Boolean {
|
||||||
|
return try {
|
||||||
|
val file = File(filePath)
|
||||||
|
val totalBytes = body.contentLength()
|
||||||
|
var inputStream: InputStream? = null
|
||||||
|
var outputStream: OutputStream? = null
|
||||||
|
try {
|
||||||
|
val fileReader = ByteArray(4096)
|
||||||
|
var downloadedBytes: Long = 0
|
||||||
|
inputStream = body.byteStream()
|
||||||
|
outputStream = FileOutputStream(file)
|
||||||
|
var read: Int
|
||||||
|
while (inputStream.read(fileReader).also { read = it } != -1) {
|
||||||
|
outputStream.write(fileReader, 0, read)
|
||||||
|
downloadedBytes += read.toLong()
|
||||||
|
downloadProgress.value?.downloadProgress?.postValue((downloadedBytes * 100 / totalBytes).toInt())
|
||||||
|
}
|
||||||
|
outputStream.flush()
|
||||||
|
true
|
||||||
|
} catch (e: IOException) {
|
||||||
|
false
|
||||||
|
} finally {
|
||||||
|
inputStream?.close()
|
||||||
|
outputStream?.close()
|
||||||
|
}
|
||||||
|
} catch (e: IOException) {
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val downloadProgress = MutableLiveData<ProgressModel>()
|
val downloadProgress = MutableLiveData<ProgressModel>()
|
||||||
|
@ -54,7 +117,7 @@ object DownloadHelper : CoroutineScope by CoroutineScope(Dispatchers.IO) {
|
||||||
|
|
||||||
fun downloadManager(context: Context) {
|
fun downloadManager(context: Context) {
|
||||||
val url = "https://github.com/YTVanced/VancedManager/releases/latest/download/manager.apk"
|
val url = "https://github.com/YTVanced/VancedManager/releases/latest/download/manager.apk"
|
||||||
fuelDownload(url, "manager", "manager.apk", context, onDownloadComplete = {
|
download(url,"https://github.com/YTVanced/VancedManager", "manager", "manager.apk", context, onDownloadComplete = {
|
||||||
val apk = File("${context.getExternalFilesDir("manager")?.path}/manager.apk")
|
val apk = File("${context.getExternalFilesDir("manager")?.path}/manager.apk")
|
||||||
val uri =
|
val uri =
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||||
|
@ -69,7 +132,12 @@ object DownloadHelper : CoroutineScope by CoroutineScope(Dispatchers.IO) {
|
||||||
context.startActivity(intent)
|
context.startActivity(intent)
|
||||||
sendCloseDialog(context)
|
sendCloseDialog(context)
|
||||||
}, onError = {
|
}, onError = {
|
||||||
downloadProgress.value?.downloadingFile?.postValue(context.getString(R.string.error_downloading, "manager.apk"))
|
downloadProgress.value?.downloadingFile?.postValue(
|
||||||
|
context.getString(
|
||||||
|
R.string.error_downloading,
|
||||||
|
"manager.apk"
|
||||||
|
)
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.squareup.moshi.Moshi
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import retrofit2.Retrofit
|
import retrofit2.Retrofit
|
||||||
import retrofit2.converter.moshi.MoshiConverterFactory
|
import retrofit2.converter.moshi.MoshiConverterFactory
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
fun provideRetrofit(
|
fun provideRetrofit(
|
||||||
okHttpClient: OkHttpClient,
|
okHttpClient: OkHttpClient,
|
||||||
|
@ -13,4 +14,12 @@ fun provideRetrofit(
|
||||||
.addConverterFactory(MoshiConverterFactory.create(moshi))
|
.addConverterFactory(MoshiConverterFactory.create(moshi))
|
||||||
.client(okHttpClient)
|
.client(okHttpClient)
|
||||||
.baseUrl(url)
|
.baseUrl(url)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
fun <S: Any> createService(service: KClass<S>, baseurl: String): S {
|
||||||
|
return provideRetrofit(
|
||||||
|
provideOkHttpClient(),
|
||||||
|
provideMoshi(),
|
||||||
|
baseurl
|
||||||
|
).create(service.java)
|
||||||
|
}
|
Loading…
Reference in New Issue