Использование Dagger2 и Service вместе. Kotlin
Есть Service и Fragment. В Service инжектятся параметры. Суть сервиса заключается в том, что он должен раз в день парсить данные с сайта и, если они подходят под условия, то высылается уведомление. При попытке создать Intent для запуска Service во фрагменте возникает ошибка java.lang.RuntimeException: Unable to create service com.example.currencytask.ui.home.NotificationService: java.lang.InstantiationException: java.lang.Class<com.example.currencytask.ui.home.NotificationService> has no zero argument constructor
.
Код сервиса:
class NotificationService @Inject constructor(
private val iGetCurrencyListUseCase: IGetCurrencyListUseCase,
private val iSharedPrefsRepository: ISharedPrefsRepository,
private val context: Context
) : Service() {
private lateinit var scheduler: ScheduledExecutorService
private lateinit var notificationManager: NotificationManager
private val serviceScope = CoroutineScope(Dispatchers.Default)
private val currencyId = "R01235"
override fun onBind(intent: Intent?): IBinder? {
return null
}
override fun onCreate() {
super.onCreate()
notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
startScheduler()
return START_STICKY
}
override fun onDestroy() {
scheduler.shutdown()
super.onDestroy()
}
private fun startScheduler() {
scheduler = Executors.newSingleThreadScheduledExecutor()
serviceScope.launch {
val currentTime = LocalTime.now()
val initialDelay = currentTime.until(LocalTime.of(12, 0), ChronoUnit.SECONDS)
delay(initialDelay)
while (isActive) {
val defaultCurrency = iSharedPrefsRepository.getDefaultCurrency()
val dateTo = LocalDate.now().format(DateTimeFormatter.ofPattern("dd/MM/yyyy"))
val dateFrom =
LocalDate.now().plusMonths(-1).format(DateTimeFormatter.ofPattern("dd/MM/yyyy"))
val currencyList = iGetCurrencyListUseCase.invoke(dateFrom, dateTo, currencyId)
if (currencyList.records?.reversed()?.get(0)?.value?.let {
compareStringsAsNumbers(
it,
defaultCurrency
)
} == 1
) sendNotification()
//delay(24 * 60 * 60 * 1000)
delay(5 * 1000)
}
}
}
private fun sendNotification() {
val intent = Intent(context, MainApplication::class.java)
intent.apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent = PendingIntent.getActivity(
context,
0,
intent,
PendingIntent.FLAG_IMMUTABLE
)
val notificationId = 101
val channelId = "currency_update"
val channelName = "Currency Update"
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel(channelId, channelName, importance)
notificationManager.createNotificationChannel(channel)
val builder = NotificationCompat.Builder(context, channelId)
.setSmallIcon(R.drawable.ic_dollar)
.setContentTitle("Оповещение")
.setContentText("Цена поднялась")
.setAutoCancel(true)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pendingIntent)
notificationManager.notify(notificationId, builder.build())
}
private fun compareStringsAsNumbers(str1: String, str2: String): Int {
val number1 = str1.replace(",", ".").toDouble()
val number2 = str2.replace(",", ".").toDouble()
Log.e("First number", number1.toString())
Log.e("Second number", number2.toString())
return when {
number1 < number2 -> -1
number1 > number2 -> 1
else -> 0
}
}
}
Часть фрагмента:
class HomeFragment : Fragment() {
@Inject
lateinit var notificationService: NotificationService
//...остальной код
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val serviceIntent = Intent(context, NotificationService::class.java)
// был еще такой вариант
// val serviceIntent = Intent(context, notificationService::class.java)
requireActivity().startForegroundService(serviceIntent)
Я понимаю, что при создании интента нужно передавать данные в конструктор сервиса, но как сделать, чтобы они сами инжектились? Возможно, неправильно написан модуль.
@Module
class NotificationModule {
@Provides
fun provideNotificationService(
iGetCurrencyListUseCase: IGetCurrencyListUseCase,
iSharedPrefsRepository: ISharedPrefsRepository,
context: Context
): NotificationService {
return NotificationService(iGetCurrencyListUseCase, iSharedPrefsRepository, context)
}
}
Возможно, есть другой способ запуска сервиса или его вообще не нужно использовать в DI, тогда как получить доступ к репозиторию?. Не нашел ответа в интернете.