Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad4cdef4cb | ||
|
|
ea79599c08 | ||
|
|
e82725887b | ||
|
|
bd4d6a35ff | ||
|
|
e332738eff | ||
|
|
aae7836e89 | ||
|
|
945f5146ed | ||
|
|
bf4037d933 | ||
|
|
47de6bad98 | ||
|
|
cd866600e6 | ||
|
|
2b51518d0e | ||
|
|
2e5f6d1ba5 | ||
|
|
204faf0186 | ||
|
|
0cf08466b6 |
No files matched your search
@@ -24,8 +24,8 @@ android {
|
|||||||
applicationId = "com.hotdeal.alarm"
|
applicationId = "com.hotdeal.alarm"
|
||||||
minSdk = 31
|
minSdk = 31
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
versionCode = 31
|
versionCode = 32
|
||||||
versionName = "0.3.1"
|
versionName = "0.3.2"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables {
|
vectorDrawables {
|
||||||
|
|||||||
@@ -65,9 +65,16 @@
|
|||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:foregroundServiceType="dataSync" />
|
android:foregroundServiceType="dataSync" />
|
||||||
|
|
||||||
<!-- Boot Receiver -->
|
<!-- Boot Receiver: 부팅/앱 업데이트 후 백그라운드 폴링 자동 재등록 -->
|
||||||
|
<receiver
|
||||||
<!-- Widget -->
|
android:name=".receiver.BootReceiver"
|
||||||
|
android:enabled="true"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||||
|
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
<receiver
|
<receiver
|
||||||
android:name=".widget.HotDealWidget"
|
android:name=".widget.HotDealWidget"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
|
|||||||
@@ -1,9 +1,17 @@
|
|||||||
package com.hotdeal.alarm
|
package com.hotdeal.alarm
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import android.util.Log
|
||||||
import androidx.hilt.work.HiltWorkerFactory
|
import androidx.hilt.work.HiltWorkerFactory
|
||||||
import androidx.work.Configuration
|
import androidx.work.Configuration
|
||||||
|
import com.hotdeal.alarm.data.local.preferences.AppSettings
|
||||||
|
import com.hotdeal.alarm.worker.WorkerScheduler
|
||||||
import dagger.hilt.android.HiltAndroidApp
|
import dagger.hilt.android.HiltAndroidApp
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.SupervisorJob
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltAndroidApp
|
@HiltAndroidApp
|
||||||
@@ -12,13 +20,41 @@ class HotDealApplication : Application(), Configuration.Provider {
|
|||||||
@Inject
|
@Inject
|
||||||
lateinit var workerFactory: HiltWorkerFactory
|
lateinit var workerFactory: HiltWorkerFactory
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var workerScheduler: WorkerScheduler
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var appSettings: AppSettings
|
||||||
|
|
||||||
|
private val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
|
||||||
|
|
||||||
override val workManagerConfiguration: Configuration
|
override val workManagerConfiguration: Configuration
|
||||||
get() = Configuration.Builder()
|
get() = Configuration.Builder()
|
||||||
.setWorkerFactory(workerFactory)
|
.setWorkerFactory(workerFactory)
|
||||||
|
.setMinimumLoggingLevel(Log.DEBUG)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
// Application initialization
|
// 앱 시작 시 백그라운드 폴링 즉시 등록/갱신
|
||||||
|
ensurePollingScheduled()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 앱이 시작될 때마다 백그라운드 폴링이 등록되어 있는지 확인하고,
|
||||||
|
* 없으면 즉시 등록합니다. UPDATE 정책으로 항상 최신 Worker가 동작합니다.
|
||||||
|
*/
|
||||||
|
private fun ensurePollingScheduled() {
|
||||||
|
applicationScope.launch {
|
||||||
|
try {
|
||||||
|
val interval = appSettings.pollingInterval.first()
|
||||||
|
Log.d("HotDealApp", "백그라운드 폴링 등록/갱신: ${interval}분 간격")
|
||||||
|
workerScheduler.schedulePeriodicPolling(interval.toLong())
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("HotDealApp", "폴링 스케줄 등록 실패: ${e.message}", e)
|
||||||
|
// 기본값으로 폴백
|
||||||
|
workerScheduler.schedulePeriodicPolling(WorkerScheduler.DEFAULT_INTERVAL_MINUTES)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.hotdeal.alarm.receiver
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.util.Log
|
||||||
|
import com.hotdeal.alarm.data.local.preferences.AppSettings
|
||||||
|
import com.hotdeal.alarm.worker.WorkerScheduler
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.SupervisorJob
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 부팅 완료 시 백그라운드 폴링을 자동으로 재등록하는 리시버
|
||||||
|
*/
|
||||||
|
@AndroidEntryPoint
|
||||||
|
class BootReceiver : BroadcastReceiver() {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var workerScheduler: WorkerScheduler
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var appSettings: AppSettings
|
||||||
|
|
||||||
|
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
|
||||||
|
|
||||||
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
if (intent.action == Intent.ACTION_BOOT_COMPLETED ||
|
||||||
|
intent.action == Intent.ACTION_MY_PACKAGE_REPLACED
|
||||||
|
) {
|
||||||
|
Log.d("BootReceiver", "부팅/업데이트 감지 → 백그라운드 폴링 재등록")
|
||||||
|
scope.launch {
|
||||||
|
try {
|
||||||
|
val interval = appSettings.pollingInterval.first()
|
||||||
|
workerScheduler.schedulePeriodicPolling(interval.toLong())
|
||||||
|
Log.d("BootReceiver", "폴링 재등록 완료: ${interval}분 간격")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("BootReceiver", "폴링 재등록 실패: ${e.message}")
|
||||||
|
workerScheduler.schedulePeriodicPolling(WorkerScheduler.DEFAULT_INTERVAL_MINUTES)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -54,7 +54,7 @@ class WorkerScheduler @Inject constructor(
|
|||||||
|
|
||||||
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
|
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
|
||||||
HotDealPollingWorker.WORK_NAME,
|
HotDealPollingWorker.WORK_NAME,
|
||||||
ExistingPeriodicWorkPolicy.KEEP,
|
ExistingPeriodicWorkPolicy.UPDATE,
|
||||||
workRequest
|
workRequest
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"version": "0.3.1",
|
"version": "0.3.2",
|
||||||
"versionCode": 31,
|
"versionCode": 32,
|
||||||
"updateUrl": "https://git.webpluss.net/sanjeok77/hotdeal_alarm/releases/download/v0.3.1/app-release.apk",
|
"updateUrl": "https://git.webpluss.net/sanjeok77/hotdeal_alarm/releases/download/v0.3.2/app-release.apk",
|
||||||
"changelog": [
|
"changelog": [
|
||||||
"사이트 및 키워드 순서 조절을 터치 드래그 앤 드롭(Drag & Drop) 방식으로 전면 업그레이드",
|
"사이트 및 키워드 순서 조절을 터치 드래그 앤 드롭(Drag & Drop) 방식으로 전면 업그레이드",
|
||||||
"앱 내 업데이트 시 다운로드 완료 후 설치 화면으로 안 넘어가는 버그 수정",
|
"앱 내 업데이트 시 다운로드 완료 후 설치 화면으로 안 넘어가는 버그 수정",
|
||||||
|
|||||||
Reference in new issue
Block a user