fix: 업데이트 설치 버그 수정 및 Android 12+ 호환성 개선 (v1.11.4)
- BroadcastReceiver에 RECEIVER_NOT_EXPORTED 플래그 추가 (Android 12+) - 다운로드 완료 후 리시버 자동 해제로 메모리 누수 방지 - FileProvider 경로 수정으로 APK 설치 실패 문제 해결 - 버전 1.11.4로 업데이트
This commit is contained in:
@@ -24,8 +24,8 @@ android {
|
||||
applicationId = "com.hotdeal.alarm"
|
||||
minSdk = 31
|
||||
targetSdk = 35
|
||||
versionCode = 20
|
||||
versionName = "1.11.3"
|
||||
versionCode = 21
|
||||
versionName = "1.11.4"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
vectorDrawables {
|
||||
|
||||
@@ -172,10 +172,7 @@ class MainActivity : ComponentActivity() {
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
// 리시버 해제
|
||||
downloadReceiver?.let {
|
||||
ApkDownloadManager.unregisterDownloadCompleteReceiver(this, it)
|
||||
}
|
||||
ApkDownloadManager.unregisterDownloadCompleteReceiver(this)
|
||||
}
|
||||
|
||||
// 비저빌리티 콜백 - 백그라운드에서 포어그라운드 전환 시 새로고침
|
||||
|
||||
@@ -477,22 +477,20 @@ private fun MoreTab(viewModel: MainViewModel) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun downloadAndInstallApk(context: Context, updateInfo: com.hotdeal.alarm.util.UpdateInfo) {
|
||||
// ApkDownloadManager를 사용하여 다운로드 시작 및 자동 설치
|
||||
val downloadId = ApkDownloadManager.downloadApk(context, updateInfo)
|
||||
|
||||
// 다운로드 완료 리시버 등록 - 완료 시 자동 설치
|
||||
ApkDownloadManager.registerDownloadCompleteReceiver(
|
||||
context = context,
|
||||
downloadId = downloadId,
|
||||
onComplete = {
|
||||
ApkDownloadManager.installApk(context)
|
||||
},
|
||||
onFailed = {
|
||||
Toast.makeText(context, "다운로드 실패. 다시 시도해주세요.", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
)
|
||||
}
|
||||
private fun downloadAndInstallApk(context: Context, updateInfo: com.hotdeal.alarm.util.UpdateInfo) {
|
||||
val downloadId = ApkDownloadManager.downloadApk(context, updateInfo)
|
||||
|
||||
ApkDownloadManager.registerDownloadCompleteReceiver(
|
||||
context = context,
|
||||
downloadId = downloadId,
|
||||
onComplete = {
|
||||
ApkDownloadManager.installApk(context)
|
||||
},
|
||||
onFailed = {
|
||||
Toast.makeText(context, "다운로드 실패. 다시 시도해주세요.", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// ==================== 공통 컴포넌트 ====================
|
||||
|
||||
|
||||
@@ -6,7 +6,9 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Environment
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.core.content.FileProvider
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -19,8 +21,12 @@ import java.io.File
|
||||
*/
|
||||
object ApkDownloadManager {
|
||||
|
||||
private const val TAG = "ApkDownloadManager"
|
||||
private const val APK_FILE_NAME = "hotdeal-alarm-update.apk"
|
||||
|
||||
// 등록된 리시버 추적 (메모리 누수 방지)
|
||||
private var registeredReceiver: BroadcastReceiver? = null
|
||||
|
||||
/**
|
||||
* APK 다운로드 시작
|
||||
*/
|
||||
@@ -65,6 +71,9 @@ object ApkDownloadManager {
|
||||
onComplete: () -> Unit,
|
||||
onFailed: () -> Unit
|
||||
): BroadcastReceiver {
|
||||
// 기존 리시버가 있으면 먼저 해제
|
||||
unregisterDownloadCompleteReceiver(context)
|
||||
|
||||
val receiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
val id = intent?.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1) ?: -1
|
||||
@@ -72,15 +81,25 @@ object ApkDownloadManager {
|
||||
val downloadManager = context?.getSystemService(Context.DOWNLOAD_SERVICE) as? DownloadManager
|
||||
val query = DownloadManager.Query().setFilterById(downloadId)
|
||||
val cursor = downloadManager?.query(query)
|
||||
|
||||
|
||||
cursor?.use {
|
||||
if (it.moveToFirst()) {
|
||||
val statusIndex = it.getColumnIndex(DownloadManager.COLUMN_STATUS)
|
||||
val status = it.getInt(statusIndex)
|
||||
|
||||
|
||||
when (status) {
|
||||
DownloadManager.STATUS_SUCCESSFUL -> onComplete()
|
||||
DownloadManager.STATUS_FAILED -> onFailed()
|
||||
DownloadManager.STATUS_SUCCESSFUL -> {
|
||||
Log.d(TAG, "다운로드 완료, 설치 시작")
|
||||
onComplete()
|
||||
// 설치 후 리시버 해제
|
||||
unregisterDownloadCompleteReceiver(context)
|
||||
}
|
||||
DownloadManager.STATUS_FAILED -> {
|
||||
Log.e(TAG, "다운로드 실패")
|
||||
onFailed()
|
||||
// 실패 시 리시버 해제
|
||||
unregisterDownloadCompleteReceiver(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,10 +107,22 @@ object ApkDownloadManager {
|
||||
}
|
||||
}
|
||||
|
||||
context.registerReceiver(
|
||||
receiver,
|
||||
IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)
|
||||
)
|
||||
// Android 12+ 에서는 RECEIVER_NOT_EXPORTED 플래그 필요
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
context.registerReceiver(
|
||||
receiver,
|
||||
IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE),
|
||||
Context.RECEIVER_NOT_EXPORTED
|
||||
)
|
||||
} else {
|
||||
context.registerReceiver(
|
||||
receiver,
|
||||
IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)
|
||||
)
|
||||
}
|
||||
|
||||
registeredReceiver = receiver
|
||||
Log.d(TAG, "다운로드 리시버 등록됨, downloadId=$downloadId")
|
||||
|
||||
return receiver
|
||||
}
|
||||
@@ -99,11 +130,15 @@ object ApkDownloadManager {
|
||||
/**
|
||||
* 다운로드 완료 리시버 해제
|
||||
*/
|
||||
fun unregisterDownloadCompleteReceiver(context: Context, receiver: BroadcastReceiver) {
|
||||
try {
|
||||
context.unregisterReceiver(receiver)
|
||||
} catch (e: Exception) {
|
||||
// 이미 해제된 경우 무시
|
||||
fun unregisterDownloadCompleteReceiver(context: Context) {
|
||||
registeredReceiver?.let { receiver ->
|
||||
try {
|
||||
context.unregisterReceiver(receiver)
|
||||
Log.d(TAG, "다운로드 리시버 해제됨")
|
||||
} catch (e: Exception) {
|
||||
Log.w(TAG, "리시버 해제 실패 (이미 해제됨): ${e.message}")
|
||||
}
|
||||
registeredReceiver = null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<paths>
|
||||
<external-files-path
|
||||
name="downloads"
|
||||
path="Download" />
|
||||
path="." />
|
||||
<cache-path
|
||||
name="cache"
|
||||
path="." />
|
||||
|
||||
12
version.json
12
version.json
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"version": "1.11.3",
|
||||
"versionCode": 20,
|
||||
"updateUrl": "https://git.webpluss.net/sanjeok77/hotdeal_alarm/releases/download/v1.11.3/app-release.apk",
|
||||
"version": "1.11.4",
|
||||
"versionCode": 21,
|
||||
"updateUrl": "https://git.webpluss.net/sanjeok77/hotdeal_alarm/releases/download/v1.11.4/app-release.apk",
|
||||
"changelog": [
|
||||
"뽐뿌 인기 게시물 뱃지 표시",
|
||||
"인기 게시물 감지 기능 추가",
|
||||
"DB 마이그레이션 (v4->v5)"
|
||||
"업데이트 설치 버그 수정",
|
||||
"Android 12+ 호환성 개선",
|
||||
"다운로드 리시버 생명주기 관리 개선"
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user