Meet some mandatory requirements for migrating to Android 12
1. Replace foreground services with Workers 2. Support approximate location 3. Fallback to inexact alarms if the SCHEDULE_EXACT_ALARM permission is revoked 4. Specify the mutability of each PendingIntent 5. Explicitly declare the android:exported attribute for app components that use intent filters
This commit is contained in:
parent
5763a18421
commit
388653f62b
@ -6,14 +6,15 @@
|
|||||||
<uses-permission android:name="android.permission.READ_CALENDAR" />
|
<uses-permission android:name="android.permission.READ_CALENDAR" />
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||||
<uses-permission android:name="com.android.vending.BILLING" />
|
<uses-permission android:name="com.android.vending.BILLING" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
|
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
|
||||||
<uses-permission android:name="android.gms.permission.ACTIVITY_RECOGNITION"/>
|
<uses-permission android:name="android.gms.permission.ACTIVITY_RECOGNITION"/>
|
||||||
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
|
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
|
||||||
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
|
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
|
||||||
|
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
@ -25,7 +26,7 @@
|
|||||||
android:usesCleartextTraffic="true"
|
android:usesCleartextTraffic="true"
|
||||||
android:theme="@style/AppTheme"
|
android:theme="@style/AppTheme"
|
||||||
tools:ignore="LockedOrientationActivity">
|
tools:ignore="LockedOrientationActivity">
|
||||||
<activity android:name=".ui.activities.SplashActivity" android:theme="@style/AppTheme.Main" android:screenOrientation="portrait">
|
<activity android:name=".ui.activities.SplashActivity" android:exported="true" android:theme="@style/AppTheme.Main" android:screenOrientation="portrait">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
@ -44,11 +45,10 @@
|
|||||||
<activity android:name=".ui.activities.tabs.MediaInfoFormatActivity" android:screenOrientation="portrait" />
|
<activity android:name=".ui.activities.tabs.MediaInfoFormatActivity" android:screenOrientation="portrait" />
|
||||||
<activity android:name=".ui.activities.tabs.TimeZoneSelectorActivity" android:screenOrientation="portrait" />
|
<activity android:name=".ui.activities.tabs.TimeZoneSelectorActivity" android:screenOrientation="portrait" />
|
||||||
|
|
||||||
<receiver android:name=".ui.widgets.MainWidget">
|
<receiver android:name=".ui.widgets.MainWidget" android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="android.appwidget.provider"
|
android:name="android.appwidget.provider"
|
||||||
android:resource="@xml/the_widget_info" />
|
android:resource="@xml/the_widget_info" />
|
||||||
@ -112,7 +112,7 @@
|
|||||||
|
|
||||||
<service android:name=".services.BatteryListenerJob" android:permission="android.permission.BIND_JOB_SERVICE" />
|
<service android:name=".services.BatteryListenerJob" android:permission="android.permission.BIND_JOB_SERVICE" />
|
||||||
|
|
||||||
<service android:name=".receivers.NotificationListener"
|
<service android:name=".receivers.NotificationListener" android:exported="true"
|
||||||
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
|
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.service.notification.NotificationListenerService" />
|
<action android:name="android.service.notification.NotificationListenerService" />
|
||||||
@ -140,17 +140,6 @@
|
|||||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<service
|
|
||||||
android:name=".services.UpdateCalendarService"
|
|
||||||
android:enabled="true"
|
|
||||||
android:exported="true"
|
|
||||||
android:foregroundServiceType="dataSync" />
|
|
||||||
<service
|
|
||||||
android:name=".services.LocationService"
|
|
||||||
android:enabled="true"
|
|
||||||
android:exported="true"
|
|
||||||
android:foregroundServiceType="location" />
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
<queries>
|
<queries>
|
||||||
|
@ -9,6 +9,7 @@ import android.util.Log
|
|||||||
import com.tommasoberlose.anotherwidget.global.Actions
|
import com.tommasoberlose.anotherwidget.global.Actions
|
||||||
import com.tommasoberlose.anotherwidget.receivers.ActivityDetectionReceiver
|
import com.tommasoberlose.anotherwidget.receivers.ActivityDetectionReceiver
|
||||||
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
|
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.setExactIfCanSchedule
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@ -44,14 +45,14 @@ object AlarmHelper {
|
|||||||
val intent = Intent(context, UpdatesReceiver::class.java).apply {
|
val intent = Intent(context, UpdatesReceiver::class.java).apply {
|
||||||
action = Actions.ACTION_ALARM_UPDATE
|
action = Actions.ACTION_ALARM_UPDATE
|
||||||
}
|
}
|
||||||
setExact(
|
setExactIfCanSchedule(
|
||||||
AlarmManager.RTC,
|
AlarmManager.RTC,
|
||||||
trigger,
|
trigger,
|
||||||
PendingIntent.getBroadcast(
|
PendingIntent.getBroadcast(
|
||||||
context,
|
context,
|
||||||
ALARM_UPDATE_ID,
|
ALARM_UPDATE_ID,
|
||||||
intent,
|
intent,
|
||||||
0
|
PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -62,7 +63,7 @@ object AlarmHelper {
|
|||||||
val intent = Intent(context, UpdatesReceiver::class.java).apply {
|
val intent = Intent(context, UpdatesReceiver::class.java).apply {
|
||||||
action = Actions.ACTION_ALARM_UPDATE
|
action = Actions.ACTION_ALARM_UPDATE
|
||||||
}
|
}
|
||||||
cancel(PendingIntent.getBroadcast(context, ALARM_UPDATE_ID, intent, 0))
|
cancel(PendingIntent.getBroadcast(context, ALARM_UPDATE_ID, intent, PendingIntent.FLAG_IMMUTABLE))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import android.provider.CalendarContract
|
|||||||
import com.tommasoberlose.anotherwidget.services.EventListenerJob
|
import com.tommasoberlose.anotherwidget.services.EventListenerJob
|
||||||
import com.tommasoberlose.anotherwidget.models.Event
|
import com.tommasoberlose.anotherwidget.models.Event
|
||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.services.UpdateCalendarService
|
import com.tommasoberlose.anotherwidget.services.UpdateCalendarWorker
|
||||||
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
||||||
import me.everything.providers.android.calendar.CalendarProvider
|
import me.everything.providers.android.calendar.CalendarProvider
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@ -19,7 +19,7 @@ import kotlin.collections.ArrayList
|
|||||||
|
|
||||||
object CalendarHelper {
|
object CalendarHelper {
|
||||||
fun updateEventList(context: Context) {
|
fun updateEventList(context: Context) {
|
||||||
UpdateCalendarService.enqueueWork(context)
|
UpdateCalendarWorker.enqueue(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCalendarList(context: Context): List<me.everything.providers.android.calendar.Calendar> {
|
fun getCalendarList(context: Context): List<me.everything.providers.android.calendar.Calendar> {
|
||||||
|
@ -37,7 +37,7 @@ object GreetingsHelper {
|
|||||||
Intent(context, UpdatesReceiver::class.java).apply {
|
Intent(context, UpdatesReceiver::class.java).apply {
|
||||||
action = Actions.ACTION_UPDATE_GREETINGS
|
action = Actions.ACTION_UPDATE_GREETINGS
|
||||||
},
|
},
|
||||||
0)
|
PendingIntent.FLAG_IMMUTABLE)
|
||||||
)
|
)
|
||||||
|
|
||||||
setRepeating(
|
setRepeating(
|
||||||
@ -51,7 +51,7 @@ object GreetingsHelper {
|
|||||||
Intent(context, UpdatesReceiver::class.java).apply {
|
Intent(context, UpdatesReceiver::class.java).apply {
|
||||||
action = Actions.ACTION_UPDATE_GREETINGS
|
action = Actions.ACTION_UPDATE_GREETINGS
|
||||||
},
|
},
|
||||||
0)
|
PendingIntent.FLAG_IMMUTABLE)
|
||||||
)
|
)
|
||||||
|
|
||||||
setRepeating(
|
setRepeating(
|
||||||
@ -65,7 +65,7 @@ object GreetingsHelper {
|
|||||||
Intent(context, UpdatesReceiver::class.java).apply {
|
Intent(context, UpdatesReceiver::class.java).apply {
|
||||||
action = Actions.ACTION_UPDATE_GREETINGS
|
action = Actions.ACTION_UPDATE_GREETINGS
|
||||||
},
|
},
|
||||||
0)
|
PendingIntent.FLAG_IMMUTABLE)
|
||||||
)
|
)
|
||||||
|
|
||||||
setRepeating(
|
setRepeating(
|
||||||
@ -79,14 +79,14 @@ object GreetingsHelper {
|
|||||||
Intent(context, UpdatesReceiver::class.java).apply {
|
Intent(context, UpdatesReceiver::class.java).apply {
|
||||||
action = Actions.ACTION_UPDATE_GREETINGS
|
action = Actions.ACTION_UPDATE_GREETINGS
|
||||||
},
|
},
|
||||||
0)
|
PendingIntent.FLAG_IMMUTABLE)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
listOf(MORNING_TIME, MORNING_TIME_END, EVENING_TIME, NIGHT_TIME).forEach {
|
listOf(MORNING_TIME, MORNING_TIME_END, EVENING_TIME, NIGHT_TIME).forEach {
|
||||||
cancel(PendingIntent.getBroadcast(context, it, Intent(context,
|
cancel(PendingIntent.getBroadcast(context, it, Intent(context,
|
||||||
UpdatesReceiver::class.java).apply {
|
UpdatesReceiver::class.java).apply {
|
||||||
action = Actions.ACTION_UPDATE_GREETINGS
|
action = Actions.ACTION_UPDATE_GREETINGS
|
||||||
}, 0))
|
}, PendingIntent.FLAG_IMMUTABLE))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ object IntentHelper {
|
|||||||
return if (intent.flags and Intent.FLAG_ACTIVITY_NEW_TASK == Intent.FLAG_ACTIVITY_NEW_TASK)
|
return if (intent.flags and Intent.FLAG_ACTIVITY_NEW_TASK == Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
PendingIntent.getActivity(context, requestCode, intent, flags)
|
PendingIntent.getActivity(context, requestCode, intent, flags)
|
||||||
else
|
else
|
||||||
PendingIntent.getBroadcast(context, requestCode, intent, 0)
|
PendingIntent.getBroadcast(context, requestCode, intent, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getWidgetUpdateIntent(context: Context): Intent {
|
fun getWidgetUpdateIntent(context: Context): Intent {
|
||||||
|
@ -7,7 +7,7 @@ import com.tommasoberlose.anotherwidget.R
|
|||||||
import com.tommasoberlose.anotherwidget.global.Constants
|
import com.tommasoberlose.anotherwidget.global.Constants
|
||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.network.WeatherNetworkApi
|
import com.tommasoberlose.anotherwidget.network.WeatherNetworkApi
|
||||||
import com.tommasoberlose.anotherwidget.services.LocationService
|
import com.tommasoberlose.anotherwidget.services.WeatherWorker
|
||||||
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||||
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
||||||
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
|
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
|
||||||
@ -19,20 +19,8 @@ import com.tommasoberlose.anotherwidget.utils.isDarkTheme
|
|||||||
|
|
||||||
object WeatherHelper {
|
object WeatherHelper {
|
||||||
|
|
||||||
suspend fun updateWeather(context: Context) {
|
fun updateWeather(context: Context) {
|
||||||
Kotpref.init(context)
|
WeatherWorker.enqueue(context)
|
||||||
if (Preferences.customLocationAdd != "") {
|
|
||||||
WeatherNetworkApi(context).updateWeather()
|
|
||||||
} else if (context.checkGrantedPermission(Manifest.permission.ACCESS_FINE_LOCATION)) {
|
|
||||||
LocationService.requestNewLocation(context)
|
|
||||||
} else {
|
|
||||||
Preferences.weatherProviderLocationError = context.getString(R.string.weather_provider_error_missing_location)
|
|
||||||
Preferences.weatherProviderError = ""
|
|
||||||
removeWeather(context)
|
|
||||||
org.greenrobot.eventbus.EventBus.getDefault().post(
|
|
||||||
com.tommasoberlose.anotherwidget.ui.fragments.MainFragment.UpdateUiMessageEvent()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeWeather(context: Context) {
|
fun removeWeather(context: Context) {
|
||||||
|
@ -21,6 +21,7 @@ import com.google.android.gms.location.*
|
|||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||||
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.setExactIfCanSchedule
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
@ -79,7 +80,7 @@ class ActivityDetectionReceiver : BroadcastReceiver() {
|
|||||||
context,
|
context,
|
||||||
2,
|
2,
|
||||||
Intent(context, ActivityDetectionReceiver::class.java),
|
Intent(context, ActivityDetectionReceiver::class.java),
|
||||||
0
|
PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -98,7 +99,7 @@ class ActivityDetectionReceiver : BroadcastReceiver() {
|
|||||||
context,
|
context,
|
||||||
2,
|
2,
|
||||||
Intent(context, ActivityDetectionReceiver::class.java),
|
Intent(context, ActivityDetectionReceiver::class.java),
|
||||||
0
|
PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -108,7 +109,7 @@ class ActivityDetectionReceiver : BroadcastReceiver() {
|
|||||||
context,
|
context,
|
||||||
2,
|
2,
|
||||||
Intent(context, ActivityDetectionReceiver::class.java),
|
Intent(context, ActivityDetectionReceiver::class.java),
|
||||||
0
|
PendingIntent.FLAG_IMMUTABLE
|
||||||
).cancel()
|
).cancel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,14 +168,14 @@ class ActivityDetectionReceiver : BroadcastReceiver() {
|
|||||||
|
|
||||||
private fun setTimeout(context: Context) {
|
private fun setTimeout(context: Context) {
|
||||||
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
|
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
|
||||||
setExact(
|
setExactIfCanSchedule(
|
||||||
AlarmManager.RTC,
|
AlarmManager.RTC,
|
||||||
Calendar.getInstance().timeInMillis + 5 * 60 * 1000,
|
Calendar.getInstance().timeInMillis + 5 * 60 * 1000,
|
||||||
PendingIntent.getBroadcast(
|
PendingIntent.getBroadcast(
|
||||||
context,
|
context,
|
||||||
5,
|
5,
|
||||||
Intent(context, ActivityDetectionReceiver::class.java),
|
Intent(context, ActivityDetectionReceiver::class.java),
|
||||||
0
|
PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -187,7 +188,7 @@ class ActivityDetectionReceiver : BroadcastReceiver() {
|
|||||||
context,
|
context,
|
||||||
5,
|
5,
|
||||||
Intent(context, ActivityDetectionReceiver::class.java),
|
Intent(context, ActivityDetectionReceiver::class.java),
|
||||||
0
|
PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import com.tommasoberlose.anotherwidget.global.Preferences
|
|||||||
import com.tommasoberlose.anotherwidget.helpers.ActiveNotificationsHelper
|
import com.tommasoberlose.anotherwidget.helpers.ActiveNotificationsHelper
|
||||||
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
|
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
|
||||||
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.setExactIfCanSchedule
|
||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@ -83,7 +84,7 @@ class NotificationListener : NotificationListenerService() {
|
|||||||
}
|
}
|
||||||
val timeoutPref = Constants.GlanceNotificationTimer.fromInt(Preferences.hideNotificationAfter)
|
val timeoutPref = Constants.GlanceNotificationTimer.fromInt(Preferences.hideNotificationAfter)
|
||||||
if (timeoutPref != Constants.GlanceNotificationTimer.WHEN_DISMISSED) {
|
if (timeoutPref != Constants.GlanceNotificationTimer.WHEN_DISMISSED) {
|
||||||
setExact(
|
setExactIfCanSchedule(
|
||||||
AlarmManager.RTC,
|
AlarmManager.RTC,
|
||||||
Calendar.getInstance().timeInMillis + when (timeoutPref) {
|
Calendar.getInstance().timeInMillis + when (timeoutPref) {
|
||||||
Constants.GlanceNotificationTimer.HALF_MINUTE -> 30 * 1000
|
Constants.GlanceNotificationTimer.HALF_MINUTE -> 30 * 1000
|
||||||
@ -97,7 +98,7 @@ class NotificationListener : NotificationListenerService() {
|
|||||||
context,
|
context,
|
||||||
5,
|
5,
|
||||||
intent,
|
intent,
|
||||||
0
|
PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -110,7 +111,7 @@ class NotificationListener : NotificationListenerService() {
|
|||||||
val intent = Intent(context, UpdatesReceiver::class.java).apply {
|
val intent = Intent(context, UpdatesReceiver::class.java).apply {
|
||||||
action = Actions.ACTION_CLEAR_NOTIFICATION
|
action = Actions.ACTION_CLEAR_NOTIFICATION
|
||||||
}
|
}
|
||||||
cancel(PendingIntent.getBroadcast(context, 5, intent, 0))
|
cancel(PendingIntent.getBroadcast(context, 5, intent, PendingIntent.FLAG_IMMUTABLE))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import com.tommasoberlose.anotherwidget.global.Preferences
|
|||||||
import com.tommasoberlose.anotherwidget.helpers.*
|
import com.tommasoberlose.anotherwidget.helpers.*
|
||||||
import com.tommasoberlose.anotherwidget.models.Event
|
import com.tommasoberlose.anotherwidget.models.Event
|
||||||
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.setExactIfCanSchedule
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -55,11 +56,9 @@ class UpdatesReceiver : BroadcastReceiver() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Actions.ACTION_REFRESH -> {
|
Actions.ACTION_REFRESH -> {
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
CalendarHelper.updateEventList(context)
|
||||||
CalendarHelper.updateEventList(context)
|
MediaPlayerHelper.updatePlayingMediaInfo(context)
|
||||||
MediaPlayerHelper.updatePlayingMediaInfo(context)
|
WeatherHelper.updateWeather(context)
|
||||||
WeatherHelper.updateWeather(context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -74,7 +73,7 @@ class UpdatesReceiver : BroadcastReceiver() {
|
|||||||
if (eventId == null) {
|
if (eventId == null) {
|
||||||
// schedule ACTION_CALENDAR_UPDATE at midnight (ACTION_DATE_CHANGED no longer works)
|
// schedule ACTION_CALENDAR_UPDATE at midnight (ACTION_DATE_CHANGED no longer works)
|
||||||
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
|
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
|
||||||
setExact(
|
setExactIfCanSchedule(
|
||||||
AlarmManager.RTC,
|
AlarmManager.RTC,
|
||||||
Calendar.getInstance().apply {
|
Calendar.getInstance().apply {
|
||||||
set(Calendar.MILLISECOND, 0)
|
set(Calendar.MILLISECOND, 0)
|
||||||
@ -89,7 +88,7 @@ class UpdatesReceiver : BroadcastReceiver() {
|
|||||||
Intent(context, UpdatesReceiver::class.java).apply {
|
Intent(context, UpdatesReceiver::class.java).apply {
|
||||||
action = Actions.ACTION_CALENDAR_UPDATE
|
action = Actions.ACTION_CALENDAR_UPDATE
|
||||||
},
|
},
|
||||||
0
|
PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -164,7 +163,7 @@ class UpdatesReceiver : BroadcastReceiver() {
|
|||||||
add(Calendar.DATE, 1)
|
add(Calendar.DATE, 1)
|
||||||
}.timeInMillis <= fireTime) return
|
}.timeInMillis <= fireTime) return
|
||||||
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
|
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
|
||||||
setExact(
|
setExactIfCanSchedule(
|
||||||
AlarmManager.RTC,
|
AlarmManager.RTC,
|
||||||
fireTime.coerceAtLeast(now.timeInMillis + 1000 * 60),
|
fireTime.coerceAtLeast(now.timeInMillis + 1000 * 60),
|
||||||
PendingIntent.getBroadcast(
|
PendingIntent.getBroadcast(
|
||||||
@ -175,7 +174,7 @@ class UpdatesReceiver : BroadcastReceiver() {
|
|||||||
if (event.startDate > now.timeInMillis)
|
if (event.startDate > now.timeInMillis)
|
||||||
putExtra(EVENT_ID, event.id)
|
putExtra(EVENT_ID, event.id)
|
||||||
},
|
},
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -185,12 +184,12 @@ class UpdatesReceiver : BroadcastReceiver() {
|
|||||||
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
|
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
|
||||||
cancel(PendingIntent.getBroadcast(context, 0, Intent(context, UpdatesReceiver::class.java).apply {
|
cancel(PendingIntent.getBroadcast(context, 0, Intent(context, UpdatesReceiver::class.java).apply {
|
||||||
action = Actions.ACTION_CALENDAR_UPDATE
|
action = Actions.ACTION_CALENDAR_UPDATE
|
||||||
}, 0))
|
}, PendingIntent.FLAG_IMMUTABLE))
|
||||||
val eventRepository = EventRepository(context)
|
val eventRepository = EventRepository(context)
|
||||||
eventRepository.getFutureEvents().forEach {
|
eventRepository.getFutureEvents().forEach {
|
||||||
cancel(PendingIntent.getBroadcast(context, it.id.toInt(), Intent(context, UpdatesReceiver::class.java).apply {
|
cancel(PendingIntent.getBroadcast(context, it.id.toInt(), Intent(context, UpdatesReceiver::class.java).apply {
|
||||||
action = Actions.ACTION_TIME_UPDATE
|
action = Actions.ACTION_TIME_UPDATE
|
||||||
}, 0))
|
}, PendingIntent.FLAG_IMMUTABLE))
|
||||||
}
|
}
|
||||||
eventRepository.close()
|
eventRepository.close()
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,11 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import com.tommasoberlose.anotherwidget.global.Actions
|
import com.tommasoberlose.anotherwidget.global.Actions
|
||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
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.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.util.*
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
|
||||||
class WeatherReceiver : BroadcastReceiver() {
|
class WeatherReceiver : BroadcastReceiver() {
|
||||||
@ -22,16 +22,18 @@ class WeatherReceiver : BroadcastReceiver() {
|
|||||||
Intent.ACTION_MY_PACKAGE_REPLACED,
|
Intent.ACTION_MY_PACKAGE_REPLACED,
|
||||||
Intent.ACTION_TIMEZONE_CHANGED,
|
Intent.ACTION_TIMEZONE_CHANGED,
|
||||||
Intent.ACTION_LOCALE_CHANGED,
|
Intent.ACTION_LOCALE_CHANGED,
|
||||||
Intent.ACTION_TIME_CHANGED,
|
Intent.ACTION_TIME_CHANGED -> setUpdates(context)
|
||||||
Actions.ACTION_WEATHER_UPDATE -> setUpdates(context)
|
|
||||||
|
Actions.ACTION_WEATHER_UPDATE -> {
|
||||||
|
WeatherWorker.enqueue(context)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val MINUTE = 60 * 1000L
|
|
||||||
fun setUpdates(context: Context) {
|
fun setUpdates(context: Context) {
|
||||||
if (Preferences.showWeather) {
|
if (Preferences.showWeather) {
|
||||||
val interval = MINUTE * when (Preferences.weatherRefreshPeriod) {
|
val interval = when (Preferences.weatherRefreshPeriod) {
|
||||||
0 -> 30
|
0 -> 30
|
||||||
1 -> 60
|
1 -> 60
|
||||||
2 -> 60L * 3
|
2 -> 60L * 3
|
||||||
@ -40,40 +42,12 @@ class WeatherReceiver : BroadcastReceiver() {
|
|||||||
5 -> 60L * 24
|
5 -> 60L * 24
|
||||||
else -> 60
|
else -> 60
|
||||||
}
|
}
|
||||||
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
|
WeatherWorker.enqueue(context, interval, TimeUnit.MINUTES)
|
||||||
setExact(
|
|
||||||
AlarmManager.RTC,
|
|
||||||
System.currentTimeMillis() + interval,
|
|
||||||
PendingIntent.getBroadcast(context, 0, Intent(context, WeatherReceiver::class.java).apply { action = Actions.ACTION_WEATHER_UPDATE }, 0)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
|
||||||
WeatherHelper.updateWeather(context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setOneTimeUpdate(context: Context) {
|
|
||||||
if (Preferences.showWeather) {
|
|
||||||
listOf(10, 20, 30).forEach {
|
|
||||||
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
|
|
||||||
setExactAndAllowWhileIdle(
|
|
||||||
AlarmManager.RTC,
|
|
||||||
it * MINUTE,
|
|
||||||
PendingIntent.getBroadcast(context, it, Intent(context, WeatherReceiver::class.java).apply { action = Actions.ACTION_WEATHER_UPDATE }, 0)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeUpdates(context: Context) {
|
fun removeUpdates(context: Context) {
|
||||||
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
|
WeatherWorker.cancel(context)
|
||||||
cancel(PendingIntent.getBroadcast(context, 0, Intent(context, WeatherReceiver::class.java).apply { action = Actions.ACTION_WEATHER_UPDATE }, 0))
|
|
||||||
listOf(10, 20, 30).forEach {
|
|
||||||
cancel(PendingIntent.getBroadcast(context, it, Intent(context, WeatherReceiver::class.java).apply { action = Actions.ACTION_WEATHER_UPDATE }, 0))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,144 +0,0 @@
|
|||||||
package com.tommasoberlose.anotherwidget.services
|
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import android.app.*
|
|
||||||
import android.app.job.JobScheduler
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.pm.PackageManager
|
|
||||||
import android.location.Address
|
|
||||||
import android.location.Geocoder
|
|
||||||
import android.os.IBinder
|
|
||||||
import android.util.Log
|
|
||||||
import androidx.core.app.*
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import com.google.android.gms.location.LocationServices
|
|
||||||
import com.tommasoberlose.anotherwidget.R
|
|
||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
|
||||||
import com.tommasoberlose.anotherwidget.network.WeatherNetworkApi
|
|
||||||
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
|
|
||||||
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
|
|
||||||
import kotlinx.coroutines.*
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
|
||||||
import java.lang.Exception
|
|
||||||
import java.util.*
|
|
||||||
import kotlin.collections.ArrayList
|
|
||||||
|
|
||||||
class LocationService : Service() {
|
|
||||||
|
|
||||||
private var job: Job? = null
|
|
||||||
|
|
||||||
override fun onCreate() {
|
|
||||||
super.onCreate()
|
|
||||||
startForeground(LOCATION_ACCESS_NOTIFICATION_ID, getLocationAccessNotification())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
|
||||||
startForeground(LOCATION_ACCESS_NOTIFICATION_ID, getLocationAccessNotification())
|
|
||||||
job?.cancel()
|
|
||||||
job = GlobalScope.launch(Dispatchers.IO) {
|
|
||||||
if (ActivityCompat.checkSelfPermission(
|
|
||||||
this@LocationService,
|
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION
|
|
||||||
) == PackageManager.PERMISSION_GRANTED
|
|
||||||
) {
|
|
||||||
if (com.google.android.gms.common.GoogleApiAvailability.getInstance()
|
|
||||||
.isGooglePlayServicesAvailable(this@LocationService)
|
|
||||||
== com.google.android.gms.common.ConnectionResult.SUCCESS
|
|
||||||
) {
|
|
||||||
LocationServices.getFusedLocationProviderClient(this@LocationService).lastLocation
|
|
||||||
} else {
|
|
||||||
val lm = getSystemService(LOCATION_SERVICE) as android.location.LocationManager
|
|
||||||
var location: android.location.Location? = null
|
|
||||||
for (provider in arrayOf(
|
|
||||||
"fused", // LocationManager.FUSED_PROVIDER,
|
|
||||||
android.location.LocationManager.GPS_PROVIDER,
|
|
||||||
android.location.LocationManager.NETWORK_PROVIDER,
|
|
||||||
android.location.LocationManager.PASSIVE_PROVIDER
|
|
||||||
)) {
|
|
||||||
if (lm.isProviderEnabled(provider)) {
|
|
||||||
location = lm.getLastKnownLocation(provider)
|
|
||||||
if (location != null) break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
com.google.android.gms.tasks.Tasks.forResult(location)
|
|
||||||
}.addOnCompleteListener { task ->
|
|
||||||
val networkApi = WeatherNetworkApi(this@LocationService)
|
|
||||||
if (task.isSuccessful) {
|
|
||||||
val location = task.result
|
|
||||||
if (location != null) {
|
|
||||||
Preferences.customLocationLat = location.latitude.toString()
|
|
||||||
Preferences.customLocationLon = location.longitude.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
|
||||||
networkApi.updateWeather()
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
stopSelf()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
|
||||||
} else {
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
|
||||||
networkApi.updateWeather()
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
stopSelf()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
stopSelf()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return START_STICKY
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
super.onDestroy()
|
|
||||||
job?.cancel()
|
|
||||||
job = null
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val LOCATION_ACCESS_NOTIFICATION_ID = 28465
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun requestNewLocation(context: Context) {
|
|
||||||
ContextCompat.startForegroundService(context, Intent(context, LocationService::class.java))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBind(intent: Intent?): IBinder? {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getLocationAccessNotification(): Notification {
|
|
||||||
with(NotificationManagerCompat.from(this)) {
|
|
||||||
// Create channel
|
|
||||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
|
||||||
createNotificationChannel(
|
|
||||||
NotificationChannel(
|
|
||||||
getString(R.string.location_access_notification_channel_id),
|
|
||||||
getString(R.string.location_access_notification_channel_name),
|
|
||||||
NotificationManager.IMPORTANCE_LOW
|
|
||||||
).apply {
|
|
||||||
description = getString(R.string.location_access_notification_channel_description)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val builder = NotificationCompat.Builder(this@LocationService, getString(R.string.location_access_notification_channel_id))
|
|
||||||
.setSmallIcon(R.drawable.ic_stat_notification)
|
|
||||||
.setContentTitle(getString(R.string.location_access_notification_title))
|
|
||||||
.setOngoing(true)
|
|
||||||
.setColor(ContextCompat.getColor(this@LocationService, R.color.colorAccent))
|
|
||||||
|
|
||||||
// Main intent that open the activity
|
|
||||||
builder.setContentIntent(PendingIntent.getActivity(this@LocationService, 0, Intent(this@LocationService, MainActivity::class.java), PendingIntent.FLAG_UPDATE_CURRENT))
|
|
||||||
|
|
||||||
return builder.build()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +1,12 @@
|
|||||||
package com.tommasoberlose.anotherwidget.services
|
package com.tommasoberlose.anotherwidget.services
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.app.*
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import androidx.work.CoroutineWorker
|
||||||
import android.os.IBinder
|
import androidx.work.ExistingWorkPolicy
|
||||||
import android.util.Log
|
import androidx.work.OneTimeWorkRequestBuilder
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.work.WorkManager
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.work.WorkerParameters
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import com.tommasoberlose.anotherwidget.R
|
|
||||||
import com.tommasoberlose.anotherwidget.db.EventRepository
|
import com.tommasoberlose.anotherwidget.db.EventRepository
|
||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper
|
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper
|
||||||
@ -17,81 +14,54 @@ import com.tommasoberlose.anotherwidget.helpers.CalendarHelper.applyFilters
|
|||||||
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper.sortEvents
|
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper.sortEvents
|
||||||
import com.tommasoberlose.anotherwidget.models.Event
|
import com.tommasoberlose.anotherwidget.models.Event
|
||||||
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
|
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
|
||||||
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
|
|
||||||
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
|
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
|
||||||
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||||
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import me.everything.providers.android.calendar.CalendarProvider
|
import me.everything.providers.android.calendar.CalendarProvider
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
class UpdateCalendarService : Service() {
|
class UpdateCalendarWorker(private val context: Context, params: WorkerParameters) :
|
||||||
|
CoroutineWorker(context, params) {
|
||||||
|
|
||||||
companion object {
|
override suspend fun doWork(): Result {
|
||||||
const val CALENDAR_SYNC_NOTIFICATION_ID = 28468
|
withContext(Dispatchers.IO) {
|
||||||
fun enqueueWork(context: Context) {
|
UpdatesReceiver.removeUpdates(context)
|
||||||
ContextCompat.startForegroundService(context, Intent(context, UpdateCalendarService::class.java))
|
val eventRepository = EventRepository(context)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreate() {
|
|
||||||
super.onCreate()
|
|
||||||
startForeground(CALENDAR_SYNC_NOTIFICATION_ID, getCalendarSyncNotification())
|
|
||||||
}
|
|
||||||
|
|
||||||
private var job: Job? = null
|
|
||||||
|
|
||||||
override fun onBind(intent: Intent?): IBinder? {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
|
||||||
startForeground(CALENDAR_SYNC_NOTIFICATION_ID, getCalendarSyncNotification())
|
|
||||||
job?.cancel()
|
|
||||||
job = GlobalScope.launch(Dispatchers.IO) {
|
|
||||||
|
|
||||||
UpdatesReceiver.removeUpdates(this@UpdateCalendarService)
|
|
||||||
|
|
||||||
val eventRepository = EventRepository(this@UpdateCalendarService)
|
|
||||||
if (Preferences.showEvents) {
|
if (Preferences.showEvents) {
|
||||||
val eventList = ArrayList<Event>()
|
if (!context.checkGrantedPermission(Manifest.permission.READ_CALENDAR)) {
|
||||||
|
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!checkGrantedPermission(
|
|
||||||
Manifest.permission.READ_CALENDAR
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
eventRepository.resetNextEventData()
|
eventRepository.resetNextEventData()
|
||||||
eventRepository.clearEvents()
|
eventRepository.clearEvents()
|
||||||
Preferences.showEvents = false
|
Preferences.showEvents = false
|
||||||
} else {
|
} 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 {
|
try {
|
||||||
val provider = CalendarProvider(this@UpdateCalendarService)
|
val eventList = ArrayList<Event>()
|
||||||
|
val provider = CalendarProvider(context)
|
||||||
// apply time zone offset to correctly fetch all-day events
|
// apply time zone offset to correctly fetch all-day events
|
||||||
val data = provider.getInstances(
|
val data = provider.getInstances(
|
||||||
now.timeInMillis + now.timeZone.getOffset(now.timeInMillis).coerceAtMost(0),
|
now.timeInMillis + now.timeZone.getOffset(now.timeInMillis).coerceAtMost(0),
|
||||||
@ -157,20 +127,16 @@ class UpdateCalendarService : Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val sortedEvents = eventList.sortEvents()
|
val sortedEvents = eventList.sortEvents()
|
||||||
val filteredEventList = sortedEvents
|
val filteredEventList = sortedEvents.applyFilters()
|
||||||
.applyFilters()
|
|
||||||
|
|
||||||
if (filteredEventList.isEmpty()) {
|
if (filteredEventList.isEmpty()) {
|
||||||
eventRepository.resetNextEventData()
|
eventRepository.resetNextEventData()
|
||||||
eventRepository.clearEvents()
|
eventRepository.clearEvents()
|
||||||
} else {
|
} else {
|
||||||
eventRepository.saveEvents(
|
eventRepository.saveEvents(sortedEvents)
|
||||||
sortedEvents
|
//eventRepository.saveNextEventData(filteredEventList.first())
|
||||||
)
|
|
||||||
eventRepository.saveNextEventData(filteredEventList.first())
|
|
||||||
}
|
}
|
||||||
} catch (ignored: java.lang.Exception) {
|
} catch (ignored: java.lang.Exception) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -179,48 +145,22 @@ class UpdateCalendarService : Service() {
|
|||||||
}
|
}
|
||||||
eventRepository.close()
|
eventRepository.close()
|
||||||
|
|
||||||
UpdatesReceiver.setUpdates(this@UpdateCalendarService)
|
UpdatesReceiver.setUpdates(context)
|
||||||
MainWidget.updateWidget(this@UpdateCalendarService)
|
MainWidget.updateWidget(context)
|
||||||
|
|
||||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||||
|
|
||||||
stopSelf()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return START_STICKY
|
return Result.success()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
companion object {
|
||||||
super.onDestroy()
|
fun enqueue(context: Context) {
|
||||||
job?.cancel()
|
WorkManager.getInstance(context.applicationContext).enqueueUniqueWork(
|
||||||
job = null
|
"UpdateCalendarWorker",
|
||||||
}
|
ExistingWorkPolicy.REPLACE,
|
||||||
|
OneTimeWorkRequestBuilder<UpdateCalendarWorker>().build()
|
||||||
private fun getCalendarSyncNotification(): Notification {
|
)
|
||||||
with(NotificationManagerCompat.from(this)) {
|
|
||||||
// Create channel
|
|
||||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
|
||||||
createNotificationChannel(
|
|
||||||
NotificationChannel(
|
|
||||||
getString(R.string.calendar_sync_notification_channel_id),
|
|
||||||
getString(R.string.calendar_sync_notification_channel_name),
|
|
||||||
NotificationManager.IMPORTANCE_LOW
|
|
||||||
).apply {
|
|
||||||
description = getString(R.string.calendar_sync_notification_channel_description)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val builder = NotificationCompat.Builder(this@UpdateCalendarService, getString(R.string.calendar_sync_notification_channel_id))
|
|
||||||
.setSmallIcon(R.drawable.ic_stat_notification)
|
|
||||||
.setContentTitle(getString(R.string.calendar_sync_notification_title))
|
|
||||||
.setOngoing(true)
|
|
||||||
.setColor(ContextCompat.getColor(this@UpdateCalendarService, R.color.colorAccent))
|
|
||||||
|
|
||||||
// Main intent that open the activity
|
|
||||||
builder.setContentIntent(PendingIntent.getActivity(this@UpdateCalendarService, 0, Intent(this@UpdateCalendarService, MainActivity::class.java), PendingIntent.FLAG_UPDATE_CURRENT))
|
|
||||||
|
|
||||||
return builder.build()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,107 @@
|
|||||||
|
package com.tommasoberlose.anotherwidget.services
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
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.WorkerParameters
|
||||||
|
import com.google.android.gms.common.ConnectionResult
|
||||||
|
import com.google.android.gms.common.GoogleApiAvailability
|
||||||
|
import com.google.android.gms.location.LocationServices
|
||||||
|
import com.google.android.gms.tasks.Tasks
|
||||||
|
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 kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
class WeatherWorker(private val 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
|
||||||
|
) {
|
||||||
|
LocationServices.getFusedLocationProviderClient(context).lastLocation
|
||||||
|
} 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Tasks.forResult(location)
|
||||||
|
}.addOnCompleteListener { task ->
|
||||||
|
val networkApi = WeatherNetworkApi(context)
|
||||||
|
if (task.isSuccessful) {
|
||||||
|
val location = task.result
|
||||||
|
if (location != null) {
|
||||||
|
Preferences.customLocationLat = location.latitude.toString()
|
||||||
|
Preferences.customLocationLon = location.longitude.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
networkApi.updateWeather()
|
||||||
|
}
|
||||||
|
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
Preferences.weatherProviderLocationError = context.getString(R.string.weather_provider_error_missing_location)
|
||||||
|
Preferences.weatherProviderError = ""
|
||||||
|
WeatherHelper.removeWeather(context)
|
||||||
|
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result.success()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun enqueue(context: Context) {
|
||||||
|
WorkManager.getInstance(context.applicationContext).enqueueUniqueWork(
|
||||||
|
"OneTimeWeatherWorker",
|
||||||
|
ExistingWorkPolicy.REPLACE,
|
||||||
|
OneTimeWorkRequestBuilder<WeatherWorker>().build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun enqueue(context: Context, interval: Long, unit: TimeUnit) {
|
||||||
|
WorkManager.getInstance(context.applicationContext).enqueueUniquePeriodicWork(
|
||||||
|
"WeatherWorker",
|
||||||
|
ExistingPeriodicWorkPolicy.REPLACE,
|
||||||
|
PeriodicWorkRequestBuilder<WeatherWorker>(interval, unit).build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun cancel(context: Context) {
|
||||||
|
WorkManager.getInstance(context.applicationContext).cancelUniqueWork(
|
||||||
|
"WeatherWorker"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -169,6 +169,7 @@ class CustomDateActivity : AppCompatActivity() {
|
|||||||
isDateCapitalize = viewModel.isDateCapitalize.value ?: true
|
isDateCapitalize = viewModel.isDateCapitalize.value ?: true
|
||||||
isDateUppercase = viewModel.isDateUppercase.value ?: false
|
isDateUppercase = viewModel.isDateUppercase.value ?: false
|
||||||
}
|
}
|
||||||
|
com.tommasoberlose.anotherwidget.ui.widgets.MainWidget.updateWidget(this)
|
||||||
super.onBackPressed()
|
super.onBackPressed()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,9 +57,7 @@ class WeatherProviderActivity : AppCompatActivity() {
|
|||||||
updateListItem()
|
updateListItem()
|
||||||
binding.loader.isVisible = true
|
binding.loader.isVisible = true
|
||||||
|
|
||||||
lifecycleScope.launch {
|
WeatherHelper.updateWeather(this@WeatherProviderActivity)
|
||||||
WeatherHelper.updateWeather(this@WeatherProviderActivity)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.clicked(R.id.radioButton) {
|
.clicked(R.id.radioButton) {
|
||||||
if (Preferences.weatherProvider != provider.rawValue) {
|
if (Preferences.weatherProvider != provider.rawValue) {
|
||||||
@ -72,9 +70,7 @@ class WeatherProviderActivity : AppCompatActivity() {
|
|||||||
updateListItem()
|
updateListItem()
|
||||||
binding.loader.isVisible = true
|
binding.loader.isVisible = true
|
||||||
|
|
||||||
lifecycleScope.launch {
|
WeatherHelper.updateWeather(this@WeatherProviderActivity)
|
||||||
WeatherHelper.updateWeather(this@WeatherProviderActivity)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.checked(R.id.radioButton, provider.rawValue == Preferences.weatherProvider)
|
.checked(R.id.radioButton, provider.rawValue == Preferences.weatherProvider)
|
||||||
.with<TextView>(R.id.text2) {
|
.with<TextView>(R.id.text2) {
|
||||||
@ -92,10 +88,8 @@ class WeatherProviderActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
.clicked(R.id.action_configure) {
|
.clicked(R.id.action_configure) {
|
||||||
BottomSheetWeatherProviderSettings(this) {
|
BottomSheetWeatherProviderSettings(this) {
|
||||||
lifecycleScope.launch {
|
binding.loader.isVisible = true
|
||||||
binding.loader.isVisible = true
|
WeatherHelper.updateWeather(this@WeatherProviderActivity)
|
||||||
WeatherHelper.updateWeather(this@WeatherProviderActivity)
|
|
||||||
}
|
|
||||||
}.show()
|
}.show()
|
||||||
}
|
}
|
||||||
.visibility(R.id.action_configure, if (/*WeatherHelper.isKeyRequired(provider) && */provider.rawValue == Preferences.weatherProvider) View.VISIBLE else View.GONE)
|
.visibility(R.id.action_configure, if (/*WeatherHelper.isKeyRequired(provider) && */provider.rawValue == Preferences.weatherProvider) View.VISIBLE else View.GONE)
|
||||||
|
@ -206,15 +206,13 @@ class SettingsFragment : Fragment() {
|
|||||||
.animate()
|
.animate()
|
||||||
.rotation((binding.actionRefreshIcon.rotation - binding.actionRefreshIcon.rotation % 360f) + 360f)
|
.rotation((binding.actionRefreshIcon.rotation - binding.actionRefreshIcon.rotation % 360f) + 360f)
|
||||||
.withEndAction {
|
.withEndAction {
|
||||||
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
|
try {
|
||||||
try {
|
WeatherHelper.updateWeather(requireContext())
|
||||||
WeatherHelper.updateWeather(requireContext())
|
CalendarHelper.updateEventList(requireContext())
|
||||||
CalendarHelper.updateEventList(requireContext())
|
MediaPlayerHelper.updatePlayingMediaInfo(requireContext())
|
||||||
MediaPlayerHelper.updatePlayingMediaInfo(requireContext())
|
ActiveNotificationsHelper.clearLastNotification(requireContext())
|
||||||
ActiveNotificationsHelper.clearLastNotification(requireContext())
|
} catch (ex: Exception) {
|
||||||
} catch (ex: Exception) {
|
ex.printStackTrace()
|
||||||
ex.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.start()
|
.start()
|
||||||
|
@ -134,7 +134,7 @@ class WeatherFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun checkLocationPermission() {
|
private fun checkLocationPermission() {
|
||||||
if (requireActivity().checkGrantedPermission(Manifest.permission.ACCESS_FINE_LOCATION)) {
|
if (requireActivity().checkGrantedPermission(Manifest.permission.ACCESS_COARSE_LOCATION)) {
|
||||||
binding.locationPermissionAlert.isVisible = false
|
binding.locationPermissionAlert.isVisible = false
|
||||||
} else if (Preferences.customLocationAdd == "") {
|
} else if (Preferences.customLocationAdd == "") {
|
||||||
binding.locationPermissionAlert.isVisible = true
|
binding.locationPermissionAlert.isVisible = true
|
||||||
@ -177,9 +177,7 @@ class WeatherFragment : Fragment() {
|
|||||||
.addOnSelectItemListener { value ->
|
.addOnSelectItemListener { value ->
|
||||||
if (value != Preferences.weatherTempUnit) {
|
if (value != Preferences.weatherTempUnit) {
|
||||||
Preferences.weatherTempUnit = value
|
Preferences.weatherTempUnit = value
|
||||||
viewLifecycleOwner.lifecycleScope.launch {
|
WeatherHelper.updateWeather(requireContext())
|
||||||
WeatherHelper.updateWeather(requireContext())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.show()
|
}.show()
|
||||||
}
|
}
|
||||||
@ -208,9 +206,7 @@ class WeatherFragment : Fragment() {
|
|||||||
if (resultCode == Activity.RESULT_OK) {
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
when (requestCode) {
|
when (requestCode) {
|
||||||
Constants.RESULT_CODE_CUSTOM_LOCATION -> {
|
Constants.RESULT_CODE_CUSTOM_LOCATION -> {
|
||||||
viewLifecycleOwner.lifecycleScope.launch {
|
WeatherHelper.updateWeather(requireContext())
|
||||||
WeatherHelper.updateWeather(requireContext())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//RequestCode.WEATHER_PROVIDER_REQUEST_CODE.code -> {
|
//RequestCode.WEATHER_PROVIDER_REQUEST_CODE.code -> {
|
||||||
//}
|
//}
|
||||||
@ -222,15 +218,14 @@ class WeatherFragment : Fragment() {
|
|||||||
private fun requirePermission() {
|
private fun requirePermission() {
|
||||||
Dexter.withContext(requireContext())
|
Dexter.withContext(requireContext())
|
||||||
.withPermissions(
|
.withPermissions(
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION
|
Manifest.permission.ACCESS_FINE_LOCATION,
|
||||||
|
Manifest.permission.ACCESS_COARSE_LOCATION
|
||||||
).withListener(object: MultiplePermissionsListener {
|
).withListener(object: MultiplePermissionsListener {
|
||||||
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
|
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
|
||||||
report?.let {
|
report?.let {
|
||||||
if (report.areAllPermissionsGranted()) {
|
if (report.grantedPermissionResponses.isNotEmpty()) {
|
||||||
checkLocationPermission()
|
checkLocationPermission()
|
||||||
viewLifecycleOwner.lifecycleScope.launch {
|
WeatherHelper.updateWeather(requireContext())
|
||||||
WeatherHelper.updateWeather(requireContext())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
|
|||||||
context,
|
context,
|
||||||
appWidgetId,
|
appWidgetId,
|
||||||
IntentHelper.getWidgetUpdateIntent(context),
|
IntentHelper.getWidgetUpdateIntent(context),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(R.id.widget_shape_background, refreshIntent)
|
views.setOnClickPendingIntent(R.id.widget_shape_background, refreshIntent)
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
|
|||||||
|
|
||||||
val i = Intent(context, WidgetClickListenerReceiver::class.java)
|
val i = Intent(context, WidgetClickListenerReceiver::class.java)
|
||||||
i.action = Actions.ACTION_OPEN_WEATHER_INTENT
|
i.action = Actions.ACTION_OPEN_WEATHER_INTENT
|
||||||
val weatherPIntent = PendingIntent.getBroadcast(context, widgetID, i, 0)
|
val weatherPIntent = PendingIntent.getBroadcast(context, widgetID, i, PendingIntent.FLAG_IMMUTABLE)
|
||||||
|
|
||||||
views.setOnClickPendingIntent(R.id.weather_rect, weatherPIntent)
|
views.setOnClickPendingIntent(R.id.weather_rect, weatherPIntent)
|
||||||
views.setOnClickPendingIntent(R.id.weather_sub_line_rect, weatherPIntent)
|
views.setOnClickPendingIntent(R.id.weather_sub_line_rect, weatherPIntent)
|
||||||
@ -133,7 +133,7 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
|
|||||||
context,
|
context,
|
||||||
widgetID,
|
widgetID,
|
||||||
IntentHelper.getCalendarIntent(context),
|
IntentHelper.getCalendarIntent(context),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(R.id.date_rect, calPIntent)
|
views.setOnClickPendingIntent(R.id.date_rect, calPIntent)
|
||||||
views.setViewVisibility(R.id.first_line_rect, View.VISIBLE)
|
views.setViewVisibility(R.id.first_line_rect, View.VISIBLE)
|
||||||
@ -170,7 +170,7 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
|
|||||||
context,
|
context,
|
||||||
NewCalendarEventReceiver::class.java
|
NewCalendarEventReceiver::class.java
|
||||||
).apply { action = Actions.ACTION_GO_TO_NEXT_EVENT },
|
).apply { action = Actions.ACTION_GO_TO_NEXT_EVENT },
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -184,7 +184,7 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
|
|||||||
context,
|
context,
|
||||||
widgetID,
|
widgetID,
|
||||||
IntentHelper.getEventIntent(context, nextEvent),
|
IntentHelper.getEventIntent(context, nextEvent),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(R.id.next_event_rect, eventIntent)
|
views.setOnClickPendingIntent(R.id.next_event_rect, eventIntent)
|
||||||
views.setImageViewBitmap(
|
views.setImageViewBitmap(
|
||||||
@ -221,7 +221,7 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
|
|||||||
context,
|
context,
|
||||||
widgetID,
|
widgetID,
|
||||||
IntentHelper.getGoogleMapsIntentFromAddress(context, nextEvent.address),
|
IntentHelper.getGoogleMapsIntentFromAddress(context, nextEvent.address),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(R.id.sub_line_rect, mapIntent)
|
views.setOnClickPendingIntent(R.id.sub_line_rect, mapIntent)
|
||||||
} else {
|
} else {
|
||||||
@ -229,7 +229,7 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
|
|||||||
context,
|
context,
|
||||||
widgetID,
|
widgetID,
|
||||||
IntentHelper.getCalendarIntent(context, nextEvent.startDate),
|
IntentHelper.getCalendarIntent(context, nextEvent.startDate),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(R.id.sub_line_rect, pIntentDetail)
|
views.setOnClickPendingIntent(R.id.sub_line_rect, pIntentDetail)
|
||||||
}
|
}
|
||||||
@ -249,7 +249,7 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
|
|||||||
context,
|
context,
|
||||||
widgetID,
|
widgetID,
|
||||||
IntentHelper.getMusicIntent(context),
|
IntentHelper.getMusicIntent(context),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(R.id.sub_line_rect, musicIntent)
|
views.setOnClickPendingIntent(R.id.sub_line_rect, musicIntent)
|
||||||
showSomething = true
|
showSomething = true
|
||||||
@ -264,7 +264,7 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
|
|||||||
context,
|
context,
|
||||||
widgetID,
|
widgetID,
|
||||||
IntentHelper.getClockIntent(context),
|
IntentHelper.getClockIntent(context),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(R.id.sub_line_rect, alarmIntent)
|
views.setOnClickPendingIntent(R.id.sub_line_rect, alarmIntent)
|
||||||
showSomething = true
|
showSomething = true
|
||||||
@ -280,7 +280,7 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
|
|||||||
context,
|
context,
|
||||||
widgetID,
|
widgetID,
|
||||||
IntentHelper.getBatteryIntent(),
|
IntentHelper.getBatteryIntent(),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(R.id.sub_line_rect, batteryIntent)
|
views.setOnClickPendingIntent(R.id.sub_line_rect, batteryIntent)
|
||||||
showSomething = true
|
showSomething = true
|
||||||
@ -300,7 +300,7 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
|
|||||||
context,
|
context,
|
||||||
widgetID,
|
widgetID,
|
||||||
IntentHelper.getFitIntent(context),
|
IntentHelper.getFitIntent(context),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(R.id.sub_line_rect, fitIntent)
|
views.setOnClickPendingIntent(R.id.sub_line_rect, fitIntent)
|
||||||
showSomething = true
|
showSomething = true
|
||||||
@ -321,7 +321,7 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
|
|||||||
context,
|
context,
|
||||||
widgetID,
|
widgetID,
|
||||||
IntentHelper.getNotificationIntent(context),
|
IntentHelper.getNotificationIntent(context),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(
|
views.setOnClickPendingIntent(
|
||||||
R.id.sub_line_rect,
|
R.id.sub_line_rect,
|
||||||
@ -339,7 +339,7 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Constants.GlanceProviderId.EVENTS -> {
|
Constants.GlanceProviderId.EVENTS -> {
|
||||||
if (Preferences.showEventsAsGlanceProvider&& Preferences.showEvents && context.checkGrantedPermission(
|
if (Preferences.showEventsAsGlanceProvider && Preferences.showEvents && context.checkGrantedPermission(
|
||||||
Manifest.permission.READ_CALENDAR) && nextEvent != null) {
|
Manifest.permission.READ_CALENDAR) && nextEvent != null) {
|
||||||
val pIntentDetail = IntentHelper.getPendingIntent(
|
val pIntentDetail = IntentHelper.getPendingIntent(
|
||||||
context,
|
context,
|
||||||
@ -349,7 +349,7 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
|
|||||||
nextEvent,
|
nextEvent,
|
||||||
forceEventDetails = true
|
forceEventDetails = true
|
||||||
),
|
),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(
|
views.setOnClickPendingIntent(
|
||||||
R.id.sub_line_rect,
|
R.id.sub_line_rect,
|
||||||
@ -363,7 +363,7 @@ class AlignedWidget(val context: Context, val rightAligned: Boolean = false) {
|
|||||||
if (Preferences.showWeatherAsGlanceProvider && Preferences.showWeather && Preferences.weatherIcon != "") {
|
if (Preferences.showWeatherAsGlanceProvider && Preferences.showWeather && Preferences.weatherIcon != "") {
|
||||||
val i = Intent(context, WidgetClickListenerReceiver::class.java)
|
val i = Intent(context, WidgetClickListenerReceiver::class.java)
|
||||||
i.action = Actions.ACTION_OPEN_WEATHER_INTENT
|
i.action = Actions.ACTION_OPEN_WEATHER_INTENT
|
||||||
val weatherPIntent = PendingIntent.getBroadcast(context, widgetID, i, 0)
|
val weatherPIntent = PendingIntent.getBroadcast(context, widgetID, i, PendingIntent.FLAG_IMMUTABLE)
|
||||||
|
|
||||||
views.setOnClickPendingIntent(
|
views.setOnClickPendingIntent(
|
||||||
R.id.sub_line_rect,
|
R.id.sub_line_rect,
|
||||||
|
@ -41,7 +41,7 @@ class ClockWidget(val context: Context) {
|
|||||||
context,
|
context,
|
||||||
widgetID,
|
widgetID,
|
||||||
IntentHelper.getClockIntent(context),
|
IntentHelper.getClockIntent(context),
|
||||||
0
|
PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(R.id.time, clockPIntent)
|
views.setOnClickPendingIntent(R.id.time, clockPIntent)
|
||||||
views.setOnClickPendingIntent(R.id.time_am_pm, clockPIntent)
|
views.setOnClickPendingIntent(R.id.time_am_pm, clockPIntent)
|
||||||
|
@ -60,7 +60,7 @@ class StandardWidget(val context: Context) {
|
|||||||
context,
|
context,
|
||||||
appWidgetId,
|
appWidgetId,
|
||||||
IntentHelper.getWidgetUpdateIntent(context),
|
IntentHelper.getWidgetUpdateIntent(context),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(R.id.widget_shape_background, refreshIntent)
|
views.setOnClickPendingIntent(R.id.widget_shape_background, refreshIntent)
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ class StandardWidget(val context: Context) {
|
|||||||
|
|
||||||
val i = Intent(context, WidgetClickListenerReceiver::class.java)
|
val i = Intent(context, WidgetClickListenerReceiver::class.java)
|
||||||
i.action = Actions.ACTION_OPEN_WEATHER_INTENT
|
i.action = Actions.ACTION_OPEN_WEATHER_INTENT
|
||||||
val weatherPIntent = PendingIntent.getBroadcast(context, widgetID, i, 0)
|
val weatherPIntent = PendingIntent.getBroadcast(context, widgetID, i, PendingIntent.FLAG_IMMUTABLE)
|
||||||
|
|
||||||
views.setOnClickPendingIntent(R.id.weather_rect, weatherPIntent)
|
views.setOnClickPendingIntent(R.id.weather_rect, weatherPIntent)
|
||||||
views.setOnClickPendingIntent(R.id.weather_sub_line_rect, weatherPIntent)
|
views.setOnClickPendingIntent(R.id.weather_sub_line_rect, weatherPIntent)
|
||||||
@ -135,7 +135,7 @@ class StandardWidget(val context: Context) {
|
|||||||
context,
|
context,
|
||||||
widgetID,
|
widgetID,
|
||||||
IntentHelper.getCalendarIntent(context),
|
IntentHelper.getCalendarIntent(context),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(R.id.date_rect, calPIntent)
|
views.setOnClickPendingIntent(R.id.date_rect, calPIntent)
|
||||||
views.setViewVisibility(R.id.first_line_rect, View.VISIBLE)
|
views.setViewVisibility(R.id.first_line_rect, View.VISIBLE)
|
||||||
@ -178,7 +178,7 @@ class StandardWidget(val context: Context) {
|
|||||||
context,
|
context,
|
||||||
NewCalendarEventReceiver::class.java
|
NewCalendarEventReceiver::class.java
|
||||||
).apply { action = Actions.ACTION_GO_TO_NEXT_EVENT },
|
).apply { action = Actions.ACTION_GO_TO_NEXT_EVENT },
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -197,7 +197,7 @@ class StandardWidget(val context: Context) {
|
|||||||
context,
|
context,
|
||||||
NewCalendarEventReceiver::class.java
|
NewCalendarEventReceiver::class.java
|
||||||
).apply { action = Actions.ACTION_GO_TO_PREVIOUS_EVENT },
|
).apply { action = Actions.ACTION_GO_TO_PREVIOUS_EVENT },
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -213,7 +213,7 @@ class StandardWidget(val context: Context) {
|
|||||||
context,
|
context,
|
||||||
widgetID,
|
widgetID,
|
||||||
IntentHelper.getEventIntent(context, nextEvent),
|
IntentHelper.getEventIntent(context, nextEvent),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(R.id.next_event_rect, eventIntent)
|
views.setOnClickPendingIntent(R.id.next_event_rect, eventIntent)
|
||||||
views.setViewVisibility(R.id.next_event_rect, View.VISIBLE)
|
views.setViewVisibility(R.id.next_event_rect, View.VISIBLE)
|
||||||
@ -246,7 +246,7 @@ class StandardWidget(val context: Context) {
|
|||||||
context,
|
context,
|
||||||
widgetID,
|
widgetID,
|
||||||
IntentHelper.getGoogleMapsIntentFromAddress(context, nextEvent.address),
|
IntentHelper.getGoogleMapsIntentFromAddress(context, nextEvent.address),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(R.id.sub_line_rect, mapIntent)
|
views.setOnClickPendingIntent(R.id.sub_line_rect, mapIntent)
|
||||||
} else {
|
} else {
|
||||||
@ -254,7 +254,7 @@ class StandardWidget(val context: Context) {
|
|||||||
context,
|
context,
|
||||||
widgetID,
|
widgetID,
|
||||||
IntentHelper.getCalendarIntent(context, nextEvent.startDate),
|
IntentHelper.getCalendarIntent(context, nextEvent.startDate),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(R.id.sub_line_rect, pIntentDetail)
|
views.setOnClickPendingIntent(R.id.sub_line_rect, pIntentDetail)
|
||||||
}
|
}
|
||||||
@ -280,7 +280,7 @@ class StandardWidget(val context: Context) {
|
|||||||
context,
|
context,
|
||||||
widgetID,
|
widgetID,
|
||||||
IntentHelper.getMusicIntent(context),
|
IntentHelper.getMusicIntent(context),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(R.id.sub_line_rect, musicIntent)
|
views.setOnClickPendingIntent(R.id.sub_line_rect, musicIntent)
|
||||||
showSomething = true
|
showSomething = true
|
||||||
@ -295,7 +295,7 @@ class StandardWidget(val context: Context) {
|
|||||||
context,
|
context,
|
||||||
widgetID,
|
widgetID,
|
||||||
IntentHelper.getClockIntent(context),
|
IntentHelper.getClockIntent(context),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(R.id.sub_line_rect, alarmIntent)
|
views.setOnClickPendingIntent(R.id.sub_line_rect, alarmIntent)
|
||||||
showSomething = true
|
showSomething = true
|
||||||
@ -311,7 +311,7 @@ class StandardWidget(val context: Context) {
|
|||||||
context,
|
context,
|
||||||
widgetID,
|
widgetID,
|
||||||
IntentHelper.getBatteryIntent(),
|
IntentHelper.getBatteryIntent(),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(R.id.sub_line_rect, batteryIntent)
|
views.setOnClickPendingIntent(R.id.sub_line_rect, batteryIntent)
|
||||||
showSomething = true
|
showSomething = true
|
||||||
@ -331,7 +331,7 @@ class StandardWidget(val context: Context) {
|
|||||||
context,
|
context,
|
||||||
widgetID,
|
widgetID,
|
||||||
IntentHelper.getFitIntent(context),
|
IntentHelper.getFitIntent(context),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(R.id.sub_line_rect, fitIntent)
|
views.setOnClickPendingIntent(R.id.sub_line_rect, fitIntent)
|
||||||
showSomething = true
|
showSomething = true
|
||||||
@ -352,7 +352,7 @@ class StandardWidget(val context: Context) {
|
|||||||
context,
|
context,
|
||||||
widgetID,
|
widgetID,
|
||||||
IntentHelper.getNotificationIntent(context),
|
IntentHelper.getNotificationIntent(context),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(
|
views.setOnClickPendingIntent(
|
||||||
R.id.sub_line_rect,
|
R.id.sub_line_rect,
|
||||||
@ -370,7 +370,7 @@ class StandardWidget(val context: Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Constants.GlanceProviderId.EVENTS -> {
|
Constants.GlanceProviderId.EVENTS -> {
|
||||||
if (Preferences.showEventsAsGlanceProvider&& Preferences.showEvents && context.checkGrantedPermission(
|
if (Preferences.showEventsAsGlanceProvider && Preferences.showEvents && context.checkGrantedPermission(
|
||||||
Manifest.permission.READ_CALENDAR) && nextEvent != null) {
|
Manifest.permission.READ_CALENDAR) && nextEvent != null) {
|
||||||
val pIntentDetail = IntentHelper.getPendingIntent(
|
val pIntentDetail = IntentHelper.getPendingIntent(
|
||||||
context,
|
context,
|
||||||
@ -380,7 +380,7 @@ class StandardWidget(val context: Context) {
|
|||||||
nextEvent,
|
nextEvent,
|
||||||
forceEventDetails = true
|
forceEventDetails = true
|
||||||
),
|
),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(
|
views.setOnClickPendingIntent(
|
||||||
R.id.sub_line_rect,
|
R.id.sub_line_rect,
|
||||||
@ -394,7 +394,7 @@ class StandardWidget(val context: Context) {
|
|||||||
if (Preferences.showWeatherAsGlanceProvider && Preferences.showWeather && Preferences.weatherIcon != "") {
|
if (Preferences.showWeatherAsGlanceProvider && Preferences.showWeather && Preferences.weatherIcon != "") {
|
||||||
val i = Intent(context, WidgetClickListenerReceiver::class.java)
|
val i = Intent(context, WidgetClickListenerReceiver::class.java)
|
||||||
i.action = Actions.ACTION_OPEN_WEATHER_INTENT
|
i.action = Actions.ACTION_OPEN_WEATHER_INTENT
|
||||||
val weatherPIntent = PendingIntent.getBroadcast(context, widgetID, i, 0)
|
val weatherPIntent = PendingIntent.getBroadcast(context, widgetID, i, PendingIntent.FLAG_IMMUTABLE)
|
||||||
|
|
||||||
views.setOnClickPendingIntent(
|
views.setOnClickPendingIntent(
|
||||||
R.id.sub_line_rect,
|
R.id.sub_line_rect,
|
||||||
|
@ -214,6 +214,14 @@ fun Context.checkGrantedPermission(permission: String): Boolean {
|
|||||||
return ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED
|
return ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun android.app.AlarmManager.setExactIfCanSchedule(type: Int, triggerAtMillis: Long, operation: android.app.PendingIntent) {
|
||||||
|
// uncomment the following check after bumping compileSdkVersion/targetSdkVersion to 31
|
||||||
|
//if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.S || canScheduleExactAlarms())
|
||||||
|
setExact(type, triggerAtMillis, operation)
|
||||||
|
//else
|
||||||
|
// set(type, triggerAtMillis, operation)
|
||||||
|
}
|
||||||
|
|
||||||
fun Context.getCurrentWallpaper(): Drawable? = try {
|
fun Context.getCurrentWallpaper(): Drawable? = try {
|
||||||
WallpaperManager.getInstance(this).drawable
|
WallpaperManager.getInstance(this).drawable
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user