Switched to Fuel downloader

This commit is contained in:
Xinto 2020-11-23 20:00:41 +04:00
parent a1827fd8c7
commit dd3dba0fad
23 changed files with 186 additions and 292 deletions

View File

@ -75,7 +75,7 @@ def getLanguages() {
langs.add("pt_PT")
langs.add("zh_CN")
langs.add("zh_TW")
List<String> exceptions = [ "bn", "pt", "zh"]
List<String> exceptions = ["bn", "pt", "zh"]
Pattern pattern = Pattern.compile("-(\\w+)-")
new File("${projectDir}/src/main/res").eachDir { dir ->
if (dir.name.startsWith("values-") && !dir.name.contains("v23")) {
@ -139,9 +139,6 @@ dependencies {
// Layout
implementation 'com.google.android:flexbox:2.0.1'
// File downloader
implementation 'com.mindorks.android:prdownloader:0.6.0'
// Firebase
implementation 'com.google.firebase:firebase-analytics-ktx:18.0.0'
implementation 'com.google.firebase:firebase-crashlytics:17.3.0'

View File

@ -8,7 +8,6 @@ import com.crowdin.platform.Crowdin
import com.crowdin.platform.CrowdinConfig
import com.crowdin.platform.data.model.AuthConfig
import com.crowdin.platform.data.remote.NetworkType
import com.downloader.PRDownloader
import com.vanced.manager.BuildConfig.*
import com.vanced.manager.utils.InternetTools.loadJson
import kotlinx.coroutines.CoroutineScope
@ -24,7 +23,6 @@ open class App: Application() {
override fun onCreate() {
scope.launch { loadJson(this@App) }
super.onCreate()
PRDownloader.initialize(this)
Crowdin.init(this,
CrowdinConfig.Builder().apply {

View File

@ -1,48 +1,30 @@
package com.vanced.manager.core.downloader
import android.content.Context
import com.downloader.Error
import com.downloader.OnDownloadListener
import com.downloader.PRDownloader
import com.vanced.manager.R
import com.vanced.manager.utils.DownloadHelper.downloadProgress
import com.vanced.manager.utils.InternetTools.getFileNameFromUrl
import com.vanced.manager.utils.DownloadHelper.fuelDownload
import com.vanced.manager.utils.InternetTools.microg
import com.vanced.manager.utils.PackageHelper.install
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
object MicrogDownloader : CoroutineScope by CoroutineScope(Dispatchers.IO) {
object MicrogDownloader {
fun downloadMicrog(
context: Context,
) = launch {
val url = microg.get()?.string("url")
private const val fileName = "microg.apk"
private const val folderName = "microg"
downloadProgress.value?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("microg")?.path, "microg.apk")
.build()
.setOnStartOrResumeListener {
downloadProgress.value?.downloadingFile?.value = context.getString(R.string.downloading_file, url?.let { getFileNameFromUrl(it) })
}
.setOnProgressListener { progress ->
downloadProgress.value?.downloadProgress?.value = (progress.currentBytes * 100 / progress.totalBytes).toInt()
}
.start(object : OnDownloadListener {
override fun onDownloadComplete() {
startMicrogInstall(context)
}
fun downloadMicrog(context: Context) {
val url = microg.get()?.string("url") ?: ""
fuelDownload(url, folderName, fileName, context, onDownloadComplete = {
startMicrogInstall(context)
}, onError = {
downloadProgress.value?.downloadingFile?.postValue(context.getString(R.string.error_downloading, fileName))
})
override fun onError(error: Error?) {
downloadProgress.value?.downloadingFile?.value = context.getString(R.string.error_downloading, "microG")
}
})
}
}
fun startMicrogInstall(context: Context) {
downloadProgress.value?.installing?.value = true
downloadProgress.value?.reset()
install("${context.getExternalFilesDir("microg")}/microg.apk", context)
downloadProgress.value?.installing?.postValue(true)
downloadProgress.value?.postReset()
install("${context.getExternalFilesDir(folderName)}/$fileName", context)
}
}

View File

@ -2,34 +2,28 @@ package com.vanced.manager.core.downloader
import android.content.Context
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.downloader.Error
import com.downloader.OnDownloadListener
import com.downloader.PRDownloader
import com.vanced.manager.R
import com.vanced.manager.utils.AppUtils.musicRootPkg
import com.vanced.manager.utils.AppUtils.validateTheme
import com.vanced.manager.utils.DeviceUtils.getArch
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.getLatestAppVersion
import com.vanced.manager.utils.InternetTools.backupUrl
import com.vanced.manager.utils.InternetTools.getFileNameFromUrl
import com.vanced.manager.utils.InternetTools.music
import com.vanced.manager.utils.InternetTools.musicVersions
import com.vanced.manager.utils.PackageHelper.downloadStockCheck
import com.vanced.manager.utils.PackageHelper.install
import com.vanced.manager.utils.PackageHelper.installMusicRoot
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlin.coroutines.suspendCoroutine
object MusicDownloader: CoroutineScope by CoroutineScope(Dispatchers.IO) {
object MusicDownloader {
private var variant: String? = null
private var version: String? = null
private var versionCode: Int? = null
private var baseurl = ""
private var folderName: String? = null
private var downloadPath: String? = null
private var hashUrl: String? = null
@ -39,68 +33,45 @@ object MusicDownloader: CoroutineScope by CoroutineScope(Dispatchers.IO) {
versionCode = music.get()?.int("versionCode")
variant = prefs.getString("vanced_variant", "nonroot")
baseurl = "${prefs.getInstallUrl()}/music/v$version"
downloadPath = context.getExternalFilesDir("music/$variant")?.path
folderName = "music/$variant"
downloadPath = context.getExternalFilesDir(folderName)?.path
hashUrl = "$baseurl/hash.json"
downloadApk(context)
}
private fun downloadApk(context: Context, apk: String = "music") {
launch {
val url = if (apk == "stock") "$baseurl/stock/${getArch()}.apk" else "$baseurl/$variant.apk"
suspendCoroutine {
downloadProgress.value?.currentDownload = PRDownloader.download(url, downloadPath, getFileNameFromUrl(url))
.build()
.setOnStartOrResumeListener {
downloadProgress.value?.downloadingFile?.value =context.getString(R.string.downloading_file, getFileNameFromUrl(url))
}
.setOnProgressListener { progress ->
downloadProgress.value?.downloadProgress?.value = (progress.currentBytes * 100 / progress.totalBytes).toInt()
}
.start(object : OnDownloadListener {
override fun onDownloadComplete() {
if (variant == "root" && apk != "stock") {
downloadApk(context, "stock") // recursive in coroutine its so bad...
return
}
when (apk) {
"music" -> {
if (variant == "root") {
if (validateTheme(downloadPath!!, "root", hashUrl!!, context)) {
if (downloadStockCheck(musicRootPkg, versionCode!!, context))
downloadApk(context, "stock")
else
startMusicInstall(context)
} else {
downloadApk(context, apk)
}
} else
startMusicInstall(context)
}
}
startMusicInstall(context)
}
override fun onError(error: Error?) {
if (baseurl != backupUrl) {
baseurl = "$backupUrl/music/v$version"
downloadApk(context, apk)
return
}
downloadProgress.value?.downloadingFile?.value = context.getString(R.string.error_downloading, "Music")
}
})
val url = if (apk == "stock") "$baseurl/stock/${getArch()}.apk" else "$baseurl/$variant.apk"
fuelDownload(url, folderName!!, getFileNameFromUrl(url), context, onDownloadComplete = {
if (variant == "root" && apk != "stock") {
downloadApk(context, "stock")
return@fuelDownload
}
}
when (apk) {
"music" -> {
if (variant == "root") {
if (validateTheme(downloadPath!!, "root", hashUrl!!, context)) {
if (downloadStockCheck(musicRootPkg, versionCode!!, context))
downloadApk(context, "stock")
else
startMusicInstall(context)
} else {
downloadApk(context, apk)
}
} else
startMusicInstall(context)
}
"stock" -> startMusicInstall(context)
}
}, onError = {
downloadProgress.value?.downloadingFile?.postValue(context.getString(R.string.error_downloading, getFileNameFromUrl(url)))
})
}
fun startMusicInstall(context: Context) {
downloadProgress.value?.installing?.value = true
downloadProgress.value?.reset()
downloadProgress.value?.installing?.postValue(true)
downloadProgress.value?.postReset()
if (variant == "root")
installMusicRoot(context)
else

View File

@ -3,9 +3,6 @@ package com.vanced.manager.core.downloader
import android.content.Context
import android.content.SharedPreferences
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.downloader.Error
import com.downloader.OnDownloadListener
import com.downloader.PRDownloader
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.logEvent
import com.vanced.manager.R
@ -13,9 +10,9 @@ import com.vanced.manager.utils.AppUtils.validateTheme
import com.vanced.manager.utils.AppUtils.vancedRootPkg
import com.vanced.manager.utils.DeviceUtils.getArch
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.getLatestAppVersion
import com.vanced.manager.utils.InternetTools.backupUrl
import com.vanced.manager.utils.InternetTools.getFileNameFromUrl
import com.vanced.manager.utils.InternetTools.vanced
import com.vanced.manager.utils.InternetTools.vancedVersions
@ -23,12 +20,9 @@ import com.vanced.manager.utils.LanguageHelper.getDefaultVancedLanguages
import com.vanced.manager.utils.PackageHelper.downloadStockCheck
import com.vanced.manager.utils.PackageHelper.installVanced
import com.vanced.manager.utils.PackageHelper.installVancedRoot
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
object VancedDownloader: CoroutineScope by CoroutineScope(Dispatchers.IO) {
object VancedDownloader {
private lateinit var prefs: SharedPreferences
private lateinit var defPrefs: SharedPreferences
@ -48,12 +42,14 @@ object VancedDownloader: CoroutineScope by CoroutineScope(Dispatchers.IO) {
private var vancedVersion: String? = null
private var downloadPath: String? = null
private var folderName: String? = null
fun downloadVanced(context: Context) {
defPrefs = getDefaultSharedPreferences(context)
prefs = context.getSharedPreferences("installPrefs", Context.MODE_PRIVATE)
variant = defPrefs.getString("vanced_variant", "nonroot")
downloadPath = context.getExternalFilesDir("vanced/$variant")?.path
folderName = "vanced/$variant"
downloadPath = context.getExternalFilesDir(folderName)?.path
File(downloadPath.toString()).deleteRecursively()
installUrl = defPrefs.getInstallUrl()
prefs.getString("lang", getDefaultVancedLanguages())?.let {
@ -71,88 +67,63 @@ object VancedDownloader: CoroutineScope by CoroutineScope(Dispatchers.IO) {
downloadSplits(context)
}
private fun downloadSplits(
context: Context,
type: String = "theme"
) {
launch {
val url =
when (type) {
"theme" -> "$themePath/$theme.apk"
"arch" -> "$installUrl/apks/v$vancedVersion/$variant/Arch/split_config.$arch.apk"
"stock" -> "$themePath/stock.apk"
"dpi" -> "$themePath/dpi.apk"
"lang" -> "$installUrl/apks/v$vancedVersion/$variant/Language/split_config.${lang[count]}.apk"
else -> throw NotImplementedError("This type of APK is NOT valid. What the hell did you even do?")
}
downloadProgress.value?.currentDownload = PRDownloader.download(url, downloadPath, getFileNameFromUrl(url))
.build()
.setOnStartOrResumeListener {
downloadProgress.value?.downloadingFile?.value = context.getString(R.string.downloading_file, getFileNameFromUrl(url))
}
.setOnProgressListener { progress ->
downloadProgress.value?.downloadProgress?.value = (progress.currentBytes * 100 / progress.totalBytes).toInt()
}
.start(object : OnDownloadListener {
override fun onDownloadComplete() {
when (type) {
"theme" ->
if (variant == "root") {
if (validateTheme(downloadPath!!, theme!!, hashUrl, context)) {
if (downloadStockCheck(vancedRootPkg, vancedVersionCode, context))
downloadSplits(context, "arch")
else
startVancedInstall(context)
} else
downloadSplits(context, "theme")
} else
downloadSplits(context, "arch")
"arch" -> if (variant == "root") downloadSplits(context, "stock") else downloadSplits(context, "lang")
"stock" -> downloadSplits(context, "dpi")
"dpi" -> downloadSplits(context, "lang")
"lang" -> {
count++
succesfulLangCount++
if (count < lang.size)
downloadSplits(context, "lang")
else
startVancedInstall(context)
}
}
}
override fun onError(error: Error?) {
if (installUrl != backupUrl) {
installUrl = backupUrl
themePath = "$installUrl/apks/v$vancedVersion/$variant/Theme"
downloadSplits(context, type)
return
}
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?.value = context.getString(R.string.error_downloading, getFileNameFromUrl(url))
}
}
})
private fun downloadSplits(context: Context, type: String = "theme") {
val url = when (type) {
"theme" -> "$themePath/$theme.apk"
"arch" -> "$installUrl/apks/v$vancedVersion/$variant/Arch/split_config.$arch.apk"
"stock" -> "$themePath/stock.apk"
"dpi" -> "$themePath/dpi.apk"
"lang" -> "$installUrl/apks/v$vancedVersion/$variant/Language/split_config.${lang[count]}.apk"
else -> throw NotImplementedError("This type of APK is NOT valid. What the hell did you even do?")
}
fuelDownload(url, folderName!!, getFileNameFromUrl(url), context, onDownloadComplete = {
when (type) {
"theme" ->
if (variant == "root") {
if (validateTheme(downloadPath!!, theme!!, hashUrl, context)) {
if (downloadStockCheck(vancedRootPkg, vancedVersionCode, context))
downloadSplits(context, "arch")
else
startVancedInstall(context)
} else
downloadSplits(context, "theme")
} else
downloadSplits(context, "arch")
"arch" -> if (variant == "root") downloadSplits(context, "stock") else downloadSplits(context, "lang")
"stock" -> downloadSplits(context, "dpi")
"dpi" -> downloadSplits(context, "lang")
"lang" -> {
count++
succesfulLangCount++
if (count < lang.size)
downloadSplits(context, "lang")
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)))
}
})
}
fun startVancedInstall(context: Context, variant: String? = this.variant) {
downloadProgress.value?.installing?.value = true
downloadProgress.value?.reset()
downloadProgress.value?.installing?.postValue(true)
downloadProgress.value?.postReset()
FirebaseAnalytics.getInstance(context).logEvent(FirebaseAnalytics.Event.SELECT_ITEM) {
variant?.let { param("vanced_variant", it) }
theme?.let { param("vanced_theme", it) }

View File

@ -1,6 +1,7 @@
package com.vanced.manager.model
import androidx.lifecycle.MutableLiveData
import com.github.kittinunf.fuel.core.requests.CancellableRequest
open class ProgressModel {
@ -8,13 +9,18 @@ open class ProgressModel {
val downloadingFile = MutableLiveData<String>()
val installing = MutableLiveData<Boolean>()
var currentDownload: Int = 0
var currentDownload: CancellableRequest? = null
fun reset() {
downloadProgress.value = 0
downloadingFile.value = ""
}
fun postReset() {
downloadProgress.postValue(0)
downloadingFile.postValue("")
}
init {
installing.value = false
reset()

View File

@ -13,11 +13,11 @@ import androidx.navigation.NavDestination
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupWithNavController
import androidx.preference.PreferenceManager.*
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.crowdin.platform.Crowdin
import com.crowdin.platform.LoadingStateListener
import com.google.firebase.messaging.FirebaseMessaging
import com.vanced.manager.BuildConfig.*
import com.vanced.manager.BuildConfig.ENABLE_CROWDIN_AUTH
import com.vanced.manager.R
import com.vanced.manager.databinding.ActivityMainBinding
import com.vanced.manager.ui.dialogs.DialogContainer

View File

@ -11,7 +11,6 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.downloader.PRDownloader
import com.vanced.manager.R
import com.vanced.manager.core.downloader.MicrogDownloader.downloadMicrog
import com.vanced.manager.core.downloader.MusicDownloader.downloadMusic
@ -91,7 +90,7 @@ class AppDownloadDialog : BindingDialogFragment<DialogAppDownloadBinding>() {
if (installing) {
return@setOnClickListener
}
PRDownloader.cancel(progressModel.currentDownload)
progressModel.currentDownload?.cancel()
dismiss()
}
}

View File

@ -2,7 +2,6 @@ package com.vanced.manager.ui.dialogs
import android.content.DialogInterface
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.edit

View File

@ -3,7 +3,7 @@ package com.vanced.manager.ui.dialogs
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.preference.PreferenceManager.*
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.vanced.manager.R
import com.vanced.manager.core.downloader.MicrogDownloader.startMicrogInstall
import com.vanced.manager.core.downloader.MusicDownloader.startMusicInstall

View File

@ -2,15 +2,10 @@ package com.vanced.manager.ui.dialogs
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.edit
import androidx.databinding.DataBindingUtil
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.radiobutton.MaterialRadioButton
import com.vanced.manager.R
import com.vanced.manager.databinding.DialogInstallationFilesDetectedBinding
import com.vanced.manager.databinding.DialogManagerAccentColorBinding
import com.vanced.manager.ui.core.BindingBottomSheetDialogFragment
import com.vanced.manager.utils.Extensions.getCheckedButtonTag

View File

@ -3,11 +3,12 @@ package com.vanced.manager.ui.dialogs
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.*
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import androidx.core.content.edit
import androidx.preference.PreferenceManager.*
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.google.android.material.radiobutton.MaterialRadioButton
import com.vanced.manager.BuildConfig.*
import com.vanced.manager.BuildConfig.MANAGER_LANGUAGES
import com.vanced.manager.databinding.DialogManagerLanguageBinding
import com.vanced.manager.ui.core.BindingBottomSheetDialogFragment
import com.vanced.manager.utils.Extensions.getCheckedButtonTag

View File

@ -4,7 +4,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.edit
import androidx.preference.PreferenceManager.*
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.google.android.material.radiobutton.MaterialRadioButton
import com.vanced.manager.databinding.DialogManagerThemeBinding
import com.vanced.manager.ui.core.BindingBottomSheetDialogFragment

View File

@ -10,22 +10,19 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.downloader.PRDownloader
import com.vanced.manager.R
import com.vanced.manager.databinding.DialogManagerUpdateBinding
import com.vanced.manager.ui.core.BindingDialogFragment
import com.vanced.manager.utils.DownloadHelper.downloadManager
import com.vanced.manager.utils.DownloadHelper.downloadProgress
import com.vanced.manager.utils.InternetTools.isUpdateAvailable
import kotlinx.coroutines.launch
class ManagerUpdateDialog : BindingDialogFragment<DialogManagerUpdateBinding>() {
companion object {
const val CLOSE_DIALOG = "close_dialog"
const val CLOSE_DIALOG = "CLOSE_DIALOG"
private const val TAG_FORCE_UPDATE = "TAG_FORCE_UPDATE"
fun newInstance(
@ -56,18 +53,16 @@ class ManagerUpdateDialog : BindingDialogFragment<DialogManagerUpdateBinding>()
override fun otherSetups() {
dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
bindData()
lifecycleScope.launch {
if (arguments?.getBoolean(TAG_FORCE_UPDATE) == true) {
binding.managerUpdatePatient.text = requireActivity().getString(R.string.please_be_patient)
downloadManager(requireActivity())
} else {
checkUpdates()
}
if (arguments?.getBoolean(TAG_FORCE_UPDATE) == true) {
binding.managerUpdatePatient.text = requireActivity().getString(R.string.please_be_patient)
downloadManager(requireActivity())
} else {
checkUpdates()
}
binding.managerUpdateCancel.setOnClickListener {
PRDownloader.cancel(downloadProgress.value?.currentDownload)
dismiss()
}
binding.managerUpdateCancel.setOnClickListener {
downloadProgress.value?.currentDownload?.cancel()
dismiss()
}
}
@ -94,7 +89,7 @@ class ManagerUpdateDialog : BindingDialogFragment<DialogManagerUpdateBinding>()
registerReceiver()
}
private suspend fun checkUpdates() {
private fun checkUpdates() {
if (isUpdateAvailable()) {
binding.managerUpdatePatient.text = requireActivity().getString(R.string.please_be_patient)
downloadManager(requireActivity())

View File

@ -4,7 +4,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.edit
import androidx.preference.PreferenceManager.*
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import com.google.android.material.radiobutton.MaterialRadioButton
import com.topjohnwu.superuser.Shell
import com.vanced.manager.databinding.DialogManagerVariantBinding

View File

@ -5,7 +5,7 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.content.edit
import androidx.preference.PreferenceManager.*
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import androidx.recyclerview.widget.LinearLayoutManager
import com.vanced.manager.R
import com.vanced.manager.adapter.SelectAppsAdapter

View File

@ -5,7 +5,8 @@ import android.content.DialogInterface
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.*
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.LinearLayout
import android.widget.Toast
import androidx.core.content.edit

View File

@ -4,11 +4,8 @@ import android.content.Context
import android.content.DialogInterface
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.edit
import androidx.databinding.DataBindingUtil
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.radiobutton.MaterialRadioButton
import com.vanced.manager.R
import com.vanced.manager.databinding.DialogBottomRadioButtonBinding

View File

@ -10,7 +10,7 @@ import androidx.core.content.edit
import androidx.core.net.toUri
import androidx.preference.*
import com.crowdin.platform.Crowdin
import com.vanced.manager.BuildConfig.*
import com.vanced.manager.BuildConfig.ENABLE_CROWDIN_AUTH
import com.vanced.manager.R
import com.vanced.manager.ui.WelcomeActivity
import com.vanced.manager.ui.dialogs.ManagerUpdateDialog

View File

@ -32,8 +32,8 @@ import com.vanced.manager.ui.viewmodels.HomeViewModelFactory
open class HomeFragment : BindingFragment<FragmentHomeBinding>() {
companion object {
const val INSTALL_FAILED = "install_failed"
const val REFRESH_HOME = "refresh_home"
const val INSTALL_FAILED = "INSTALL_FAILED"
const val REFRESH_HOME = "REFRESH_HOME"
}
private val viewModel: HomeViewModel by viewModels {

View File

@ -10,5 +10,4 @@ object DeviceUtils {
else -> "armeabi_v7a"
}
}

View File

@ -1,37 +1,41 @@
package com.vanced.manager.utils
import android.app.DownloadManager
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.util.Log
import android.widget.Toast
import androidx.core.content.FileProvider
import androidx.core.content.getSystemService
import androidx.core.net.toUri
import androidx.lifecycle.MutableLiveData
import com.downloader.OnDownloadListener
import com.downloader.PRDownloader
import com.github.kittinunf.fuel.Fuel
import com.vanced.manager.R
import com.vanced.manager.model.ProgressModel
import com.vanced.manager.utils.AppUtils.sendCloseDialog
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.coroutines.launch
import java.io.File
object DownloadHelper {
object DownloadHelper : CoroutineScope by CoroutineScope(Dispatchers.IO) {
fun download(url: String, dir: String, child: String, context: Context): Long {
val request = DownloadManager.Request(url.toUri()).apply {
setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI)
setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)
setTitle(context.getString(R.string.downloading_file, child))
setDestinationInExternalFilesDir(context, dir, child)
}
val downloadManager = context.getSystemService<DownloadManager>()!!
return downloadManager.enqueue(request)
fun fuelDownload(url: String, fileFolder: String, fileName: String, context: Context, onDownloadComplete: () -> Unit, onError: (error: String) -> Unit) = launch {
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 ->
Log.d("VMDownloader", error.errorData.toString())
onError(error.errorData.toString())
})
}
}
val downloadProgress = MutableLiveData<ProgressModel>()
@ -40,46 +44,25 @@ object DownloadHelper {
downloadProgress.value = ProgressModel()
}
suspend fun downloadManager(context: Context) =
withContext(Dispatchers.IO) {
val url = "https://github.com/YTVanced/VancedManager/releases/latest/download/manager.apk"
downloadProgress.value?.currentDownload = PRDownloader.download(url, context.getExternalFilesDir("manager")?.path, "manager.apk")
.build()
.setOnProgressListener { progress ->
val mProgress = progress.currentBytes * 100 / progress.totalBytes
downloadProgress.value?.downloadProgress?.value = mProgress.toInt()
}
.setOnCancelListener {
downloadProgress.value?.downloadProgress?.value = 0
}
.start(object : OnDownloadListener {
override fun onDownloadComplete() {
downloadProgress.value?.downloadProgress?.value = 0
val apk =
File("${context.getExternalFilesDir("manager")?.path}/manager.apk")
val uri =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
FileProvider.getUriForFile(
context,
"${context.packageName}.provider",
apk
)
else
Uri.fromFile(apk)
fun downloadManager(context: Context) {
val url = "https://github.com/YTVanced/VancedManager/releases/latest/download/manager.apk"
fuelDownload(url, "manager", "manager.apk", context, onDownloadComplete = {
val apk = File("${context.getExternalFilesDir("manager")?.path}/manager.apk")
val uri =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
FileProvider.getUriForFile(context, "${context.packageName}.provider", apk)
else
Uri.fromFile(apk)
val intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(uri, "application/vnd.android.package-archive")
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
context.startActivity(intent)
sendCloseDialog(context)
}
val intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(uri, "application/vnd.android.package-archive")
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
context.startActivity(intent)
sendCloseDialog(context)
}, onError = {
downloadProgress.value?.downloadingFile?.postValue(context.getString(R.string.error_downloading, "manager.apk"))
})
}
override fun onError(error: com.downloader.Error?) {
Toast.makeText(context, error.toString(), Toast.LENGTH_SHORT).show()
Log.e("VMUpgrade", error.toString())
}
})
}
}

View File

@ -32,8 +32,6 @@ object InternetTools {
var vancedVersions = ObservableField<JsonArray<String>>()
var musicVersions = ObservableField<JsonArray<String>>()
const val backupUrl = "https://mirror.codebucket.de/vanced/api/v1"
//var braveTiers = ObservableField<JsonObject?>()
fun openUrl(url: String, color: Int, context: Context) {
@ -80,7 +78,7 @@ object InternetTools {
}
suspend fun getJsonString(file: String, obj: String, context: Context): String {
private suspend fun getJsonString(file: String, obj: String, context: Context): String {
val installUrl = context.getDefaultPrefs().getString("install_url", baseUrl)
return try {
JsonHelper.getJson("$installUrl/$file")?.string(obj) ?: context.getString(R.string.unavailable)
@ -91,9 +89,11 @@ object InternetTools {
}
fun isUpdateAvailable(): Boolean {
val result = manager.get()?.int("versionCode") ?: 0
return result > BuildConfig.VERSION_CODE
while (true) {
if (manager.get() != null) {
return manager.get()?.int("versionCode") ?: 0 > BuildConfig.VERSION_CODE
}
}
}
suspend fun getSha256(hashUrl: String, obj: String, context: Context): String {