Make weather updates more reliable
This commit is contained in:
parent
d8e204c5d9
commit
fb3f28d035
@ -19,8 +19,15 @@ import com.tommasoberlose.anotherwidget.utils.isDarkTheme
|
||||
|
||||
object WeatherHelper {
|
||||
|
||||
fun updateWeather(context: Context) {
|
||||
WeatherWorker.enqueue(context)
|
||||
fun updateWeather(context: Context, force: Boolean = false) {
|
||||
if (Preferences.showWeather || force)
|
||||
WeatherWorker.enqueue(context, replace = force)
|
||||
else {
|
||||
removeWeather(context)
|
||||
org.greenrobot.eventbus.EventBus.getDefault().post(
|
||||
com.tommasoberlose.anotherwidget.ui.fragments.MainFragment.UpdateUiMessageEvent()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun removeWeather(context: Context) {
|
||||
|
@ -17,13 +17,11 @@ import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
|
||||
import com.tommasoberlose.anotherwidget.network.repository.*
|
||||
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
|
||||
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import java.lang.Exception
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import kotlin.coroutines.resume
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
|
||||
class WeatherNetworkApi(val context: Context) {
|
||||
suspend fun updateWeather() {
|
||||
@ -31,7 +29,7 @@ class WeatherNetworkApi(val context: Context) {
|
||||
Preferences.weatherProviderError = "-"
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
|
||||
if (Preferences.showWeather && Preferences.customLocationLat != "" && Preferences.customLocationLon != "") {
|
||||
if (Preferences.customLocationLat != "" && Preferences.customLocationLon != "") {
|
||||
when (Constants.WeatherProvider.fromInt(Preferences.weatherProvider)) {
|
||||
Constants.WeatherProvider.OPEN_WEATHER -> useOpenWeatherMap(context)
|
||||
Constants.WeatherProvider.WEATHER_GOV -> useWeatherGov(context)
|
||||
@ -42,46 +40,67 @@ class WeatherNetworkApi(val context: Context) {
|
||||
Constants.WeatherProvider.YR -> useYrProvider(context)
|
||||
}
|
||||
} else {
|
||||
if (!Preferences.showWeather)
|
||||
Preferences.weatherProviderError = context.getString(R.string.show_weather_not_visible)
|
||||
else {
|
||||
Preferences.weatherProviderLocationError = context.getString(R.string.weather_provider_error_missing_location)
|
||||
Preferences.weatherProviderError = ""
|
||||
}
|
||||
Preferences.weatherProviderLocationError = context.getString(R.string.weather_provider_error_missing_location)
|
||||
Preferences.weatherProviderError = ""
|
||||
|
||||
WeatherHelper.removeWeather(
|
||||
context
|
||||
)
|
||||
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
}
|
||||
|
||||
private fun useOpenWeatherMap(context: Context) {
|
||||
private suspend fun useOpenWeatherMap(context: Context) {
|
||||
if (Preferences.weatherProviderApiOpen != "") {
|
||||
val helper = OpenWeatherMapHelper(Preferences.weatherProviderApiOpen)
|
||||
helper.setUnits(if (Preferences.weatherTempUnit == "F") Units.IMPERIAL else Units.METRIC)
|
||||
helper.getCurrentWeatherByGeoCoordinates(Preferences.customLocationLat.toDouble(), Preferences.customLocationLon.toDouble(), object :
|
||||
CurrentWeatherCallback {
|
||||
override fun onSuccess(currentWeather: CurrentWeather?) {
|
||||
currentWeather?.let {
|
||||
Preferences.weatherTemp = currentWeather.main.temp.toFloat()
|
||||
Preferences.weatherIcon = currentWeather.weather[0].icon
|
||||
Preferences.weatherRealTempUnit = Preferences.weatherTempUnit
|
||||
MainWidget.updateWidget(context)
|
||||
when (val response = suspendCancellableCoroutine<Any?> { continuation ->
|
||||
helper.getCurrentWeatherByGeoCoordinates(Preferences.customLocationLat.toDouble(), Preferences.customLocationLon.toDouble(), object :
|
||||
CurrentWeatherCallback {
|
||||
override fun onSuccess(currentWeather: CurrentWeather?) {
|
||||
continuation.resume(currentWeather)
|
||||
}
|
||||
|
||||
override fun onFailure(throwable: Throwable?) {
|
||||
continuation.resume(throwable)
|
||||
}
|
||||
})
|
||||
}) {
|
||||
is CurrentWeather -> {
|
||||
Preferences.weatherTemp = response.main.temp.toFloat()
|
||||
Preferences.weatherIcon = response.weather[0].icon
|
||||
Preferences.weatherRealTempUnit = Preferences.weatherTempUnit
|
||||
MainWidget.updateWidget(context)
|
||||
|
||||
Preferences.weatherProviderError = ""
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
|
||||
override fun onFailure(throwable: Throwable?) {
|
||||
is Throwable -> {
|
||||
if (response.javaClass == Throwable::class.java) {
|
||||
// server error, see [OpenWeatherMapHelper.handleCurrentWeatherResponse]
|
||||
if (response.message?.startsWith("UnAuthorized") == true) {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_invalid_key)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
}
|
||||
else {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
}
|
||||
WeatherHelper.removeWeather(
|
||||
context
|
||||
)
|
||||
}
|
||||
else {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_connection)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_generic)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
}
|
||||
})
|
||||
}
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
} else {
|
||||
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_missing_key)
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
|
@ -13,11 +13,8 @@ import com.tommasoberlose.anotherwidget.helpers.*
|
||||
import com.tommasoberlose.anotherwidget.models.Event
|
||||
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||
import com.tommasoberlose.anotherwidget.utils.setExactIfCanSchedule
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.joda.time.Period
|
||||
import java.util.*
|
||||
import org.joda.time.Period
|
||||
|
||||
|
||||
class UpdatesReceiver : BroadcastReceiver() {
|
||||
@ -40,10 +37,6 @@ class UpdatesReceiver : BroadcastReceiver() {
|
||||
CalendarHelper.updateEventList(context)
|
||||
}
|
||||
|
||||
"com.sec.android.widgetapp.APPWIDGET_RESIZE",
|
||||
AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED,
|
||||
Actions.ACTION_ALARM_UPDATE,
|
||||
Actions.ACTION_UPDATE_GREETINGS,
|
||||
Actions.ACTION_TIME_UPDATE -> {
|
||||
MainWidget.updateWidget(context)
|
||||
if (intent.hasExtra(EVENT_ID)) {
|
||||
@ -51,6 +44,13 @@ class UpdatesReceiver : BroadcastReceiver() {
|
||||
}
|
||||
}
|
||||
|
||||
"com.sec.android.widgetapp.APPWIDGET_RESIZE",
|
||||
AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED,
|
||||
Actions.ACTION_ALARM_UPDATE,
|
||||
Actions.ACTION_UPDATE_GREETINGS -> {
|
||||
MainWidget.updateWidget(context)
|
||||
}
|
||||
|
||||
Actions.ACTION_CLEAR_NOTIFICATION -> {
|
||||
ActiveNotificationsHelper.clearLastNotification(context)
|
||||
}
|
||||
|
@ -1,18 +1,12 @@
|
||||
package com.tommasoberlose.anotherwidget.receivers
|
||||
|
||||
import android.app.AlarmManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.tommasoberlose.anotherwidget.global.Actions
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
|
||||
import com.tommasoberlose.anotherwidget.services.WeatherWorker
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
||||
class WeatherReceiver : BroadcastReceiver() {
|
||||
|
||||
@ -22,10 +16,9 @@ class WeatherReceiver : BroadcastReceiver() {
|
||||
Intent.ACTION_MY_PACKAGE_REPLACED,
|
||||
Intent.ACTION_TIMEZONE_CHANGED,
|
||||
Intent.ACTION_LOCALE_CHANGED,
|
||||
Intent.ACTION_TIME_CHANGED -> setUpdates(context)
|
||||
|
||||
Intent.ACTION_TIME_CHANGED,
|
||||
Actions.ACTION_WEATHER_UPDATE -> {
|
||||
WeatherWorker.enqueue(context)
|
||||
WeatherHelper.updateWeather(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -33,21 +26,12 @@ class WeatherReceiver : BroadcastReceiver() {
|
||||
companion object {
|
||||
fun setUpdates(context: Context) {
|
||||
if (Preferences.showWeather) {
|
||||
val interval = when (Preferences.weatherRefreshPeriod) {
|
||||
0 -> 30
|
||||
1 -> 60
|
||||
2 -> 60L * 3
|
||||
3 -> 60L * 6
|
||||
4 -> 60L * 12
|
||||
5 -> 60L * 24
|
||||
else -> 60
|
||||
}
|
||||
WeatherWorker.enqueuePeriodic(context, interval, TimeUnit.MINUTES)
|
||||
WeatherWorker.enqueueTrigger(context)
|
||||
}
|
||||
}
|
||||
|
||||
fun removeUpdates(context: Context) {
|
||||
WeatherWorker.cancelPeriodic(context)
|
||||
WeatherWorker.cancelTrigger(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,10 +5,10 @@ import android.content.Context
|
||||
import android.os.Build
|
||||
import android.provider.CalendarContract
|
||||
import androidx.work.Constraints
|
||||
import androidx.work.CoroutineWorker
|
||||
import androidx.work.ExistingWorkPolicy
|
||||
import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.WorkManager
|
||||
import androidx.work.Worker
|
||||
import androidx.work.WorkerParameters
|
||||
import com.tommasoberlose.anotherwidget.db.EventRepository
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
@ -20,140 +20,135 @@ import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
|
||||
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
|
||||
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
||||
import java.util.*
|
||||
import me.everything.providers.android.calendar.CalendarProvider
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class UpdateCalendarWorker(private val context: Context, params: WorkerParameters) :
|
||||
CoroutineWorker(context, params) {
|
||||
class UpdateCalendarWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
|
||||
|
||||
override suspend fun doWork(): Result {
|
||||
withContext(Dispatchers.IO) {
|
||||
UpdatesReceiver.removeUpdates(context)
|
||||
val eventRepository = EventRepository(context)
|
||||
override fun doWork(): Result {
|
||||
val context = applicationContext
|
||||
UpdatesReceiver.removeUpdates(context)
|
||||
val eventRepository = EventRepository(context)
|
||||
|
||||
if (Preferences.showEvents) {
|
||||
if (!context.checkGrantedPermission(Manifest.permission.READ_CALENDAR)) {
|
||||
eventRepository.resetNextEventData()
|
||||
eventRepository.clearEvents()
|
||||
} else {
|
||||
// fetch all events from now to next ACTION_CALENDAR_UPDATE + limit
|
||||
val now = Calendar.getInstance()
|
||||
val limit = Calendar.getInstance().apply {
|
||||
set(Calendar.MILLISECOND, 0)
|
||||
set(Calendar.SECOND, 0)
|
||||
set(Calendar.MINUTE, 0)
|
||||
set(Calendar.HOUR_OF_DAY, 0)
|
||||
add(Calendar.DATE, 1)
|
||||
when (Preferences.showUntil) {
|
||||
0 -> add(Calendar.HOUR, 3)
|
||||
1 -> add(Calendar.HOUR, 6)
|
||||
2 -> add(Calendar.HOUR, 12)
|
||||
3 -> add(Calendar.DAY_OF_MONTH, 1)
|
||||
4 -> add(Calendar.DAY_OF_MONTH, 3)
|
||||
5 -> add(Calendar.DAY_OF_MONTH, 7)
|
||||
6 -> add(Calendar.MINUTE, 30)
|
||||
7 -> add(Calendar.HOUR, 1)
|
||||
else -> add(Calendar.HOUR, 6)
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
val eventList = ArrayList<Event>()
|
||||
val provider = CalendarProvider(context)
|
||||
// apply time zone offset to correctly fetch all-day events
|
||||
val data = provider.getInstances(
|
||||
now.timeInMillis + now.timeZone.getOffset(now.timeInMillis).coerceAtMost(0),
|
||||
limit.timeInMillis + limit.timeZone.getOffset(limit.timeInMillis).coerceAtLeast(0)
|
||||
)
|
||||
if (data != null) {
|
||||
val instances = data.list
|
||||
for (instance in instances) {
|
||||
try {
|
||||
val e = provider.getEvent(instance.eventId)
|
||||
if (e == null || e.deleted || CalendarHelper.getFilteredCalendarIdList().contains(e.calendarId))
|
||||
continue
|
||||
if (e.allDay) {
|
||||
val start = Calendar.getInstance()
|
||||
start.timeInMillis = instance.begin
|
||||
val end = Calendar.getInstance()
|
||||
end.timeInMillis = instance.end
|
||||
instance.begin =
|
||||
start.timeInMillis - start.timeZone.getOffset(start.timeInMillis)
|
||||
instance.end =
|
||||
end.timeInMillis - end.timeZone.getOffset(end.timeInMillis)
|
||||
}
|
||||
if (instance.begin <= limit.timeInMillis && now.timeInMillis < instance.end) {
|
||||
/* Following check may result in "fake" all-day events with
|
||||
* non-UTC start/end time, and therefore cannot be found by
|
||||
* Calendar when tapped to open details.
|
||||
// Check all day events
|
||||
val startDate = Calendar.getInstance()
|
||||
startDate.timeInMillis = instance.begin
|
||||
val endDate = Calendar.getInstance()
|
||||
endDate.timeInMillis = instance.end
|
||||
|
||||
val isAllDay = e.allDay || (
|
||||
startDate.get(Calendar.MILLISECOND) == 0
|
||||
&& startDate.get(Calendar.SECOND) == 0
|
||||
&& startDate.get(Calendar.MINUTE) == 0
|
||||
&& startDate.get(Calendar.HOUR_OF_DAY) == 0
|
||||
&& endDate.get(Calendar.MILLISECOND) == 0
|
||||
&& endDate.get(Calendar.SECOND) == 0
|
||||
&& endDate.get(Calendar.MINUTE) == 0
|
||||
&& endDate.get(Calendar.HOUR_OF_DAY) == 0
|
||||
)
|
||||
*/
|
||||
|
||||
eventList.add(
|
||||
Event(
|
||||
id = instance.id,
|
||||
eventID = e.id,
|
||||
title = e.title ?: "",
|
||||
startDate = instance.begin,
|
||||
endDate = instance.end,
|
||||
calendarID = e.calendarId,
|
||||
allDay = e.allDay,
|
||||
address = e.eventLocation ?: "",
|
||||
selfAttendeeStatus = e.selfAttendeeStatus.toInt(),
|
||||
availability = e.availability
|
||||
)
|
||||
)
|
||||
}
|
||||
} catch (ignored: Exception) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val sortedEvents = eventList.sortEvents()
|
||||
val filteredEventList = sortedEvents.applyFilters()
|
||||
|
||||
if (filteredEventList.isEmpty()) {
|
||||
eventRepository.resetNextEventData()
|
||||
eventRepository.clearEvents()
|
||||
} else {
|
||||
eventRepository.saveEvents(sortedEvents)
|
||||
//eventRepository.saveNextEventData(filteredEventList.first())
|
||||
}
|
||||
} catch (ignored: java.lang.Exception) {
|
||||
}
|
||||
}
|
||||
enqueueTrigger(context)
|
||||
} else {
|
||||
if (Preferences.showEvents) {
|
||||
if (!context.checkGrantedPermission(Manifest.permission.READ_CALENDAR)) {
|
||||
eventRepository.resetNextEventData()
|
||||
eventRepository.clearEvents()
|
||||
} else {
|
||||
// fetch all events from now to next ACTION_CALENDAR_UPDATE + limit
|
||||
val now = Calendar.getInstance()
|
||||
val limit = Calendar.getInstance().apply {
|
||||
set(Calendar.MILLISECOND, 0)
|
||||
set(Calendar.SECOND, 0)
|
||||
set(Calendar.MINUTE, 0)
|
||||
set(Calendar.HOUR_OF_DAY, 0)
|
||||
add(Calendar.DATE, 1)
|
||||
when (Preferences.showUntil) {
|
||||
0 -> add(Calendar.HOUR, 3)
|
||||
1 -> add(Calendar.HOUR, 6)
|
||||
2 -> add(Calendar.HOUR, 12)
|
||||
3 -> add(Calendar.DAY_OF_MONTH, 1)
|
||||
4 -> add(Calendar.DAY_OF_MONTH, 3)
|
||||
5 -> add(Calendar.DAY_OF_MONTH, 7)
|
||||
6 -> add(Calendar.MINUTE, 30)
|
||||
7 -> add(Calendar.HOUR, 1)
|
||||
else -> add(Calendar.HOUR, 6)
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
val eventList = ArrayList<Event>()
|
||||
val provider = CalendarProvider(context)
|
||||
// apply time zone offset to correctly fetch all-day events
|
||||
val data = provider.getInstances(
|
||||
now.timeInMillis + now.timeZone.getOffset(now.timeInMillis).coerceAtMost(0),
|
||||
limit.timeInMillis + limit.timeZone.getOffset(limit.timeInMillis).coerceAtLeast(0)
|
||||
)
|
||||
if (data != null) {
|
||||
val instances = data.list
|
||||
for (instance in instances) {
|
||||
try {
|
||||
val e = provider.getEvent(instance.eventId)
|
||||
if (e == null || e.deleted || CalendarHelper.getFilteredCalendarIdList().contains(e.calendarId))
|
||||
continue
|
||||
if (e.allDay) {
|
||||
val start = Calendar.getInstance()
|
||||
start.timeInMillis = instance.begin
|
||||
val end = Calendar.getInstance()
|
||||
end.timeInMillis = instance.end
|
||||
instance.begin =
|
||||
start.timeInMillis - start.timeZone.getOffset(start.timeInMillis)
|
||||
instance.end =
|
||||
end.timeInMillis - end.timeZone.getOffset(end.timeInMillis)
|
||||
}
|
||||
if (instance.begin <= limit.timeInMillis && now.timeInMillis < instance.end) {
|
||||
/* Following check may result in "fake" all-day events with
|
||||
* non-UTC start/end time, and therefore cannot be found by
|
||||
* Calendar when tapped to open details.
|
||||
// Check all day events
|
||||
val startDate = Calendar.getInstance()
|
||||
startDate.timeInMillis = instance.begin
|
||||
val endDate = Calendar.getInstance()
|
||||
endDate.timeInMillis = instance.end
|
||||
|
||||
val isAllDay = e.allDay || (
|
||||
startDate.get(Calendar.MILLISECOND) == 0
|
||||
&& startDate.get(Calendar.SECOND) == 0
|
||||
&& startDate.get(Calendar.MINUTE) == 0
|
||||
&& startDate.get(Calendar.HOUR_OF_DAY) == 0
|
||||
&& endDate.get(Calendar.MILLISECOND) == 0
|
||||
&& endDate.get(Calendar.SECOND) == 0
|
||||
&& endDate.get(Calendar.MINUTE) == 0
|
||||
&& endDate.get(Calendar.HOUR_OF_DAY) == 0
|
||||
)
|
||||
*/
|
||||
|
||||
eventList.add(
|
||||
Event(
|
||||
id = instance.id,
|
||||
eventID = e.id,
|
||||
title = e.title ?: "",
|
||||
startDate = instance.begin,
|
||||
endDate = instance.end,
|
||||
calendarID = e.calendarId,
|
||||
allDay = e.allDay,
|
||||
address = e.eventLocation ?: "",
|
||||
selfAttendeeStatus = e.selfAttendeeStatus.toInt(),
|
||||
availability = e.availability
|
||||
)
|
||||
)
|
||||
}
|
||||
} catch (ignored: Exception) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val sortedEvents = eventList.sortEvents()
|
||||
val filteredEventList = sortedEvents.applyFilters()
|
||||
|
||||
if (filteredEventList.isEmpty()) {
|
||||
eventRepository.resetNextEventData()
|
||||
eventRepository.clearEvents()
|
||||
} else {
|
||||
eventRepository.saveEvents(sortedEvents)
|
||||
eventRepository.saveNextEventData(filteredEventList.first())
|
||||
}
|
||||
} catch (ignored: java.lang.Exception) {
|
||||
}
|
||||
}
|
||||
eventRepository.close()
|
||||
|
||||
UpdatesReceiver.setUpdates(context)
|
||||
MainWidget.updateWidget(context)
|
||||
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
} else {
|
||||
eventRepository.resetNextEventData()
|
||||
eventRepository.clearEvents()
|
||||
}
|
||||
eventRepository.close()
|
||||
UpdatesReceiver.setUpdates(context)
|
||||
|
||||
MainWidget.updateWidget(context)
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
|
||||
if (Preferences.showEvents)
|
||||
enqueueTrigger(context)
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
@ -169,9 +164,9 @@ class UpdateCalendarWorker(private val context: Context, params: WorkerParameter
|
||||
fun enqueueTrigger(context: Context) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
WorkManager.getInstance(context).enqueueUniqueWork(
|
||||
"updateEventListByTrigger",
|
||||
"updateEventListTrigger",
|
||||
ExistingWorkPolicy.KEEP,
|
||||
OneTimeWorkRequestBuilder<UpdateCalendarWorker>().setConstraints(
|
||||
OneTimeWorkRequestBuilder<Trigger>().setConstraints(
|
||||
Constraints.Builder().addContentUriTrigger(
|
||||
CalendarContract.CONTENT_URI,
|
||||
true
|
||||
@ -184,9 +179,17 @@ class UpdateCalendarWorker(private val context: Context, params: WorkerParameter
|
||||
fun cancelTrigger(context: Context) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
WorkManager.getInstance(context).cancelUniqueWork(
|
||||
"updateEventListByTrigger"
|
||||
"updateEventListTrigger"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Trigger(context: Context, params: WorkerParameters) : Worker(context, params) {
|
||||
override fun doWork(): Result {
|
||||
if (Preferences.showEvents && !isStopped)
|
||||
enqueue(applicationContext)
|
||||
return Result.success()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,100 +5,104 @@ import android.content.Context
|
||||
import android.location.Location
|
||||
import android.location.LocationManager
|
||||
import androidx.work.CoroutineWorker
|
||||
import androidx.work.ExistingPeriodicWorkPolicy
|
||||
import androidx.work.ExistingWorkPolicy
|
||||
import androidx.work.OneTimeWorkRequestBuilder
|
||||
import androidx.work.PeriodicWorkRequestBuilder
|
||||
import androidx.work.WorkManager
|
||||
import androidx.work.Worker
|
||||
import androidx.work.WorkerParameters
|
||||
import com.google.android.gms.common.ConnectionResult
|
||||
import com.google.android.gms.common.GoogleApiAvailability
|
||||
import com.google.android.gms.location.LocationServices
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
|
||||
import com.tommasoberlose.anotherwidget.network.WeatherNetworkApi
|
||||
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
|
||||
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.coroutines.resume
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class WeatherWorker(private val context: Context, params: WorkerParameters) :
|
||||
CoroutineWorker(context, params) {
|
||||
class WeatherWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
|
||||
|
||||
override suspend fun doWork(): Result {
|
||||
when {
|
||||
Preferences.customLocationAdd != "" -> {
|
||||
withContext(Dispatchers.IO) {
|
||||
WeatherNetworkApi(context).updateWeather()
|
||||
}
|
||||
}
|
||||
context.checkGrantedPermission(Manifest.permission.ACCESS_COARSE_LOCATION) -> {
|
||||
if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context)
|
||||
== ConnectionResult.SUCCESS
|
||||
) {
|
||||
suspendCancellableCoroutine { continuation ->
|
||||
LocationServices.getFusedLocationProviderClient(context).lastLocation.addOnCompleteListener {
|
||||
continuation.resume(if (it.isSuccessful) it.result else null)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val lm = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||
var location: Location? = null
|
||||
for (provider in lm.getProviders(true)) {
|
||||
lm.getLastKnownLocation(provider)?.let {
|
||||
if (location == null ||
|
||||
it.time - location!!.time > 2 * 60 * 1000 ||
|
||||
(it.time - location!!.time > -2 * 60 * 1000 && it.accuracy < location!!.accuracy))
|
||||
location = it
|
||||
}
|
||||
}
|
||||
location
|
||||
}.let { location ->
|
||||
if (location != null) {
|
||||
Preferences.customLocationLat = location.latitude.toString()
|
||||
Preferences.customLocationLon = location.longitude.toString()
|
||||
}
|
||||
withContext(Dispatchers.IO) {
|
||||
WeatherNetworkApi(context).updateWeather()
|
||||
val context = applicationContext
|
||||
if (Preferences.customLocationAdd == "" &&
|
||||
context.checkGrantedPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
|
||||
) {
|
||||
if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context)
|
||||
== ConnectionResult.SUCCESS
|
||||
) {
|
||||
suspendCancellableCoroutine { continuation ->
|
||||
LocationServices.getFusedLocationProviderClient(context).lastLocation.addOnCompleteListener {
|
||||
continuation.resume(if (it.isSuccessful) it.result else null)
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
Preferences.weatherProviderLocationError = context.getString(R.string.weather_provider_error_missing_location)
|
||||
Preferences.weatherProviderError = ""
|
||||
WeatherHelper.removeWeather(context)
|
||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||
} else {
|
||||
val lm = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||
var location: Location? = null
|
||||
for (provider in lm.getProviders(true)) {
|
||||
lm.getLastKnownLocation(provider)?.let {
|
||||
if (location == null ||
|
||||
it.time - location!!.time > 2 * 60 * 1000 ||
|
||||
(it.time - location!!.time > -2 * 60 * 1000 && it.accuracy < location!!.accuracy))
|
||||
location = it
|
||||
}
|
||||
}
|
||||
location
|
||||
}?.let { location ->
|
||||
Preferences.customLocationLat = location.latitude.toString()
|
||||
Preferences.customLocationLon = location.longitude.toString()
|
||||
}
|
||||
}
|
||||
withContext(Dispatchers.IO) {
|
||||
WeatherNetworkApi(context).updateWeather()
|
||||
}
|
||||
|
||||
if (Preferences.showWeather)
|
||||
enqueueTrigger(context)
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun enqueue(context: Context) {
|
||||
fun enqueue(context: Context, replace: Boolean = false) {
|
||||
WorkManager.getInstance(context).enqueueUniqueWork(
|
||||
"updateWeather",
|
||||
ExistingWorkPolicy.REPLACE,
|
||||
if (replace) ExistingWorkPolicy.REPLACE else ExistingWorkPolicy.KEEP,
|
||||
OneTimeWorkRequestBuilder<WeatherWorker>().build()
|
||||
)
|
||||
}
|
||||
|
||||
fun enqueuePeriodic(context: Context, interval: Long, unit: TimeUnit) {
|
||||
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
|
||||
"updateWeatherPeriodically",
|
||||
ExistingPeriodicWorkPolicy.REPLACE,
|
||||
PeriodicWorkRequestBuilder<WeatherWorker>(interval, unit).build()
|
||||
fun enqueueTrigger(context: Context) {
|
||||
val interval = when (Preferences.weatherRefreshPeriod) {
|
||||
0 -> 30
|
||||
1 -> 60
|
||||
2 -> 60L * 3
|
||||
3 -> 60L * 6
|
||||
4 -> 60L * 12
|
||||
5 -> 60L * 24
|
||||
else -> 60
|
||||
}
|
||||
WorkManager.getInstance(context).enqueueUniqueWork(
|
||||
"updateWeatherTrigger",
|
||||
ExistingWorkPolicy.REPLACE,
|
||||
OneTimeWorkRequestBuilder<Trigger>().setInitialDelay(
|
||||
interval, TimeUnit.MINUTES
|
||||
).build()
|
||||
)
|
||||
}
|
||||
|
||||
fun cancelPeriodic(context: Context) {
|
||||
fun cancelTrigger(context: Context) {
|
||||
WorkManager.getInstance(context).cancelUniqueWork(
|
||||
"updateWeatherPeriodically"
|
||||
"updateWeatherTrigger"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class Trigger(context: Context, params: WorkerParameters) : Worker(context, params) {
|
||||
override fun doWork(): Result {
|
||||
if (Preferences.showWeather && !isStopped)
|
||||
enqueue(applicationContext)
|
||||
return Result.success()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ class WeatherProviderActivity : AppCompatActivity() {
|
||||
updateListItem()
|
||||
binding.loader.isVisible = true
|
||||
|
||||
WeatherHelper.updateWeather(this@WeatherProviderActivity)
|
||||
WeatherHelper.updateWeather(this@WeatherProviderActivity, true)
|
||||
}
|
||||
.clicked(R.id.radioButton) {
|
||||
if (Preferences.weatherProvider != provider.rawValue) {
|
||||
@ -70,7 +70,7 @@ class WeatherProviderActivity : AppCompatActivity() {
|
||||
updateListItem()
|
||||
binding.loader.isVisible = true
|
||||
|
||||
WeatherHelper.updateWeather(this@WeatherProviderActivity)
|
||||
WeatherHelper.updateWeather(this@WeatherProviderActivity, true)
|
||||
}
|
||||
.checked(R.id.radioButton, provider.rawValue == Preferences.weatherProvider)
|
||||
.with<TextView>(R.id.text2) {
|
||||
@ -89,7 +89,7 @@ class WeatherProviderActivity : AppCompatActivity() {
|
||||
.clicked(R.id.action_configure) {
|
||||
BottomSheetWeatherProviderSettings(this) {
|
||||
binding.loader.isVisible = true
|
||||
WeatherHelper.updateWeather(this@WeatherProviderActivity)
|
||||
WeatherHelper.updateWeather(this@WeatherProviderActivity, true)
|
||||
}.show()
|
||||
}
|
||||
.visibility(R.id.action_configure, if (/*WeatherHelper.isKeyRequired(provider) && */provider.rawValue == Preferences.weatherProvider) View.VISIBLE else View.GONE)
|
||||
|
@ -23,6 +23,7 @@ import com.tommasoberlose.anotherwidget.components.MaterialBottomSheetDialog
|
||||
import com.tommasoberlose.anotherwidget.databinding.FragmentPreferencesBinding
|
||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper
|
||||
import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
|
||||
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
|
||||
import com.tommasoberlose.anotherwidget.receivers.WeatherReceiver
|
||||
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
|
||||
@ -137,7 +138,7 @@ class PreferencesFragment : Fragment() {
|
||||
if (enabled) {
|
||||
Preferences.weatherProviderError = ""
|
||||
Preferences.weatherProviderLocationError = ""
|
||||
WeatherReceiver.setUpdates(requireContext())
|
||||
WeatherHelper.updateWeather(requireContext())
|
||||
} else {
|
||||
WeatherReceiver.removeUpdates(requireContext())
|
||||
}
|
||||
|
@ -156,7 +156,6 @@ class MainViewModel(context: Application) : AndroidViewModel(context) {
|
||||
|
||||
addSource(Preferences.asLiveData(Preferences::showWeather)) { value = true }
|
||||
addSource(Preferences.asLiveData(Preferences::weatherProvider)) { value = true }
|
||||
addSource(Preferences.asLiveData(Preferences::weatherTempUnit)) { value = true }
|
||||
addSource(Preferences.asLiveData(Preferences::weatherIconPack)) { value = true }
|
||||
addSource(Preferences.asLiveData(Preferences::customLocationLat)) { value = true }
|
||||
addSource(Preferences.asLiveData(Preferences::customLocationLon)) { value = true }
|
||||
|
@ -32,7 +32,7 @@ class MainWidget : AppWidgetProvider() {
|
||||
|
||||
override fun onEnabled(context: Context) {
|
||||
CalendarHelper.updateEventList(context)
|
||||
WeatherReceiver.setUpdates(context)
|
||||
WeatherHelper.updateWeather(context)
|
||||
MediaPlayerHelper.updatePlayingMediaInfo(context)
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user