Initial commit - v1.1.9
This commit is contained in:
187
app/src/main/java/com/example/shiftalarm/AppUpdateManager.kt
Normal file
187
app/src/main/java/com/example/shiftalarm/AppUpdateManager.kt
Normal file
@@ -0,0 +1,187 @@
|
||||
package com.example.shiftalarm
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.ProgressDialog
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.content.FileProvider
|
||||
import org.json.JSONObject
|
||||
import java.io.BufferedInputStream
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.URL
|
||||
|
||||
object AppUpdateManager {
|
||||
|
||||
private const val VERSION_URL = "https://git.webpluss.net/sanjeok77/ShiftRing/raw/branch/main/version.json"
|
||||
|
||||
fun checkUpdate(activity: Activity, silent: Boolean = false) {
|
||||
val ctx = activity.applicationContext
|
||||
val versionCheckUrl = "$VERSION_URL?t=${System.currentTimeMillis()}"
|
||||
|
||||
Thread {
|
||||
try {
|
||||
val url = URL(versionCheckUrl)
|
||||
val connection = url.openConnection() as HttpURLConnection
|
||||
connection.connectTimeout = 5000
|
||||
connection.readTimeout = 5000
|
||||
connection.requestMethod = "GET"
|
||||
connection.useCaches = false
|
||||
|
||||
if (connection.responseCode == 200) {
|
||||
val reader = connection.inputStream.bufferedReader()
|
||||
val result = reader.readText()
|
||||
reader.close()
|
||||
|
||||
val json = JSONObject(result)
|
||||
val serverVersionName = json.getString("versionName")
|
||||
val apkUrl = json.getString("apkUrl")
|
||||
val changelog = json.optString("changelog", "버그 수정 및 성능 향상")
|
||||
|
||||
val pInfo = ctx.packageManager.getPackageInfo(ctx.packageName, 0)
|
||||
val currentVersionName = pInfo.versionName ?: "0.0.0"
|
||||
|
||||
if (isNewerVersion(serverVersionName, currentVersionName)) {
|
||||
activity.runOnUiThread {
|
||||
showUpdateDialog(activity, serverVersionName, changelog, apkUrl)
|
||||
}
|
||||
} else if (!silent) {
|
||||
activity.runOnUiThread {
|
||||
Toast.makeText(ctx, "현재 최신 버전을 사용 중입니다. ($currentVersionName)", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
} else if (!silent) {
|
||||
activity.runOnUiThread {
|
||||
Toast.makeText(ctx, "서버 연결 실패", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
if (!silent) {
|
||||
activity.runOnUiThread {
|
||||
Toast.makeText(ctx, "업데이트 확인 중 오류 발생", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
private fun isNewerVersion(server: String, current: String): Boolean {
|
||||
try {
|
||||
// Clean version strings (remove non-numeric suffixes if any)
|
||||
val sClean = server.split("-")[0].split(" ")[0]
|
||||
val cClean = current.split("-")[0].split(" ")[0]
|
||||
|
||||
val sParts = sClean.split(".").map { it.filter { char -> char.isDigit() }.let { p -> if (p.isEmpty()) 0 else p.toInt() } }
|
||||
val cParts = cClean.split(".").map { it.filter { char -> char.isDigit() }.let { p -> if (p.isEmpty()) 0 else p.toInt() } }
|
||||
|
||||
val length = Math.max(sParts.size, cParts.size)
|
||||
for (i in 0 until length) {
|
||||
val s = if (i < sParts.size) sParts[i] else 0
|
||||
val c = if (i < cParts.size) cParts[i] else 0
|
||||
if (s > c) return true
|
||||
if (s < c) return false
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
android.util.Log.e("AppUpdateManager", "Version comparison failed: ${e.message}")
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun showUpdateDialog(activity: Activity, version: String, changelog: String, apkUrl: String) {
|
||||
com.google.android.material.dialog.MaterialAlertDialogBuilder(activity)
|
||||
.setTitle("새로운 업데이트 발견 (v$version)")
|
||||
.setMessage("업데이트 내용:\n$changelog\n\n지금 다운로드하시겠습니까?")
|
||||
.setPositiveButton("다운로드") { _, _ ->
|
||||
downloadAndInstallApk(activity, apkUrl, version)
|
||||
}
|
||||
.setNegativeButton("나중에", null)
|
||||
.show()
|
||||
}
|
||||
|
||||
private fun downloadAndInstallApk(activity: Activity, apkUrl: String, version: String) {
|
||||
val progressDialog = ProgressDialog(activity).apply {
|
||||
setTitle("업데이트 다운로드 중")
|
||||
setMessage("v$version 다운로드 중...")
|
||||
setProgressStyle(ProgressDialog.STYLE_HORIZONTAL)
|
||||
setCancelable(false)
|
||||
max = 100
|
||||
show()
|
||||
}
|
||||
|
||||
Thread {
|
||||
try {
|
||||
val url = URL(apkUrl)
|
||||
val connection = url.openConnection() as HttpURLConnection
|
||||
connection.connectTimeout = 15000
|
||||
connection.readTimeout = 15000
|
||||
connection.requestMethod = "GET"
|
||||
connection.connect()
|
||||
|
||||
val fileLength = connection.contentLength
|
||||
val inputStream = BufferedInputStream(connection.inputStream)
|
||||
|
||||
val apkFile = File(activity.cacheDir, "update.apk")
|
||||
val outputStream = FileOutputStream(apkFile)
|
||||
|
||||
val buffer = ByteArray(8192)
|
||||
var total: Long = 0
|
||||
var count: Int
|
||||
|
||||
while (inputStream.read(buffer).also { count = it } != -1) {
|
||||
total += count
|
||||
outputStream.write(buffer, 0, count)
|
||||
|
||||
if (fileLength > 0) {
|
||||
val progress = (total * 100 / fileLength).toInt()
|
||||
activity.runOnUiThread {
|
||||
progressDialog.progress = progress
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
outputStream.flush()
|
||||
outputStream.close()
|
||||
inputStream.close()
|
||||
connection.disconnect()
|
||||
|
||||
activity.runOnUiThread {
|
||||
progressDialog.dismiss()
|
||||
installApk(activity, apkFile)
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
activity.runOnUiThread {
|
||||
progressDialog.dismiss()
|
||||
Toast.makeText(activity, "다운로드 실패: ${e.message}", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
private fun installApk(activity: Activity, apkFile: File) {
|
||||
try {
|
||||
val apkUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
FileProvider.getUriForFile(activity, "${activity.packageName}.provider", apkFile)
|
||||
} else {
|
||||
Uri.fromFile(apkFile)
|
||||
}
|
||||
|
||||
val intent = Intent(Intent.ACTION_VIEW).apply {
|
||||
setDataAndType(apkUri, "application/vnd.android.package-archive")
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
}
|
||||
activity.startActivity(intent)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
Toast.makeText(activity, "설치 실패: ${e.message}", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user