add update file

This commit is contained in:
2026-07-25 23:08:44 +03:00
parent 356d70b737
commit ee340f11ed
10 changed files with 90 additions and 48 deletions
@@ -2,4 +2,17 @@
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"
tools:ignore="RequestInstallPackagesPolicy" />
<application>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
</manifest>
@@ -2,14 +2,17 @@ package ru.shadowsparky.updater.data
import android.app.Application
import io.ktor.client.HttpClient
import io.ktor.client.request.get
import io.ktor.client.request.prepareGet
import io.ktor.client.statement.bodyAsChannel
import io.ktor.http.contentLength
import io.ktor.utils.io.ByteReadChannel
import io.ktor.utils.io.readAvailable
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.withContext
import org.koin.core.annotation.Factory
import ru.shadowsparky.domain.DispatcherProvider
import ru.shadowsparky.updater.domain.DownloadProgress
import ru.shadowsparky.updater.domain.UpdateDownloader
import java.io.File
@@ -18,55 +21,58 @@ import java.io.File
class KtorUpdateDownloader(
private val httpClient: HttpClient,
app: Application,
private val dispatcherProvider: DispatcherProvider
) : UpdateDownloader {
private val destinationPath = "${app.cacheDir.absolutePath}/update"
override fun download(url: String): Flow<DownloadProgress> = flow {
try {
val response = httpClient.get(url)
val contentLength = response.contentLength() ?: -1L
val channel: ByteReadChannel = response.bodyAsChannel()
httpClient.prepareGet(url).execute { response ->
val contentLength = response.contentLength() ?: -1L
val channel: ByteReadChannel = response.bodyAsChannel()
val directory = File(destinationPath)
if (!directory.exists()) {
directory.mkdirs()
}
val fileName = "update.apk"
val fullPath = "$destinationPath/$fileName"
val file = File(fullPath)
val directory = File(destinationPath)
if (!directory.exists()) {
directory.mkdirs()
}
if (file.exists()) file.delete()
val fileName = "update.apk"
val fullPath = "$destinationPath/$fileName"
val file = File(fullPath)
val bufferSize = 8192
val buffer = ByteArray(bufferSize)
var downloadedBytes = 0L
if (file.exists()) file.delete()
file.outputStream().use { outputStream ->
while (!channel.isClosedForRead) {
val read = channel.readAvailable(buffer, 0, buffer.size)
if (read <= 0) break
val bufferSize = 8192
val buffer = ByteArray(bufferSize)
var downloadedBytes = 0L
outputStream.write(buffer, 0, read)
downloadedBytes += read
file.outputStream().use { outputStream ->
while (!channel.isClosedForRead) {
val read = channel.readAvailable(buffer, 0, buffer.size)
if (read <= 0) break
outputStream.write(buffer, 0, read)
downloadedBytes += read
if (contentLength > 0) {
val progress = downloadedBytes.toFloat() / contentLength.toFloat()
emit(
DownloadProgress.Active(
progress = progress,
downloadedBytes = downloadedBytes,
totalBytes = contentLength
if (contentLength > 0) {
val progress = downloadedBytes.toFloat() / contentLength.toFloat()
emit(
DownloadProgress.Active(
progress = progress,
downloadedBytes = downloadedBytes,
totalBytes = contentLength
)
)
)
}
}
}
}
emit(DownloadProgress.Success(path = file.absolutePath))
val finalFile = File("$destinationPath/update.apk")
emit(DownloadProgress.Success(path = finalFile.absolutePath))
} catch (e: Exception) {
emit(DownloadProgress.Error(e))
}
}.flowOn(dispatcherProvider.io)
override suspend fun clean(): Unit = withContext(dispatcherProvider.io) {
File(destinationPath).deleteRecursively()
}
}