From c4a16224f0b5318f11797d05e3e0410c4b071659 Mon Sep 17 00:00:00 2001 From: Tommaso Berlose Date: Wed, 14 Oct 2020 00:45:29 +0200 Subject: [PATCH] Update the glance support --- .../components/FixedFocusScrollView.kt | 3 +- .../components/GlanceSettingsDialog.kt | 64 ++++-- .../anotherwidget/global/Actions.kt | 1 + .../anotherwidget/global/Constants.kt | 4 +- .../anotherwidget/global/Preferences.kt | 6 + .../helpers/ActiveNotificationsHelper.kt | 21 +- .../helpers/GlanceProviderHelper.kt | 17 +- .../anotherwidget/helpers/IntentHelper.kt | 12 ++ .../receivers/NotificationListener.kt | 62 ++++-- .../receivers/UpdatesReceiver.kt | 10 + .../ui/fragments/GlanceTabFragment.kt | 197 +++++++++++++----- .../ui/fragments/MainFragment.kt | 4 +- .../ui/fragments/SettingsFragment.kt | 5 +- .../anotherwidget/ui/widgets/MainWidget.kt | 50 ++++- .../res/drawable-hdpi/round_history_edu.png | Bin 0 -> 604 bytes .../round_history_edu_black_18.png | Bin 0 -> 325 bytes .../round_history_edu_black_24.png | Bin 0 -> 381 bytes .../round_history_edu_black_36.png | Bin 0 -> 513 bytes .../res/drawable-hdpi/round_notifications.png | Bin 0 -> 268 bytes .../round_notifications_white_18.png | Bin 0 -> 227 bytes .../round_notifications_white_36.png | Bin 0 -> 355 bytes .../round_notifications_white_48.png | Bin 0 -> 447 bytes .../res/drawable-mdpi/round_history_edu.png | Bin 0 -> 430 bytes .../round_history_edu_black_18.png | Bin 0 -> 232 bytes .../round_history_edu_black_24.png | Bin 0 -> 255 bytes .../round_history_edu_black_36.png | Bin 0 -> 381 bytes .../res/drawable-mdpi/round_notifications.png | Bin 0 -> 198 bytes .../round_notifications_white_18.png | Bin 0 -> 174 bytes .../round_notifications_white_36.png | Bin 0 -> 268 bytes .../round_notifications_white_48.png | Bin 0 -> 319 bytes .../res/drawable-xhdpi/round_history_edu.png | Bin 0 -> 763 bytes .../round_history_edu_black_18.png | Bin 0 -> 381 bytes .../round_history_edu_black_24.png | Bin 0 -> 430 bytes .../round_history_edu_black_36.png | Bin 0 -> 604 bytes .../drawable-xhdpi/round_notifications.png | Bin 0 -> 319 bytes .../round_notifications_white_18.png | Bin 0 -> 268 bytes .../round_notifications_white_36.png | Bin 0 -> 447 bytes .../round_notifications_white_48.png | Bin 0 -> 566 bytes .../res/drawable-xxhdpi/round_history_edu.png | Bin 0 -> 1087 bytes .../round_history_edu_black_18.png | Bin 0 -> 513 bytes .../round_history_edu_black_24.png | Bin 0 -> 604 bytes .../round_history_edu_black_36.png | Bin 0 -> 880 bytes .../drawable-xxhdpi/round_notifications.png | Bin 0 -> 447 bytes .../round_notifications_white_18.png | Bin 0 -> 355 bytes .../round_notifications_white_36.png | Bin 0 -> 624 bytes .../round_notifications_white_48.png | Bin 0 -> 851 bytes .../drawable-xxxhdpi/round_history_edu.png | Bin 0 -> 1326 bytes .../round_history_edu_black_18.png | Bin 0 -> 604 bytes .../round_history_edu_black_24.png | Bin 0 -> 763 bytes .../round_history_edu_black_36.png | Bin 0 -> 1087 bytes .../drawable-xxxhdpi/round_notifications.png | Bin 0 -> 566 bytes .../round_notifications_white_18.png | Bin 0 -> 447 bytes .../round_notifications_white_36.png | Bin 0 -> 851 bytes .../round_notifications_white_48.png | Bin 0 -> 1045 bytes .../res/drawable/round_history_edu_24.xml | 10 + .../res/drawable/round_notifications_24.xml | 10 + .../res/layout/fragment_glance_settings.xml | 3 +- .../main/res/layout/glance_provider_item.xml | 30 ++- .../glance_provider_settings_layout.xml | 66 ++++++ app/src/main/res/values-da/strings.xml | 3 +- app/src/main/res/values-it/strings.xml | 1 + app/src/main/res/values/strings.xml | 5 + 62 files changed, 472 insertions(+), 112 deletions(-) create mode 100644 app/src/main/res/drawable-hdpi/round_history_edu.png create mode 100644 app/src/main/res/drawable-hdpi/round_history_edu_black_18.png create mode 100644 app/src/main/res/drawable-hdpi/round_history_edu_black_24.png create mode 100644 app/src/main/res/drawable-hdpi/round_history_edu_black_36.png create mode 100644 app/src/main/res/drawable-hdpi/round_notifications.png create mode 100644 app/src/main/res/drawable-hdpi/round_notifications_white_18.png create mode 100644 app/src/main/res/drawable-hdpi/round_notifications_white_36.png create mode 100644 app/src/main/res/drawable-hdpi/round_notifications_white_48.png create mode 100644 app/src/main/res/drawable-mdpi/round_history_edu.png create mode 100644 app/src/main/res/drawable-mdpi/round_history_edu_black_18.png create mode 100644 app/src/main/res/drawable-mdpi/round_history_edu_black_24.png create mode 100644 app/src/main/res/drawable-mdpi/round_history_edu_black_36.png create mode 100644 app/src/main/res/drawable-mdpi/round_notifications.png create mode 100644 app/src/main/res/drawable-mdpi/round_notifications_white_18.png create mode 100644 app/src/main/res/drawable-mdpi/round_notifications_white_36.png create mode 100644 app/src/main/res/drawable-mdpi/round_notifications_white_48.png create mode 100644 app/src/main/res/drawable-xhdpi/round_history_edu.png create mode 100644 app/src/main/res/drawable-xhdpi/round_history_edu_black_18.png create mode 100644 app/src/main/res/drawable-xhdpi/round_history_edu_black_24.png create mode 100644 app/src/main/res/drawable-xhdpi/round_history_edu_black_36.png create mode 100644 app/src/main/res/drawable-xhdpi/round_notifications.png create mode 100644 app/src/main/res/drawable-xhdpi/round_notifications_white_18.png create mode 100644 app/src/main/res/drawable-xhdpi/round_notifications_white_36.png create mode 100644 app/src/main/res/drawable-xhdpi/round_notifications_white_48.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_history_edu.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_history_edu_black_18.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_history_edu_black_24.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_history_edu_black_36.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_notifications.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_notifications_white_18.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_notifications_white_36.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_notifications_white_48.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_history_edu.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_history_edu_black_18.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_history_edu_black_24.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_history_edu_black_36.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_notifications.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_notifications_white_18.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_notifications_white_36.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_notifications_white_48.png create mode 100644 app/src/main/res/drawable/round_history_edu_24.xml create mode 100644 app/src/main/res/drawable/round_notifications_24.xml diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/components/FixedFocusScrollView.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/components/FixedFocusScrollView.kt index b5f88ab..09539d4 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/components/FixedFocusScrollView.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/components/FixedFocusScrollView.kt @@ -6,13 +6,14 @@ import android.util.AttributeSet import android.util.Log import android.view.View import android.widget.ScrollView +import androidx.core.widget.NestedScrollView class FixedFocusScrollView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyle: Int = 0 -) : ScrollView(context, attrs, defStyle) { +) : NestedScrollView(context, attrs, defStyle) { var isScrollable = true diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/components/GlanceSettingsDialog.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/components/GlanceSettingsDialog.kt index 8ed3a9d..842c80f 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/components/GlanceSettingsDialog.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/components/GlanceSettingsDialog.kt @@ -7,7 +7,6 @@ import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.os.Build -import android.os.Bundle import android.util.Log import android.view.View import androidx.core.app.NotificationManagerCompat @@ -29,10 +28,9 @@ import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper import com.tommasoberlose.anotherwidget.receivers.ActivityDetectionReceiver import com.tommasoberlose.anotherwidget.ui.activities.MusicPlayersFilterActivity import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission -import kotlinx.android.synthetic.main.fragment_glance_settings.* import kotlinx.android.synthetic.main.glance_provider_settings_layout.view.* -class GlanceSettingsDialog(val context: Activity, val provider: Constants.GlanceProviderId, val statusCallback: (() -> Unit)?) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) { +class GlanceSettingsDialog(val context: Activity, val provider: Constants.GlanceProviderId, private val statusCallback: (() -> Unit)?) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) { override fun show() { val view = View.inflate(context, R.layout.glance_provider_settings_layout, null) @@ -44,6 +42,8 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> context.getString(R.string.settings_low_battery_level_title) Constants.GlanceProviderId.CUSTOM_INFO -> context.getString(R.string.settings_custom_notes_title) Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> context.getString(R.string.settings_daily_steps_title) + Constants.GlanceProviderId.NOTIFICATIONS -> context.getString(R.string.settings_show_notifications_title) + Constants.GlanceProviderId.GREETINGS -> context.getString(R.string.settings_show_greetings_title) } /* SUBTITLE*/ @@ -53,14 +53,16 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> context.getString(R.string.settings_low_battery_level_subtitle) Constants.GlanceProviderId.CUSTOM_INFO -> "" Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> context.getString(R.string.settings_daily_steps_subtitle) + Constants.GlanceProviderId.NOTIFICATIONS -> context.getString(R.string.settings_show_notifications_subtitle) + Constants.GlanceProviderId.GREETINGS -> context.getString(R.string.settings_show_greetings_subtitle) } /* SONG */ view.action_filter_music_players.isVisible = provider == Constants.GlanceProviderId.PLAYING_SONG - view.action_filter_music_players.setOnClickListener { - context.startActivity(Intent(context, MusicPlayersFilterActivity::class.java)) - } if (provider == Constants.GlanceProviderId.PLAYING_SONG) { + view.action_filter_music_players.setOnClickListener { + context.startActivity(Intent(context, MusicPlayersFilterActivity::class.java)) + } checkNotificationPermission(view) } @@ -68,27 +70,35 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance view.alarm_set_by_container.isVisible = provider == Constants.GlanceProviderId.NEXT_CLOCK_ALARM if (provider == Constants.GlanceProviderId.NEXT_CLOCK_ALARM) { view.header.text = context.getString(R.string.information_header) - } - if (provider == Constants.GlanceProviderId.NEXT_CLOCK_ALARM) { view.warning_container.isVisible = false checkNextAlarm(view) } /* GOOGLE STEPS */ + view.action_toggle_google_fit.isVisible = provider == Constants.GlanceProviderId.GOOGLE_FIT_STEPS if (provider == Constants.GlanceProviderId.GOOGLE_FIT_STEPS) { checkFitnessPermission(view) } /* BATTERY INFO */ - view.header.isVisible = provider != Constants.GlanceProviderId.BATTERY_LEVEL_LOW if (provider == Constants.GlanceProviderId.BATTERY_LEVEL_LOW) { view.warning_container.isVisible = false + view.header.isVisible = false view.divider.isVisible = false } - /* CUSTOM NOTES */ - view.subtitle.isVisible = provider != Constants.GlanceProviderId.CUSTOM_INFO - view.provider_switch.isVisible = provider != Constants.GlanceProviderId.CUSTOM_INFO + /* NOTIFICATIONS */ + view.action_filter_notifications_app.isVisible = provider == Constants.GlanceProviderId.NOTIFICATIONS + if (provider == Constants.GlanceProviderId.NOTIFICATIONS) { + checkLastNotificationsPermission(view) + } + + /* GREETINGS */ + if (provider == Constants.GlanceProviderId.GREETINGS) { + view.warning_container.isVisible = false + view.header.isVisible = false + view.divider.isVisible = false + } /* TOGGLE */ view.provider_switch.isChecked = when (provider) { @@ -97,6 +107,8 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> Preferences.showBatteryCharging Constants.GlanceProviderId.CUSTOM_INFO -> true Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> Preferences.showDailySteps + Constants.GlanceProviderId.NOTIFICATIONS -> Preferences.showNotifications + Constants.GlanceProviderId.GREETINGS -> Preferences.showGreetings } view.provider_switch.setOnCheckedChangeListener { _, isChecked -> @@ -112,6 +124,13 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> { Preferences.showBatteryCharging = isChecked } + Constants.GlanceProviderId.NOTIFICATIONS -> { + Preferences.showNotifications = isChecked + checkLastNotificationsPermission(view) + } + Constants.GlanceProviderId.GREETINGS -> { + Preferences.showGreetings = isChecked + } Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> { if (isChecked) { val account: GoogleSignInAccount? = GoogleSignIn.getLastSignedInAccount(context) @@ -161,6 +180,7 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance } private fun checkNotificationPermission(view: View) { + Log.d("ciao", NotificationManagerCompat.getEnabledListenerPackages(context).toString()) when { NotificationManagerCompat.getEnabledListenerPackages(context).contains(context.packageName) -> { view.warning_container.isVisible = false @@ -172,7 +192,25 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance view.warning_container.setOnClickListener { context.startActivity(Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS")) } - Log.d("ciao", "ok: ${view.warning_container.isVisible}") + } + else -> { + view.warning_container.isVisible = false + } + } + statusCallback?.invoke() + } + + private fun checkLastNotificationsPermission(view: View) { + when { + NotificationManagerCompat.getEnabledListenerPackages(context).contains(context.packageName) -> { + view.warning_container.isVisible = false + } + Preferences.showNotifications -> { + view.warning_container.isVisible = true + view.warning_title.text = context.getString(R.string.settings_request_last_notification_access) + view.warning_container.setOnClickListener { + context.startActivity(Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS")) + } } else -> { view.warning_container.isVisible = false diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/global/Actions.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/global/Actions.kt index 49c1f91..57727c4 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/global/Actions.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/global/Actions.kt @@ -12,4 +12,5 @@ object Actions { const val ACTION_GO_TO_NEXT_EVENT = "com.tommasoberlose.anotherwidget.action.GO_TO_NEXT_EVENT" const val ACTION_GO_TO_PREVIOUS_EVENT = "com.tommasoberlose.anotherwidget.action.GO_TO_PREVIOUS_EVENT" const val ACTION_REPORT_CRASH = "com.tommasoberlose.anotherwidget.action.REPORT_CRASH" + const val ACTION_CLEAR_NOTIFICATION = "com.tommasoberlose.anotherwidget.action.CLEAR_NOTIFICATION" } \ No newline at end of file diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/global/Constants.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/global/Constants.kt index 9aff1ec..12e5f04 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/global/Constants.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/global/Constants.kt @@ -30,7 +30,9 @@ object Constants { NEXT_CLOCK_ALARM("NEXT_CLOCK_ALARM"), BATTERY_LEVEL_LOW("BATTERY_LEVEL_LOW"), CUSTOM_INFO("CUSTOM_INFO"), - GOOGLE_FIT_STEPS("GOOGLE_FIT_STEPS"); + GOOGLE_FIT_STEPS("GOOGLE_FIT_STEPS"), + NOTIFICATIONS("NOTIFICATIONS"), + GREETINGS("GREETINGS"); companion object { private val map = GlanceProviderId.values().associateBy(GlanceProviderId::id) diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/global/Preferences.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/global/Preferences.kt index 0de6864..b4c72b1 100755 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/global/Preferences.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/global/Preferences.kt @@ -123,8 +123,14 @@ object Preferences : KotprefModel() { var isCharging by booleanPref(default = false) var googleFitSteps by longPref(default = -1) var showDailySteps by booleanPref(default = false) + var showGreetings by booleanPref(default = false) var showNotifications by booleanPref(default = false) + var lastNotificationId by intPref(default = -1) + var lastNotificationTitle by stringPref(default = "") + var lastNotificationIcon by intPref(default = 0) + var lastNotificationPackage by stringPref(default = "") + var showMusic by booleanPref(default = false) var mediaInfoFormat by stringPref(default = "") var mediaPlayerTitle by stringPref(default = "") diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/ActiveNotificationsHelper.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/ActiveNotificationsHelper.kt index 4a9da77..f07a049 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/ActiveNotificationsHelper.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/ActiveNotificationsHelper.kt @@ -1,19 +1,28 @@ package com.tommasoberlose.anotherwidget.helpers +import android.app.Notification import android.app.NotificationManager import android.content.Context import android.service.notification.StatusBarNotification import android.util.Log +import com.chibatching.kotpref.Kotpref +import com.chibatching.kotpref.blockingBulk import com.google.gson.Gson +import com.tommasoberlose.anotherwidget.global.Preferences +import java.lang.Exception object ActiveNotificationsHelper { - fun getLastNotification(context: Context): StatusBarNotification? { - with(context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager) { - activeNotifications.forEach { - Log.d("ciao", Gson().toJson(it).toString()) - } + fun showLastNotification(): Boolean { + return Preferences.lastNotificationId != -1 && Preferences.lastNotificationIcon != 0 && Preferences.lastNotificationPackage.isNotBlank() && Preferences.lastNotificationTitle.isNotBlank() + } - return activeNotifications.lastOrNull() + fun clearLastNotification(context: Context) { + Kotpref.init(context) + Preferences.blockingBulk { + remove(Preferences::lastNotificationId) + remove(Preferences::lastNotificationTitle) + remove(Preferences::lastNotificationPackage) + remove(Preferences::lastNotificationIcon) } } } \ No newline at end of file diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/GlanceProviderHelper.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/GlanceProviderHelper.kt index a9f8436..ee55308 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/GlanceProviderHelper.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/GlanceProviderHelper.kt @@ -1,7 +1,6 @@ package com.tommasoberlose.anotherwidget.helpers import android.content.Context -import android.util.Log import com.tommasoberlose.anotherwidget.R import com.tommasoberlose.anotherwidget.db.EventRepository import com.tommasoberlose.anotherwidget.global.Constants @@ -71,6 +70,18 @@ object GlanceProviderHelper { R.drawable.round_directions_walk ) } + Constants.GlanceProviderId.NOTIFICATIONS -> { + GlanceProvider(providerId.id, + context.getString(R.string.settings_show_notifications_title), + R.drawable.round_notifications + ) + } + Constants.GlanceProviderId.GREETINGS -> { + GlanceProvider(providerId.id, + context.getString(R.string.settings_show_greetings_title), + R.drawable.round_history_edu + ) + } } } @@ -84,12 +95,12 @@ object GlanceProviderHelper { val showGlance = Preferences.showGlance && (eventRepository.getEventsCount() == 0 || !Preferences.showEvents) && ( + (Preferences.showNotifications && ActiveNotificationsHelper.showLastNotification()) || (Preferences.showNextAlarm && AlarmHelper.getNextAlarm(context) != "") || (MediaPlayerHelper.isSomeonePlaying(context)) || (Preferences.showBatteryCharging && Preferences.isCharging || Preferences.isBatteryLevelLow) || (Preferences.customNotes.isNotEmpty()) || - (Preferences.showDailySteps && Preferences.googleFitSteps > 0) || - (Preferences.showNotifications && ActiveNotificationsHelper.getLastNotification(context) != null) + (Preferences.showDailySteps && Preferences.googleFitSteps > 0) ) eventRepository.close() return showGlance diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/IntentHelper.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/IntentHelper.kt index 8615f85..4bb7752 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/IntentHelper.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/IntentHelper.kt @@ -222,4 +222,16 @@ object IntentHelper { Intent() } } + + fun getNotificationIntent(context: Context): Intent { + val pm: PackageManager = context.packageManager + return try { + pm.getLaunchIntentForPackage(Preferences.lastNotificationPackage)!!.apply { + addCategory(Intent.CATEGORY_LAUNCHER) + } + } catch (e: Exception) { + context.toast(context.getString(R.string.error_opening_app)) + Intent() + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/NotificationListener.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/NotificationListener.kt index e77a428..57227aa 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/NotificationListener.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/NotificationListener.kt @@ -1,19 +1,18 @@ package com.tommasoberlose.anotherwidget.receivers -import android.app.Notification -import android.media.MediaMetadata -import android.media.session.MediaController +import android.app.* +import android.content.Context +import android.content.Intent import android.media.session.MediaSession -import android.media.session.PlaybackState +import android.os.Build import android.service.notification.NotificationListenerService import android.service.notification.StatusBarNotification -import android.util.Log -import com.chibatching.kotpref.bulk -import com.google.gson.Gson +import com.tommasoberlose.anotherwidget.global.Actions import com.tommasoberlose.anotherwidget.global.Preferences +import com.tommasoberlose.anotherwidget.helpers.ActiveNotificationsHelper import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper -import com.tommasoberlose.anotherwidget.helpers.WidgetHelper import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget +import java.util.* class NotificationListener : NotificationListenerService() { @@ -27,19 +26,58 @@ class NotificationListener : NotificationListenerService() { sbn?.notification?.extras?.let { bundle -> bundle.getParcelable(Notification.EXTRA_MEDIA_SESSION)?.let { MediaPlayerHelper.updatePlayingMediaInfo(this) + } ?: run { + val isGroupHeader = sbn.notification.flags and Notification.FLAG_GROUP_SUMMARY != 0 + val isOngoing = sbn.notification.flags and Notification.FLAG_ONGOING_EVENT != 0 + + if (bundle.containsKey(Notification.EXTRA_TITLE) && !isGroupHeader && !isOngoing) { + Preferences.lastNotificationId = sbn.id + Preferences.lastNotificationTitle = bundle.getString(Notification.EXTRA_TITLE) ?: "" + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + Preferences.lastNotificationIcon = sbn.notification.smallIcon.resId + Preferences.lastNotificationPackage = sbn.notification.smallIcon.resPackage + } else { + Preferences.lastNotificationIcon = sbn.notification.icon + Preferences.lastNotificationPackage = sbn.packageName + } + MainWidget.updateWidget(this) + setTimeout(this) + } } } - Log.d("ciao", Gson().toJson(sbn?.notification?.smallIcon)) - Log.d("ciao", Gson().toJson(sbn?.notification?.contentIntent)) - Log.d("ciao", Gson().toJson(sbn?.notification)) - MainWidget.updateWidget(this) super.onNotificationPosted(sbn) } override fun onNotificationRemoved(sbn: StatusBarNotification?) { MediaPlayerHelper.updatePlayingMediaInfo(this) + + sbn?.let { + if (sbn.id == Preferences.lastNotificationId && sbn.packageName == Preferences.lastNotificationPackage) { + ActiveNotificationsHelper.clearLastNotification(this) + } + } + MainWidget.updateWidget(this) super.onNotificationRemoved(sbn) } + + private fun setTimeout(context: Context) { + with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) { + val intent = Intent(context, UpdatesReceiver::class.java).apply { + action = Actions.ACTION_CLEAR_NOTIFICATION + } + cancel(PendingIntent.getBroadcast(context, 28943, intent, 0)) + setExact( + AlarmManager.RTC, + Calendar.getInstance().timeInMillis + 30 * 1000, + PendingIntent.getBroadcast( + context, + 5, + intent, + 0 + ) + ) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/UpdatesReceiver.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/UpdatesReceiver.kt index c930d86..f7159ee 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/UpdatesReceiver.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/UpdatesReceiver.kt @@ -12,8 +12,10 @@ import com.tommasoberlose.anotherwidget.db.EventRepository import com.tommasoberlose.anotherwidget.global.Actions import com.tommasoberlose.anotherwidget.global.Constants import com.tommasoberlose.anotherwidget.global.Preferences +import com.tommasoberlose.anotherwidget.helpers.ActiveNotificationsHelper import com.tommasoberlose.anotherwidget.helpers.BatteryHelper import com.tommasoberlose.anotherwidget.helpers.CalendarHelper +import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper import com.tommasoberlose.anotherwidget.models.Event import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget import org.joda.time.Period @@ -32,16 +34,24 @@ class UpdatesReceiver : BroadcastReceiver() { Intent.ACTION_DATE_CHANGED, Actions.ACTION_CALENDAR_UPDATE -> { CalendarHelper.updateEventList(context) + ActiveNotificationsHelper.clearLastNotification(context) + MediaPlayerHelper.updatePlayingMediaInfo(context) } "com.sec.android.widgetapp.APPWIDGET_RESIZE", AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED, + Actions.ACTION_ALARM_UPDATE, Actions.ACTION_TIME_UPDATE -> { MainWidget.updateWidget(context) if (intent.hasExtra(EVENT_ID)) { setUpdates(context, intent.getLongExtra(EVENT_ID, -1)) } } + + Actions.ACTION_CLEAR_NOTIFICATION -> { + ActiveNotificationsHelper.clearLastNotification(context) + MainWidget.updateWidget(context) + } } } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/GlanceTabFragment.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/GlanceTabFragment.kt index 669c662..5a1673e 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/GlanceTabFragment.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/GlanceTabFragment.kt @@ -7,19 +7,16 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter -import android.content.pm.PackageManager -import android.net.Uri +import android.graphics.Canvas import android.os.Build import android.os.Bundle -import android.provider.Settings -import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ImageView import androidx.core.app.NotificationManagerCompat import androidx.core.content.ContextCompat -import androidx.core.view.isVisible +import androidx.core.view.ViewCompat import androidx.databinding.DataBindingUtil import androidx.fragment.app.Fragment import androidx.lifecycle.Observer @@ -30,15 +27,11 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.google.android.gms.auth.api.signin.GoogleSignIn import com.google.android.gms.auth.api.signin.GoogleSignInAccount -import com.google.android.gms.auth.api.signin.GoogleSignInOptions import com.google.android.gms.common.api.ApiException -import com.karumi.dexter.Dexter -import com.karumi.dexter.MultiplePermissionsReport -import com.karumi.dexter.PermissionToken -import com.karumi.dexter.listener.PermissionRequest -import com.karumi.dexter.listener.multi.MultiplePermissionsListener +import com.google.android.material.card.MaterialCardView import com.tommasoberlose.anotherwidget.R -import com.tommasoberlose.anotherwidget.components.* +import com.tommasoberlose.anotherwidget.components.CustomNotesDialog +import com.tommasoberlose.anotherwidget.components.GlanceSettingsDialog import com.tommasoberlose.anotherwidget.databinding.FragmentGlanceSettingsBinding import com.tommasoberlose.anotherwidget.global.Constants import com.tommasoberlose.anotherwidget.global.Preferences @@ -49,14 +42,10 @@ import com.tommasoberlose.anotherwidget.models.GlanceProvider import com.tommasoberlose.anotherwidget.receivers.ActivityDetectionReceiver import com.tommasoberlose.anotherwidget.receivers.ActivityDetectionReceiver.Companion.FITNESS_OPTIONS import com.tommasoberlose.anotherwidget.ui.activities.MainActivity -import com.tommasoberlose.anotherwidget.ui.activities.MusicPlayersFilterActivity import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission -import com.tommasoberlose.anotherwidget.utils.checkIfFitInstalled -import com.tommasoberlose.anotherwidget.utils.toast -import kotlinx.android.synthetic.main.fragment_calendar_settings.* +import com.tommasoberlose.anotherwidget.utils.convertDpToPixel import kotlinx.android.synthetic.main.fragment_glance_settings.* -import kotlinx.android.synthetic.main.fragment_glance_settings.scrollView import kotlinx.coroutines.delay import kotlinx.coroutines.launch import net.idik.lib.slimadapter.SlimAdapter @@ -79,11 +68,14 @@ class GlanceTabFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? + savedInstanceState: Bundle?, ): View { viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java) - val binding = DataBindingUtil.inflate(inflater, R.layout.fragment_glance_settings, container, false) + val binding = DataBindingUtil.inflate(inflater, + R.layout.fragment_glance_settings, + container, + false) subscribeUi(binding, viewModel) @@ -97,8 +89,6 @@ class GlanceTabFragment : Fragment() { super.onActivityCreated(savedInstanceState) // List - adapter = SlimAdapter.create() - providers_list.setHasFixedSize(true) val mLayoutManager = LinearLayoutManager(context) providers_list.layoutManager = mLayoutManager @@ -130,45 +120,106 @@ class GlanceTabFragment : Fragment() { when (provider) { Constants.GlanceProviderId.PLAYING_SONG -> { when { - NotificationManagerCompat.getEnabledListenerPackages(requireContext()).contains(requireContext().packageName) -> { + NotificationManagerCompat.getEnabledListenerPackages(requireContext()) + .contains( + requireContext().packageName) -> { MediaPlayerHelper.updatePlayingMediaInfo(requireContext()) - injector.invisible(R.id.error_icon) - injector.text(R.id.label, if (Preferences.showMusic) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)) + injector.visibility(R.id.error_icon, View.GONE) + injector.visibility(R.id.info_icon, View.VISIBLE) + injector.text(R.id.label, + if (Preferences.showMusic) getString(R.string.settings_visible) else getString( + R.string.settings_not_visible)) } Preferences.showMusic -> { - injector.visible(R.id.error_icon) + injector.visibility(R.id.error_icon, View.VISIBLE) + injector.visibility(R.id.info_icon, View.GONE) injector.text(R.id.label, getString(R.string.settings_not_visible)) } else -> { - injector.invisible(R.id.error_icon) + injector.visibility(R.id.error_icon, View.GONE) + injector.visibility(R.id.info_icon, View.VISIBLE) injector.text(R.id.label, getString(R.string.settings_not_visible)) } } } Constants.GlanceProviderId.NEXT_CLOCK_ALARM -> { - injector.text(R.id.label, if (Preferences.showNextAlarm && !AlarmHelper.isAlarmProbablyWrong(requireContext())) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)) - injector.visibility(R.id.error_icon, if (Preferences.showNextAlarm && AlarmHelper.isAlarmProbablyWrong(requireContext())) View.VISIBLE else View.GONE) + injector.text(R.id.label, + if (Preferences.showNextAlarm && !AlarmHelper.isAlarmProbablyWrong( + requireContext()) + ) getString(R.string.settings_visible) else getString( + R.string.settings_not_visible)) + injector.visibility(R.id.error_icon, + if (Preferences.showNextAlarm && AlarmHelper.isAlarmProbablyWrong( + requireContext()) + ) View.VISIBLE else View.GONE) + injector.visibility(R.id.info_icon, + if (!(Preferences.showNextAlarm && AlarmHelper.isAlarmProbablyWrong( + requireContext())) + ) View.VISIBLE else View.GONE) } Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> { - injector.text(R.id.label, if (Preferences.showBatteryCharging) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)) - injector.invisible(R.id.error_icon) + injector.text(R.id.label, + if (Preferences.showBatteryCharging) getString(R.string.settings_visible) else getString( + R.string.settings_not_visible)) + injector.visibility(R.id.error_icon, View.GONE) + injector.visibility(R.id.info_icon, View.VISIBLE) + } + Constants.GlanceProviderId.NOTIFICATIONS -> { + when { + NotificationManagerCompat.getEnabledListenerPackages(requireContext()) + .contains( + requireContext().packageName) -> { + injector.visibility(R.id.error_icon, View.GONE) + injector.visibility(R.id.info_icon, View.VISIBLE) + injector.text(R.id.label, + if (Preferences.showNotifications) getString( + R.string.settings_visible) else getString(R.string.settings_not_visible)) + } + Preferences.showNotifications -> { + injector.visibility(R.id.error_icon, View.VISIBLE) + injector.visibility(R.id.info_icon, View.GONE) + injector.text(R.id.label, getString(R.string.settings_not_visible)) + } + else -> { + injector.visibility(R.id.error_icon, View.GONE) + injector.visibility(R.id.info_icon, View.VISIBLE) + injector.text(R.id.label, getString(R.string.settings_not_visible)) + } + } + } + Constants.GlanceProviderId.GREETINGS -> { + injector.text(R.id.label, + if (Preferences.showGreetings) getString(R.string.settings_visible) else getString( + R.string.settings_not_visible)) + injector.visibility(R.id.error_icon, View.GONE) + injector.visibility(R.id.info_icon, View.VISIBLE) } Constants.GlanceProviderId.CUSTOM_INFO -> { - injector.text(R.id.label, if (Preferences.customNotes != "") getString(R.string.settings_visible) else getString(R.string.settings_not_visible)) - injector.invisible(R.id.error_icon) + injector.text(R.id.label, + if (Preferences.customNotes != "") getString(R.string.settings_visible) else getString( + R.string.settings_not_visible)) + injector.visibility(R.id.error_icon, View.GONE) + injector.visibility(R.id.info_icon, View.VISIBLE) } Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || activity?.checkGrantedPermission(Manifest.permission.ACTIVITY_RECOGNITION) == true) { - injector.text(R.id.label, if (Preferences.showDailySteps) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)) - injector.invisible(R.id.error_icon) + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || activity?.checkGrantedPermission( + Manifest.permission.ACTIVITY_RECOGNITION) == true + ) { + injector.text(R.id.label, + if (Preferences.showDailySteps) getString(R.string.settings_visible) else getString( + R.string.settings_not_visible)) + injector.visibility(R.id.error_icon, View.GONE) + injector.visibility(R.id.info_icon, View.VISIBLE) } else if (Preferences.showDailySteps) { ActivityDetectionReceiver.unregisterFence(requireContext()) - injector.visible(R.id.error_icon) + injector.visibility(R.id.error_icon, View.VISIBLE) + injector.visibility(R.id.info_icon, View.GONE) injector.text(R.id.label, getString(R.string.settings_not_visible)) } else { ActivityDetectionReceiver.unregisterFence(requireContext()) injector.text(R.id.label, getString(R.string.settings_not_visible)) - injector.invisible(R.id.error_icon) + injector.visibility(R.id.error_icon, View.GONE) + injector.visibility(R.id.info_icon, View.VISIBLE) } } } @@ -180,28 +231,66 @@ class GlanceTabFragment : Fragment() { ItemTouchHelper.UP or ItemTouchHelper.DOWN, 0 ) { + + val list = GlanceProviderHelper.getGlanceProviders(requireContext()) + override fun onMove( recyclerView: RecyclerView, - viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder + viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder, ): Boolean { val fromPos = viewHolder.adapterPosition val toPos = target.adapterPosition // move item in `fromPos` to `toPos` in adapter. adapter.notifyItemMoved(fromPos, toPos) - val list = GlanceProviderHelper.getGlanceProviders(requireContext()) Collections.swap(list, fromPos, toPos) - GlanceProviderHelper.saveGlanceProviderOrder(list) return true } - override fun getSwipeThreshold(viewHolder: RecyclerView.ViewHolder): Float { - return 1f + override fun isItemViewSwipeEnabled(): Boolean { + return false + } + + override fun clearView( + recyclerView: RecyclerView, + viewHolder: RecyclerView.ViewHolder + ) { + super.clearView(recyclerView, viewHolder) + GlanceProviderHelper.saveGlanceProviderOrder(list) + } + + override fun onChildDraw( + c: Canvas, + recyclerView: RecyclerView, + viewHolder: RecyclerView.ViewHolder, + dX: Float, + dY: Float, + actionState: Int, + isCurrentlyActive: Boolean, + ) { + val view = viewHolder.itemView as MaterialCardView + if (isCurrentlyActive) { + ViewCompat.setElevation(view, 2f.convertDpToPixel(requireContext())) + view.setCardBackgroundColor(ContextCompat.getColor(requireContext(), + R.color.colorPrimary)) + } else { + ViewCompat.setElevation(view, 0f) + view.setCardBackgroundColor(ContextCompat.getColor(requireContext(), + R.color.colorPrimaryDark)) + } + + super.onChildDraw(c, + recyclerView, + viewHolder, + dX, + dY, + actionState, + isCurrentlyActive) } override fun onSwiped( viewHolder: RecyclerView.ViewHolder, - direction: Int + direction: Int, ) { // remove from adapter } @@ -219,14 +308,16 @@ class GlanceTabFragment : Fragment() { private fun subscribeUi( binding: FragmentGlanceSettingsBinding, - viewModel: MainViewModel + viewModel: MainViewModel, ) { binding.isGlanceVisible = Preferences.showGlance viewModel.showGlance.observe(viewLifecycleOwner, Observer { maintainScrollPosition { binding.isGlanceVisible = it - show_glance_label.text = if (it) getString(R.string.description_show_glance_visible) else getString(R.string.description_show_glance_not_visible) + show_glance_label.text = + if (it) getString(R.string.description_show_glance_visible) else getString( + R.string.description_show_glance_not_visible) } }) } @@ -243,13 +334,14 @@ class GlanceTabFragment : Fragment() { private val nextAlarmChangeBroadcastReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { - adapter.notifyItemChanged(1) + adapter.notifyItemRangeChanged(0, adapter.data.size) } } override fun onStart() { super.onStart() - activity?.registerReceiver(nextAlarmChangeBroadcastReceiver, IntentFilter(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED)) + activity?.registerReceiver(nextAlarmChangeBroadcastReceiver, + IntentFilter(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED)) if (dialog != null) { dialog?.show() } @@ -263,12 +355,12 @@ class GlanceTabFragment : Fragment() { override fun onActivityResult( requestCode: Int, resultCode: Int, - data: Intent? + data: Intent?, ) { when (requestCode) { 1 -> { if (resultCode == Activity.RESULT_OK) { - adapter.notifyItemChanged(2) + adapter.notifyItemRangeChanged(0, adapter.data.size) if (dialog != null) { dialog?.show() } @@ -279,9 +371,10 @@ class GlanceTabFragment : Fragment() { } } } - 2-> { + 2 -> { try { - val account: GoogleSignInAccount? = GoogleSignIn.getSignedInAccountFromIntent(data).getResult(ApiException::class.java) + val account: GoogleSignInAccount? = GoogleSignIn.getSignedInAccountFromIntent( + data).getResult(ApiException::class.java) if (!GoogleSignIn.hasPermissions(account, FITNESS_OPTIONS)) { GoogleSignIn.requestPermissions( requireActivity(), @@ -289,7 +382,7 @@ class GlanceTabFragment : Fragment() { account, FITNESS_OPTIONS) } else { - adapter.notifyItemChanged(2) + adapter.notifyItemRangeChanged(0, adapter.data.size) if (dialog != null) { dialog?.show() } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/MainFragment.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/MainFragment.kt index 53e98b7..1e81b23 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/MainFragment.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/MainFragment.kt @@ -35,6 +35,7 @@ import com.tommasoberlose.anotherwidget.helpers.ColorHelper import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark import com.tommasoberlose.anotherwidget.helpers.WeatherHelper import com.tommasoberlose.anotherwidget.helpers.WidgetHelper +import com.tommasoberlose.anotherwidget.receivers.ActivityDetectionReceiver import com.tommasoberlose.anotherwidget.ui.activities.MainActivity import com.tommasoberlose.anotherwidget.ui.adapters.ViewPagerAdapter import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel @@ -363,7 +364,8 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList tabs?.getTabAt(4)?.orCreateBadge?.apply { backgroundColor = ContextCompat.getColor(requireContext(), R.color.errorColorText) badgeGravity = BadgeDrawable.TOP_END - }?.isVisible = Preferences.showMusic && !NotificationManagerCompat.getEnabledListenerPackages(requireContext()).contains(requireContext().packageName) + }?.isVisible = ((Preferences.showMusic || Preferences.showNotifications) && !NotificationManagerCompat.getEnabledListenerPackages(requireContext()).contains(requireContext().packageName)) || + (Preferences.showDailySteps && !(Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || requireActivity().checkGrantedPermission(Manifest.permission.ACTIVITY_RECOGNITION))) } override fun onResume() { diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/SettingsFragment.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/SettingsFragment.kt index 53ab98b..2e01549 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/SettingsFragment.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/fragments/SettingsFragment.kt @@ -26,6 +26,7 @@ import com.tommasoberlose.anotherwidget.R import com.tommasoberlose.anotherwidget.components.BottomSheetMenu import com.tommasoberlose.anotherwidget.databinding.FragmentSettingsBinding import com.tommasoberlose.anotherwidget.global.Preferences +import com.tommasoberlose.anotherwidget.helpers.ActiveNotificationsHelper import com.tommasoberlose.anotherwidget.ui.activities.MainActivity import com.tommasoberlose.anotherwidget.ui.activities.SupportDevActivity import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel @@ -131,9 +132,6 @@ class SettingsFragment : Fragment() { Preferences.showPreview = isChecked } - action_show_wallpaper.setOnClickListener { - } - action_show_wallpaper.setOnClickListener { show_wallpaper_toggle.isChecked = !show_wallpaper_toggle.isChecked } @@ -198,6 +196,7 @@ class SettingsFragment : Fragment() { } CalendarHelper.updateEventList(requireContext()) MediaPlayerHelper.updatePlayingMediaInfo(requireContext()) + ActiveNotificationsHelper.clearLastNotification(requireContext()) } } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/MainWidget.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/MainWidget.kt index 96b7dd5..ab9101d 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/MainWidget.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/ui/widgets/MainWidget.kt @@ -7,23 +7,21 @@ import android.appwidget.AppWidgetProvider import android.content.ComponentName import android.content.Context import android.content.Intent +import android.content.IntentSender import android.content.res.Resources import android.graphics.Color import android.graphics.Typeface import android.os.Bundle -import android.os.Handler -import android.os.HandlerThread -import android.os.Looper import android.text.format.DateUtils import android.util.Log import android.util.TypedValue import android.view.View -import android.view.ViewGroup -import android.widget.* +import android.widget.ImageView +import android.widget.RemoteViews +import android.widget.TextView import androidx.core.content.ContextCompat -import androidx.core.provider.FontRequest -import androidx.core.provider.FontsContractCompat import androidx.core.view.isVisible +import com.google.gson.Gson import com.tommasoberlose.anotherwidget.R import com.tommasoberlose.anotherwidget.db.EventRepository import com.tommasoberlose.anotherwidget.global.Actions @@ -32,9 +30,10 @@ import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.helpers.* import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toIntValue import com.tommasoberlose.anotherwidget.receivers.* -import com.tommasoberlose.anotherwidget.utils.* +import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission +import com.tommasoberlose.anotherwidget.utils.isDarkTheme +import com.tommasoberlose.anotherwidget.utils.toPixel import kotlinx.android.synthetic.main.the_widget.view.* -import java.lang.Exception import java.text.DateFormat import java.util.* import java.util.concurrent.TimeUnit @@ -348,6 +347,26 @@ class MainWidget : AppWidgetProvider() { break@loop } } + Constants.GlanceProviderId.NOTIFICATIONS -> { + if (Preferences.showNotifications && ActiveNotificationsHelper.showLastNotification()) { + try { + val remotePackageContext = context.createPackageContext(Preferences.lastNotificationPackage, 0) + val icon = ContextCompat.getDrawable(remotePackageContext, Preferences.lastNotificationIcon) + val notificationIntent = PendingIntent.getActivity( + context, + widgetID, + IntentHelper.getNotificationIntent(context), + PendingIntent.FLAG_UPDATE_CURRENT + ) + views.setOnClickPendingIntent( + R.id.second_row_rect, + notificationIntent + ) + showSomething = true + break@loop + } catch (ex: Exception) {} + } + } } } @@ -695,6 +714,19 @@ class MainWidget : AppWidgetProvider() { break@loop } } + Constants.GlanceProviderId.NOTIFICATIONS -> { + if (Preferences.showNotifications && ActiveNotificationsHelper.showLastNotification()) { + try { + val remotePackageContext = context.createPackageContext(Preferences.lastNotificationPackage, 0) + val icon = ContextCompat.getDrawable(remotePackageContext, Preferences.lastNotificationIcon) + v.second_row_icon.isVisible = true + v.second_row_icon.setImageDrawable(icon) + v.next_event_date.text = Preferences.lastNotificationTitle + showSomething = true + break@loop + } catch (ex: Exception) {} + } + } } } diff --git a/app/src/main/res/drawable-hdpi/round_history_edu.png b/app/src/main/res/drawable-hdpi/round_history_edu.png new file mode 100644 index 0000000000000000000000000000000000000000..42c946b7af99f4a6c659db7b5f2477173e469b6b GIT binary patch literal 604 zcmV-i0;BzjP)kS z{y%JiLgXkmu*3)6OYsjL$;YMzI;{8)wZJtZ_}0NC#>fSc)IMUbDEtVt`MP+KN75B2 z!dx23*%{{5ku(L8N4i1iap-yU(&|W>0?8x!Jozr3h~<%V1ac$E1IZ()3*<(U2a-op z7s!ny4H>9t@uk`d=jh;55J^vkPOA3~?D24)xApn2@pa=uNFcc6J13*v=0Sv(~00hHO000yLz%UF!F$6_0K=AFw zA%42c^%$xj4>-L1cXiggEJ1;Cq7}TGAw!Nw++&V6DA4*?WR40wWDJh*g`GzSp*|LS zGJykH{6Hfc_*VO3CFDGtv#!xY81N7qyG8>!ThyrB`wbc!42XGxz}~*wU}($+U(rD5 zFh_zFJ|G(mj+y1qNDqy)HW(92P-3uWMdmqaSj?RD4hIPNAAh)rijB6nu~G0HyVzKQ z)cJ-`AcYbCXIp5ZmzY=v1xo)jR$ze^LWxPcg-*~x&JvUN37x1y&}PU{2H0SU%g$iG Xg000000NkvXXu0mjfMtXl( literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/round_history_edu_black_24.png b/app/src/main/res/drawable-hdpi/round_history_edu_black_24.png new file mode 100644 index 0000000000000000000000000000000000000000..eacbbaf5e26b233ce82ee8965c1aca5dfa339e65 GIT binary patch literal 381 zcmV-@0fPRCP)DryFdRY%VSoS!I7B!E2oMGsLI{W9!y$wKAq)Tk4hI-QfDjHa1PCyM;q8&d zyx3d!?%c3HKfvZ;-@b!!1KqfB$0#5UD@6G7Vx+i3jwMpWSU}*F!rTR3AsxOT@CxYM zll!Ii!hfEXmKrN$NRZ(f6{KZ@qg@59AuTu1o8aDv>Mbb33#8={p^>PwR_Q2bkR7EI zXm4gm*+HJD0(x`v^ErZaRE8YVc*8`+ln^t@5u|sf?;w<@AWCgV`GX>?t&0*@xU{1j zL260Ixr*_-bK{`DsN3?YOtgb+dq!|(wigaBa}LI@#*0m2Xf;1D2$A%r0eVF<%8z;GCb;qdk# zoL7DN?CxHt@6Qha&o_H-EAD?RE-o%EE^ZeCq>z#f(LtrVgH&LOjdzSYykLq2)|lf1 z3A)(D2vU(Yg4aL~Q^+4>SXUV45HyDwqyTgD3y^FYc2MxEk5I(iMq&D8lqFt~V1NW; z-$P)94$Q-@AsP}i@Y9;O#LO3G9k$~+7&q{(fh(*%aYkW`?RnxJ&{a;6UmFWgoI#k1 z+u%SP{t}nr!XPXlPKAZW8H5GIsj$#EyD%LW9@f@jI?gVPv2E;s8$)ttI6;0b43I%I z9cLA$H-czbV2l)^1jN~e4I!bB;nw$`vku$ATVPZQ7jRH24b$sl2Ju+q5qlxm(ke`^ zgL^z-SUkbF~fAarF-K$Mtje>mTNyNmvU`nLu(TZ~>Z@VGRtCK?;`Q z$|~#vQlb=1i?BYVWUgjmG3*@q^&rY&9mAfH-v=aT30Ai-;1dJPA<7#H-zCJ@846zu zE5oP+rLAWa^^9$lI*0cPe!Uf5afZ4sE-o%EE-vm1>Lpnn{rnWx00000NkvXXu0mjf D*e=s5 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/round_notifications.png b/app/src/main/res/drawable-hdpi/round_notifications.png new file mode 100644 index 0000000000000000000000000000000000000000..b42b127529acbe7f19db234f764fe32c5c735786 GIT binary patch literal 268 zcmV+n0rUQeP)`B>YHUGrP!7sLM-haT zIIH-WR8crLjJj*kH5&11%=<)bg72c34Aj~_QwF_iTc&<8tg%If7n~H?l>7qjNs?U| SKHH-J0000^G3L749#$QS1B%NGO(Pt>}Dw*LF?4%$82$FF=z zuMAmNp)(2`+769<6d1G>nj%-V!?4Lnij(i2*fbS8`b}IAb77`2v8yn7-B2dnBktzm zMs;E{^-Q{q&Hg;r$B-gdPmVMsb`obF61$6Y3yF=eir65Dg(bG7Et0lit!mz8EW;WX dtlqEdy#R7a^9o-tS9<^e002ovPDHLkV1m0ATz3Ef literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/round_notifications_white_36.png b/app/src/main/res/drawable-hdpi/round_notifications_white_36.png new file mode 100644 index 0000000000000000000000000000000000000000..57b6433bc4f227bb2b7e9c24513f5b2725fd4f1f GIT binary patch literal 355 zcmeAS@N?(olHy`uVBq!ia0vp^W+2SL1|)l2v+go5Flu?aIEGX(zP-xm((EX4{2~8g zgBAk^2?d@+iDL``3I_z7IG7JGFdSx3WRXy4`M}83V!$GCh(VxDogrn}t+!>L?PM70 ze%z0iT_fP+AT0i3QK3#Cvkv2i1C=iW)gyjpHoBcmoNo4dnvB_|n=7uY2tJcz=DK>x z0=an`x7`(g_Cls8fV=-+TCb*5yI5&k`Ty|8UnXq(l2{&h@r>+MhurV)irZto(Y#k z%^I%78OnPu_N*$^=X76TlHOalg^_Q=r9GcBnD=b8Ru43?Id<#anhV`Q53ju2+ZFV% z{qAoeRi}8#bp;Yj4|-U#1xnQf^m(3}Kl|)rlN}o(<$8An^`%a6i_|j;=;cviPF=t= zrO_yW?UaM01`_A?;fTs(lFRQ|Jia2GKBsE=MHQLM>0Ey^xb|hu|9(;A%+~X}Gq~Dr zEj^?#tA#V{)b;}gK=0eXOOuRko_hPYOlWjp# l_dl3_baL{6!z=n1cfbJ`?WFDLCBTSb@O1TaS?83{1OWC!zu*7> literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/round_history_edu.png b/app/src/main/res/drawable-mdpi/round_history_edu.png new file mode 100644 index 0000000000000000000000000000000000000000..02219f7fc1c676d309d8f33bbad3099097074da8 GIT binary patch literal 430 zcmV;f0a5;mP)Ds;2mwME!Y~{LfWsI93@|_#0ES@*Aq-&%0AU!0@L>ocK!6Zn2m^$}aCr9s z&dV#8@7~1s=Le$CL%Gjgq@|^$rKLq$jwK|rfDBRAt7xOT4WuCfM=iq`Ym^XWhfh2} z8dhu9m_s6P4;Y~IJkZ!t-`Bw&V%XycJIDb!+ymMuAj%uMsO}Q?nBotj6v$ly)W#6y z7dNnWgL}h_c26BYYXp2qVHjAcxdcVs1rv1n3QGTr~>xkNjhc5_Pu- z2STRm>0LKMlt$LUBZf5&v?BZi>K|xFoLhj7ILiQgDZuybLqO&kuz^GtJOiW=rw>R0 zJ?qYe?KuR@(L;un`s@SIRzRE$5N!*HqtL`nw1ha=pbHj1V$tBwX^R)MU@k2!EiEnW YA8B`_(EKAS3IG5A literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/round_history_edu_black_18.png b/app/src/main/res/drawable-mdpi/round_history_edu_black_18.png new file mode 100644 index 0000000000000000000000000000000000000000..8e14917d2c764e454add7757914ed997f600bbd1 GIT binary patch literal 232 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rhe^`0({Ar*{I&oQzwIWn|e+`z%; z)Zoa@vEhZBVv9fmBjYy?#gZNYg%;Na0V^kth0Ir?S<-yO9OTdQ9L}%$AAE4aHcsxK zXCf}WH$Oi*HdQ_PRg3VkM`1A%3d;qh?kvs{Q@LI6^hnD#E!%0*lbCo_S-s^hMpS8J zxgDOXtoSdoOkIJgdsqH5JKop0_-s^_5gc;&?EE!0eXNCU=I+&00D*p!s)}o95=fMqp?3f zaOuDj@Y1k^q@G6kBqchUtj12SsXkTMfs7neO=F$KF002ovPDHLk FV1j!)XQ2Q9 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/round_history_edu_black_36.png b/app/src/main/res/drawable-mdpi/round_history_edu_black_36.png new file mode 100644 index 0000000000000000000000000000000000000000..eacbbaf5e26b233ce82ee8965c1aca5dfa339e65 GIT binary patch literal 381 zcmV-@0fPRCP)DryFdRY%VSoS!I7B!E2oMGsLI{W9!y$wKAq)Tk4hI-QfDjHa1PCyM;q8&d zyx3d!?%c3HKfvZ;-@b!!1KqfB$0#5UD@6G7Vx+i3jwMpWSU}*F!rTR3AsxOT@CxYM zll!Ii!hfEXmKrN$NRZ(f6{KZ@qg@59AuTu1o8aDv>Mbb33#8={p^>PwR_Q2bkR7EI zXm4gm*+HJD0(x`v^ErZaRE8YVc*8`+ln^t@5u|sf?;w<@AWCgV`GX>?t&0*@xU{1j zL260Ixr*_-bK{``Q1?$>cn(`qx)<;H|NZiR*jQzEwykd9Rp7bDyph3D z%;%rKjfUFsrq?PF1v6y0>n0~0ti7bGAjl)j?WXJSB;k^y-Nv@x|JCJB2qZgNSnyBa v`^Nw4)*HK>uFMw;nYTVM61Z*919aOt?bP0l+XkKuo_3G literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/round_notifications_white_18.png b/app/src/main/res/drawable-mdpi/round_notifications_white_18.png new file mode 100644 index 0000000000000000000000000000000000000000..48beb7318b4296cbf786415572b8112ca21c1a6f GIT binary patch literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@RheQcoAhkP60RiK++x|NsB1;ImTk z;(x&d^JSP-8h-q#_t_xbQR!j$;z#|R1j~(WH~t*wuVdcGWXLA^U!A9^({RN+j^`B>YHUGrP!7sLM-haT zIIH-WR8crLjJj*kH5&11%=<)bg72c34Aj~_QwF_iTc&<8tg%If7n~H?l>7qjNs?U| SKHH-J00008P-y+w|Io$jooYr6GbdVm^G18P7Gr~x&g2DHIc_of+!FDwER`HfN@@H_c^;xyH} zu#sOAso)B0`Fvp%)qjMocIy%XmfAg*5HLVv-v<3C0R~uNiw$0I5mi+s_YFUvPjiMM Rs%-!O002ovPDHLkV1murgH!+j literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/round_history_edu.png b/app/src/main/res/drawable-xhdpi/round_history_edu.png new file mode 100644 index 0000000000000000000000000000000000000000..84e48a0c2572a901cbcf47e966caa4e8b5cebe62 GIT binary patch literal 763 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7Ro>U^?XK;uuoF`1THCigcjN@sEle ze2#)Fu7V6A&V?dJ1$Y8@Tp5otxCZhZUZ~NvNTMrAf{lZXqiGRG*CGoR#}D_*B|=}V z-+5>EcfI}k@(vw;p4@5vzHs4`ATQ0O2!d_LArY~ioLpZnbZrYfBxIa@nxlM!i)hCp z#v++Vr@7lt7#@h8y1~U)U=Lr>oa7!$o_UtXezeKR{y8lqzDAMD=HRsllHyVa^2O~F zg~}Qj>kg>=VQAM#6wKK5;Qo7#YdpLY5*fQa>L;`P;E6uS6ny95uU2ax?Y^r1f6I6Z z7?@-DEso3W`f!d*#O|auzq5MydXDgN} zJ>ZCqakFW%)R-tZr*A_~0ZVa!jIvGgGmDS+4=s{DC?j&7W1ew9kn#*=57z^XNkEZ< zT1X~~AdRci^*fp`O(D}n5bznQsm$E5W7>;jX zcqYMG!X7z52{kY*$6sbLsh}2Y$KTaBq`yn{iOaU21`) zcaGw&c?r@Fm;%d~vv*ql>ey7nEN44kpmh6&X;zM3Qg`G(Oiph}ITiKAf5$PtNjk@U olk(mBB_4m-Yrh9IZC!~MPn&7E)UDryFdRY%VSoS!I7B!E2oMGsLI{W9!y$wKAq)Tk4hI-QfDjHa1PCyM;q8&d zyx3d!?%c3HKfvZ;-@b!!1KqfB$0#5UD@6G7Vx+i3jwMpWSU}*F!rTR3AsxOT@CxYM zll!Ii!hfEXmKrN$NRZ(f6{KZ@qg@59AuTu1o8aDv>Mbb33#8={p^>PwR_Q2bkR7EI zXm4gm*+HJD0(x`v^ErZaRE8YVc*8`+ln^t@5u|sf?;w<@AWCgV`GX>?t&0*@xU{1j zL260Ixr*_-bK{`Ds;2mwME!Y~{LfWsI93@|_#0ES@*Aq-&%0AU!0@L>ocK!6Zn2m^$}aCr9s z&dV#8@7~1s=Le$CL%Gjgq@|^$rKLq$jwK|rfDBRAt7xOT4WuCfM=iq`Ym^XWhfh2} z8dhu9m_s6P4;Y~IJkZ!t-`Bw&V%XycJIDb!+ymMuAj%uMsO}Q?nBotj6v$ly)W#6y z7dNnWgL}h_c26BYYXp2qVHjAcxdcVs1rv1n3QGTr~>xkNjhc5_Pu- z2STRm>0LKMlt$LUBZf5&v?BZi>K|xFoLhj7ILiQgDZuybLqO&kuz^GtJOiW=rw>R0 zJ?qYe?KuR@(L;un`s@SIRzRE$5N!*HqtL`nw1ha=pbHj1V$tBwX^R)MU@k2!EiEnW YA8B`_(EKAS3IG5A literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/round_history_edu_black_36.png b/app/src/main/res/drawable-xhdpi/round_history_edu_black_36.png new file mode 100644 index 0000000000000000000000000000000000000000..42c946b7af99f4a6c659db7b5f2477173e469b6b GIT binary patch literal 604 zcmV-i0;BzjP)kS z{y%JiLgXkmu*3)6OYsjL$;YMzI;{8)wZJtZ_}0NC#>fSc)IMUbDEtVt`MP+KN75B2 z!dx23*%{{5ku(L8N4i1iap-yU(&|W>0?8x!Jozr3h~<%V1ac$E1IZ()3*<(U2a-op z7s!ny4H>9t@uk`d=jh;55J^vkPOA8P-y+w|Io$jooYr6GbdVm^G18P7Gr~x&g2DHIc_of+!FDwER`HfN@@H_c^;xyH} zu#sOAso)B0`Fvp%)qjMocIy%XmfAg*5HLVv-v<3C0R~uNiw$0I5mi+s_YFUvPjiMM Rs%-!O002ovPDHLkV1murgH!+j literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/round_notifications_white_18.png b/app/src/main/res/drawable-xhdpi/round_notifications_white_18.png new file mode 100644 index 0000000000000000000000000000000000000000..b42b127529acbe7f19db234f764fe32c5c735786 GIT binary patch literal 268 zcmV+n0rUQeP)`B>YHUGrP!7sLM-haT zIIH-WR8crLjJj*kH5&11%=<)bg72c34Aj~_QwF_iTc&<8tg%If7n~H?l>7qjNs?U| SKHH-J0000Y#k z%^I%78OnPu_N*$^=X76TlHOalg^_Q=r9GcBnD=b8Ru43?Id<#anhV`Q53ju2+ZFV% z{qAoeRi}8#bp;Yj4|-U#1xnQf^m(3}Kl|)rlN}o(<$8An^`%a6i_|j;=;cviPF=t= zrO_yW?UaM01`_A?;fTs(lFRQ|Jia2GKBsE=MHQLM>0Ey^xb|hu|9(;A%+~X}Gq~Dr zEj^?#tA#V{)b;}gK=0eXOOuRko_hPYOlWjp# l_dl3_baL{6!z=n1cfbJ`?WFDLCBTSb@O1TaS?83{1OWC!zu*7> literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/round_notifications_white_48.png b/app/src/main/res/drawable-xhdpi/round_notifications_white_48.png new file mode 100644 index 0000000000000000000000000000000000000000..bdea9e224b96318e7e4d83ca5202940801605830 GIT binary patch literal 566 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7Ro>VEpUp;uuoF`1TH?OKhUV@rUAx z9EXn@@EkT^X;4hyP~=JEaOPlUXaO@C5;+uG5*q{#6&SWCwlsIAHzWjauYNtJ_}za- zhCTK*$6wdPyShNY^hC~Ri=z_h76+WZ};sLKe^`Y z*!_6c`U6vUOJA>P)eKcRkdTm4bz0Pzzm{8l#*Db;_cwfcG#{|?85-L2e*3uP(fto1 z^Dk6bg#YMJ7d8LDHeK$#Wn5@TqHyo=@9e9$p4hNDRyZeh`{lZptx+l!-JS1t9D5zb zQqh@x*Z7!*_1`ktD-#l(xBG4ga&A%ovGliJcE^Ub_Sdp93YOXLyE-Akb-#(k)qn?^ z|J_`-@W9f4KLec`p8r~TFlgW3+gpQb+il;Tv}{QJ`*rCrzURMQulU86{PtuNQ}4fB zEB0N^f6S5*$)w`I^d$;JqN4MtT#)P&tt{>`qdzVg7tttPki|{^bGs7!iVqtHij5}=Wx&4{{O?_^D_%Nyv>hU g9PolfQpuh8wA%TrO|Noa0Hy~9Pgg&ebxsLQ07{GeIRF3v literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/round_history_edu.png b/app/src/main/res/drawable-xxhdpi/round_history_edu.png new file mode 100644 index 0000000000000000000000000000000000000000..c428693de25852705819c15e1e97824d31c6a0d3 GIT binary patch literal 1087 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=_6GQbxB}^+3tnF;J_B^UeMyjC zFat~S?)(4G&vutMJ)dX)_VnP*A`a2z?e+Nv9Pce&Usmv6e!E#^^7{VYtEb0*|GYT- zxxir?jq8uAb&eOyIGcDo=4bUYFfe`cba4!+V0?QkwCoOpfXhX>6^UsEj~C3${J)z^ zU8;P}Hr=T@&*#+LZ_;-A`0u>U`Ogp(^wLL6@YGZ8Lu(?Oo}3bW7|ObE)`eBgLCz7W z4l6a^ueY{j3-jAdzfB8HJ!F~BdF9+E^;Om9chtU^#CrAPPKT+6ho*G#UU6Kp zOw;JZz2I;rhDQ}#^8x)h8mPG%%*vV=Y$JExr z926>8GI!F|ysQf|mFzgeuUCIseJV^?%h`pUHFf#ky8ZL_&pqJLc|yV1d5Vok_as(b zc5i1FmbZ_5=gv93Q&FiYrNO+UR57Vzg~Cm#$6L>JDYbR*OgbAq!?!FL$mE+8Qkzqe z*Z%6IN2i6t)y)6#OYThDXMaga%wsZ}<(>e?kZB&xi^___rJYqj?dsqTx-0%H*7Rby z>&B)xomqjO6m-4hmbjj5-l9=CK}?nZ(xNAhQ9yS*RbaR5_-#M+*W@mSNB{go*IjT7 zby;DsN3?YOtgb+dq!|(wigaBa}LI@#*0m2Xf;1D2$A%r0eVF<%8z;GCb;qdk# zoL7DN?CxHt@6Qha&o_H-EAD?RE-o%EE^ZeCq>z#f(LtrVgH&LOjdzSYykLq2)|lf1 z3A)(D2vU(Yg4aL~Q^+4>SXUV45HyDwqyTgD3y^FYc2MxEk5I(iMq&D8lqFt~V1NW; z-$P)94$Q-@AsP}i@Y9;O#LO3G9k$~+7&q{(fh(*%aYkW`?RnxJ&{a;6UmFWgoI#k1 z+u%SP{t}nr!XPXlPKAZW8H5GIsj$#EyD%LW9@f@jI?gVPv2E;s8$)ttI6;0b43I%I z9cLA$H-czbV2l)^1jN~e4I!bB;nw$`vku$ATVPZQ7jRH24b$sl2Ju+q5qlxm(ke`^ zgL^z-SUkbF~fAarF-K$Mtje>mTNyNmvU`nLu(TZ~>Z@VGRtCK?;`Q z$|~#vQlb=1i?BYVWUgjmG3*@q^&rY&9mAfH-v=aT30Ai-;1dJPA<7#H-zCJ@846zu zE5oP+rLAWa^^9$lI*0cPe!Uf5afZ4sE-o%EE-vm1>Lpnn{rnWx00000NkvXXu0mjf D*e=s5 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/round_history_edu_black_24.png b/app/src/main/res/drawable-xxhdpi/round_history_edu_black_24.png new file mode 100644 index 0000000000000000000000000000000000000000..42c946b7af99f4a6c659db7b5f2477173e469b6b GIT binary patch literal 604 zcmV-i0;BzjP)kS z{y%JiLgXkmu*3)6OYsjL$;YMzI;{8)wZJtZ_}0NC#>fSc)IMUbDEtVt`MP+KN75B2 z!dx23*%{{5ku(L8N4i1iap-yU(&|W>0?8x!Jozr3h~<%V1ac$E1IZ()3*<(U2a-op z7s!ny4H>9t@uk`d=jh;55J^vkPOA;69;wX;ea0r5+D1u@rh9Vdap$Li~D2iezibF9J zhXR742!^64hF}PaASj9;7>eQ$6hROKZ{IP{b^hzp%geiaKRy8TpKn6F!fzKhm_Q5~ zqlY>QzXL2F1u#Pch20jOAqDaS6%=wENC7plG21~0UG(vQrx(AJDIRf$9umZ_eDhLB z0VPmdgnjhz1X;lX1Ds&Hz`;_DP}{gb2Fbw^QxEn&p{}riY%UKL;T&_wX7gYTj4eK1 zVX5}tyob4sZ>tB3kU?w&^I$P#!%eXZ55|sH_z-V#iWWYgj$f-`2MrwI665!Y=E0hf zH<%z^;cl23{&p`HInv_12|6r$nX9+5!aV2;>aFayz2FokF)gXu?0!Sti)2eT0^ z1=EkFAIwIy6ih#welQ!+QZR*RdcpLgDFwTPXh$;;ED$aKU{&-XfI>6_!9x3p<_p(3 zJfevS1kj9TAXpBMSfCg9@G5BII|M-f(L7kdGwyKx+c%7`fB;a4=E0N%qIodI0Jk|r zD}1mPmWscY%lxBR3l?6C8DtGI?18cTqZthr-VR2P91XAq#`2G5JXm-UPICCQWjI1; z7db~W8Z5jT&X7S?@Pt!Tlx~mu!4$TSD@->0%KyoO{kbX{XrsSjSN_z4=|4X4VD=8F zi3hWHNKHJLy+dl^!3+fpMDt*lAMe3Dm9002P#uZ^Ips;a80s;U5PpJ;in0-tyQ0000Y#k z%^I%78OnPu_N*$^=X76TlHOalg^_Q=r9GcBnD=b8Ru43?Id<#anhV`Q53ju2+ZFV% z{qAoeRi}8#bp;Yj4|-U#1xnQf^m(3}Kl|)rlN}o(<$8An^`%a6i_|j;=;cviPF=t= zrO_yW?UaM01`_A?;fTs(lFRQ|Jia2GKBsE=MHQLM>0Ey^xb|hu|9(;A%+~X}Gq~Dr zEj^?#tA#V{)b;}gK=0eXOOuRko_hPYOlWjp# l_dl3_baL{6!z=n1cfbJ`?WFDLCBTSb@O1TaS?83{1OWC!zu*7> literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/round_notifications_white_18.png b/app/src/main/res/drawable-xxhdpi/round_notifications_white_18.png new file mode 100644 index 0000000000000000000000000000000000000000..57b6433bc4f227bb2b7e9c24513f5b2725fd4f1f GIT binary patch literal 355 zcmeAS@N?(olHy`uVBq!ia0vp^W+2SL1|)l2v+go5Flu?aIEGX(zP-xm((EX4{2~8g zgBAk^2?d@+iDL``3I_z7IG7JGFdSx3WRXy4`M}83V!$GCh(VxDogrn}t+!>L?PM70 ze%z0iT_fP+AT0i3QK3#Cvkv2i1C=iW)gyjpHoBcmoNo4dnvB_|n=7uY2tJcz=DK>x z0=an`x7`(g_Cls8fV=-+TCb*5yI5&k`Ty|8UnXq(l2{&h@r>+MhurV)irZto(^T@3Z{(Y3AJ>P{2`A(54;pNI*JuAIr6Z$M@BC94N|+OAxKq|J^$E(wYP2>#u8{ z<;8n&Q$-?KaWi%!d19EteMc0=!Dy@h$a znuXR!^EtEPt5xSEiVJ_vo^tX3`Hi(H|7;U=qq*g-JXZT3{q<)2lje^BwQ?KwbR69E zYC?2&PQs!%=QU3nVy2((7J1_-TO`;e`*vg8Ek4_~h0~5F%5{HcUVSU|%D05-Tj|D+ zYhwFu$-LS9?dPp$3FWUQhR^u0LT;wW#p`zV-qD%MkF%^kZE#R)asuZxeCVt91{PHG zN+qHxltKO0Yn6>cx*MfBrbToDQJZjKjQ1L5f#fw$m+swFQf#sAw8g@J4*1diJxyel987F?A+Y6eZTGM z55N9y`CR6?^zn#EDxPrEq+QX~A8}O6?g6J>-;?wLx%Yqehg(?h^DYpT{+7op?$*S8 zV@rMZESH1s?BBC=)<4+wGgjubW<_S5|FI&jYiHgcj_@nA2y^GkkV|F?a?o5La$yT= zdI9@;nR(_r8iSLonlA5XHNUaRVs?e)#2HP+6^**?`NIDne4i+6Styr$di{6a?;mcT z_}F&8fc)0)Sxev~#H_uHm> zN6ND5$L*3ka+X#*a--6ASc&QHXwtpBxvx0+VbrSiv)4_X_Jg}AIKr@Y{qcv~a*=ZN zy@!S899{PG@{rf)Blw5Mz2EIy3(ple9!c`dn9&q+nx5i*LRn7^`^<+ zf$F9;zshn?DO~?ZJiv{sgGp-v6nQa<2Efso#SKneD;nS^$bmHkhNetpT7+FjL^u?x zXzzttzmu7|mUlprx@(9H1nsn5#$&D%l(xg>sr<>@h%Gglzf$6+AG`8kqs-LXtXq7! zUMxGa(Eo;H4p2%qxRqT@x4uvFaB%ko$#;FJ4cR}$@2AAQu4wgE1}CV@jS<<(m)lCa zKNqIl`f&2m9=Vy$*S+%keWdjwdnC{G_{iV0s_}Q9#;lk0>_d*u%`cqqtYkJf-#h48 zJ~?fN`KB+EGt&N>71pZk=-B=(txep*eA0ZKkMfU&ul?Q7#$VC#8Db46^`3n4mp%69 WvzR8mt(SnAg~8L+&t;ucLK6VifPOpx literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/round_history_edu.png b/app/src/main/res/drawable-xxxhdpi/round_history_edu.png new file mode 100644 index 0000000000000000000000000000000000000000..cd172f6c191b73553044a7360c619bd3126da106 GIT binary patch literal 1326 zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE8Azrw%`pX1hXZ^9H9e*gdeY6+I^-`|TDPd1p%V-Y=l^Wp9DlO04>-+t}PvHbn+e3|g|r~5zaWNV}c zKlVRgA8(@2UhZvk{kgzpchB_~Co(WF-}H2G45?szbFdKf{t`uL%1Y$DGnEN}% zKeT(1fsFxAD{tmDk<&NJj+XeCKmC{g>Wf;Y#o?Gu^V;9rKi%p*^ZrTA+?{7Ew#R%- zQ2X!hF!fOGj1&67Yh@)erg!B!@3qYmtGbXke^uy$x!zY#{V2N{wf9oSH2ypGTJmyJ z`=WFIh?f?BT$^=!uHOBZ)6<@&pXX>0xNi53|A*(p0+Vz43(RM-{n>SM#a!m~LIcSc>dAIpm`B^|gKc1>DDC0_oVa}@6n$0*(%3+^)fzf^QU z)HrL4qJv9lqg}#@{_fx1udkhb`}S?*>QMc!j{|}gSbcuheT-e*<+AtMA{h>rXYo$& z{z}N3$Q`v}(tObP-lYDB`rEfGTuhn=-mlYd*euP#V#Qz+pm5-3fWigF1Vy2QB29r6 z3<4)v-Y#=cV0gi4z{SGE=-~gsLV$yX!S>+Ir9e>+)`h>-);!Z?1xpH?rr!|)@d=)?b8&kch` za)l=3NXEXgWp4PqL8IL#e2Q?xo)cvZ%C{MN-Z0we+6zQ5Rakuv;`+kKz3%=e9uLh6 z><>&H%-UPwkkx3%5MI3QYNDtB#}|fzq-FXMKN=hsa605q&n%W_tWkXNBdB4|t)5J- zcdLNn{0;U0j_A*}VsK%qWw@~W-KWh>=j0eRI>Pt7rpL00Wl;JZUk$aZ zLJZjoRtDXaXt3J3jX8qhUpS)%1M30?kp{!?-DhkM9QHC@w{2>*gRFMwj$0<*8$LbX zZfah{|A6)1bu(ezPy93HKfE8sDE#+~eZ%MO{`Fk5e~U4kD7wp>*PnbfbK)Hj;goB_ z<`))po$1=y_-2-(S=JT$7XG0OeSYPuu4uG=qvl28IVL@&SCB?>wG91Mxgv{an^LB{Ts5>=NR` literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/round_history_edu_black_18.png b/app/src/main/res/drawable-xxxhdpi/round_history_edu_black_18.png new file mode 100644 index 0000000000000000000000000000000000000000..42c946b7af99f4a6c659db7b5f2477173e469b6b GIT binary patch literal 604 zcmV-i0;BzjP)kS z{y%JiLgXkmu*3)6OYsjL$;YMzI;{8)wZJtZ_}0NC#>fSc)IMUbDEtVt`MP+KN75B2 z!dx23*%{{5ku(L8N4i1iap-yU(&|W>0?8x!Jozr3h~<%V1ac$E1IZ()3*<(U2a-op z7s!ny4H>9t@uk`d=jh;55J^vkPOAU^?XK;uuoF`1THCigcjN@sEle ze2#)Fu7V6A&V?dJ1$Y8@Tp5otxCZhZUZ~NvNTMrAf{lZXqiGRG*CGoR#}D_*B|=}V z-+5>EcfI}k@(vw;p4@5vzHs4`ATQ0O2!d_LArY~ioLpZnbZrYfBxIa@nxlM!i)hCp z#v++Vr@7lt7#@h8y1~U)U=Lr>oa7!$o_UtXezeKR{y8lqzDAMD=HRsllHyVa^2O~F zg~}Qj>kg>=VQAM#6wKK5;Qo7#YdpLY5*fQa>L;`P;E6uS6ny95uU2ax?Y^r1f6I6Z z7?@-DEso3W`f!d*#O|auzq5MydXDgN} zJ>ZCqakFW%)R-tZr*A_~0ZVa!jIvGgGmDS+4=s{DC?j&7W1ew9kn#*=57z^XNkEZ< zT1X~~AdRci^*fp`O(D}n5bznQsm$E5W7>;jX zcqYMG!X7z52{kY*$6sbLsh}2Y$KTaBq`yn{iOaU21`) zcaGw&c?r@Fm;%d~vv*ql>ey7nEN44kpmh6&X;zM3Qg`G(Oiph}ITiKAf5$PtNjk@U olk(mBB_4m-Yrh9IZC!~MPn&7E)U6^UsEj~C3${J)z^ zU8;P}Hr=T@&*#+LZ_;-A`0u>U`Ogp(^wLL6@YGZ8Lu(?Oo}3bW7|ObE)`eBgLCz7W z4l6a^ueY{j3-jAdzfB8HJ!F~BdF9+E^;Om9chtU^#CrAPPKT+6ho*G#UU6Kp zOw;JZz2I;rhDQ}#^8x)h8mPG%%*vV=Y$JExr z926>8GI!F|ysQf|mFzgeuUCIseJV^?%h`pUHFf#ky8ZL_&pqJLc|yV1d5Vok_as(b zc5i1FmbZ_5=gv93Q&FiYrNO+UR57Vzg~Cm#$6L>JDYbR*OgbAq!?!FL$mE+8Qkzqe z*Z%6IN2i6t)y)6#OYThDXMaga%wsZ}<(>e?kZB&xi^___rJYqj?dsqTx-0%H*7Rby z>&B)xomqjO6m-4hmbjj5-l9=CK}?nZ(xNAhQ9yS*RbaR5_-#M+*W@mSNB{go*IjT7 zby;VEpUp;uuoF`1TH?OKhUV@rUAx z9EXn@@EkT^X;4hyP~=JEaOPlUXaO@C5;+uG5*q{#6&SWCwlsIAHzWjauYNtJ_}za- zhCTK*$6wdPyShNY^hC~Ri=z_h76+WZ};sLKe^`Y z*!_6c`U6vUOJA>P)eKcRkdTm4bz0Pzzm{8l#*Db;_cwfcG#{|?85-L2e*3uP(fto1 z^Dk6bg#YMJ7d8LDHeK$#Wn5@TqHyo=@9e9$p4hNDRyZeh`{lZptx+l!-JS1t9D5zb zQqh@x*Z7!*_1`ktD-#l(xBG4ga&A%ovGliJcE^Ub_Sdp93YOXLyE-Akb-#(k)qn?^ z|J_`-@W9f4KLec`p8r~TFlgW3+gpQb+il;Tv}{QJ`*rCrzURMQulU86{PtuNQ}4fB zEB0N^f6S5*$)w`I^d$;JqN4MtT#)P&tt{>`qdzVg7tttPki|{^bGs7!iVqtHij5}=Wx&4{{O?_^D_%Nyv>hU g9PolfQpuh8wA%TrO|Noa0Hy~9Pgg&ebxsLQ07{GeIRF3v literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/round_notifications_white_18.png b/app/src/main/res/drawable-xxxhdpi/round_notifications_white_18.png new file mode 100644 index 0000000000000000000000000000000000000000..45058bb70c17de663c921743ed34e5453842cd11 GIT binary patch literal 447 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@Zgyv2U~KbraSW+oe0z;CB|1=~;bHRv zjkZJy1&M?PMUBG-BCZSv8C(T;1X!F6d6;<)3-B;I7#Y#k z%^I%78OnPu_N*$^=X76TlHOalg^_Q=r9GcBnD=b8Ru43?Id<#anhV`Q53ju2+ZFV% z{qAoeRi}8#bp;Yj4|-U#1xnQf^m(3}Kl|)rlN}o(<$8An^`%a6i_|j;=;cviPF=t= zrO_yW?UaM01`_A?;fTs(lFRQ|Jia2GKBsE=MHQLM>0Ey^xb|hu|9(;A%+~X}Gq~Dr zEj^?#tA#V{)b;}gK=0eXOOuRko_hPYOlWjp# l_dl3_baL{6!z=n1cfbJ`?WFDLCBTSb@O1TaS?83{1OWC!zu*7> literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/round_notifications_white_36.png b/app/src/main/res/drawable-xxxhdpi/round_notifications_white_36.png new file mode 100644 index 0000000000000000000000000000000000000000..e3ec74fd9af36b4c67258ce1382368d095f121e0 GIT binary patch literal 851 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q4M;wBd$farfmzDa#WAFU@$KEl_NkFF4G)`L zIl2W7DYXbVaWHlZh$(^?iY*%=Sb(H}Qv?u8v@J4*1diJxyel987F?A+Y6eZTGM z55N9y`CR6?^zn#EDxPrEq+QX~A8}O6?g6J>-;?wLx%Yqehg(?h^DYpT{+7op?$*S8 zV@rMZESH1s?BBC=)<4+wGgjubW<_S5|FI&jYiHgcj_@nA2y^GkkV|F?a?o5La$yT= zdI9@;nR(_r8iSLonlA5XHNUaRVs?e)#2HP+6^**?`NIDne4i+6Styr$di{6a?;mcT z_}F&8fc)0)Sxev~#H_uHm> zN6ND5$L*3ka+X#*a--6ASc&QHXwtpBxvx0+VbrSiv)4_X_Jg}AIKr@Y{qcv~a*=ZN zy@!S899{PG@{rf)Blw5Mz2EIy3(ple9!c`dn9&q+nx5i*LRn7^`^<+ zf$F9;zshn?DO~?ZJiv{sgGp-v6nQa<2Efso#SKneD;nS^$bmHkhNetpT7+FjL^u?x zXzzttzmu7|mUlprx@(9H1nsn5#$&D%l(xg>sr<>@h%Gglzf$6+AG`8kqs-LXtXq7! zUMxGa(Eo;H4p2%qxRqT@x4uvFaB%ko$#;FJ4cR}$@2AAQu4wgE1}CV@jS<<(m)lCa zKNqIl`f&2m9=Vy$*S+%keWdjwdnC{G_{iV0s_}Q9#;lk0>_d*u%`cqqtYkJf-#h48 zJ~?fN`KB+EGt&N>71pZk=-B=(txep*eA0ZKkMfU&ul?Q7#$VC#8Db46^`3n4mp%69 WvzR8mt(SnAg~8L+&t;ucLK6VifPOpx literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/round_notifications_white_48.png b/app/src/main/res/drawable-xxxhdpi/round_notifications_white_48.png new file mode 100644 index 0000000000000000000000000000000000000000..4fdeb5723391e6e6f07cd3bc87ee765f7214624d GIT binary patch literal 1045 zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE8Azrw%`pX1djotzT!HleAq%>y_vHXRU|$mC z7tA1%y!!b4!;7PNBqsm<|Gi$o`}1>){9u2T`PGj(*0aoh-5h_}-QoOpozn&;;nT}C zZts6zoZhamdvkwx_H`SXp2=MM7#NsNc)B=-R4~51!#e4)gMiCLlgXD9`e(M^H0b%h z|EkgYH;SR#wHDpu{MEfNvB&V3L^6<=abxMFnK^pX^+midtcc` zzrdt(fGI>nbf;VTio`FAwXSn<&t16bqPvO7F^^@RmYfQodG3|RyhPn6t4%K_tDO1P zkiThjx5~}i&u7cZC~11J?sGSAHk#7^!*8aL(1VHt<21i zpABL*R?m;K?*6b$(17is%siR4o})^v`a#^sQY_opAFC!CH?oT!)8KvXC$T*A)c?=^ zsnQoUAB)NyUYXcu7_GI7rR!Ro^V10%qj?_s^)u-`@Y(CdXlYUGDOg>g>Mdw%VYIww z1B>}OjTC9W9(IvUEyBA+ih0GkL@u{;b9e1*WY#s7ldsqr_FD0Jih#mZB>x7P2N`aI~ON=A6e|^zw6OtkBpy_{!X!DX=f05&*~^; zxGMDJja9u7Q{VSFSs9<5cO8^aDh`}w^Vp?keoE=(x1AR`Jf}Z&3-{QiWM1WT=_+&H z1(#2~I}XZD%9krx8!F57Wydv3lNI_;o?n}4$}g!oy-CP_B5Skdl^Oa!=GRDeEm33q zA2hdj;pv($?oM07+w4{*rS13R>#Lfp2u+e|W%C(@#Db+>IkM~qW)B8WS3j3^P6 + + diff --git a/app/src/main/res/drawable/round_notifications_24.xml b/app/src/main/res/drawable/round_notifications_24.xml new file mode 100644 index 0000000..1ccc080 --- /dev/null +++ b/app/src/main/res/drawable/round_notifications_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/fragment_glance_settings.xml b/app/src/main/res/layout/fragment_glance_settings.xml index 987e8f3..784944e 100644 --- a/app/src/main/res/layout/fragment_glance_settings.xml +++ b/app/src/main/res/layout/fragment_glance_settings.xml @@ -96,7 +96,8 @@ android:textAppearance="@style/AnotherWidget.Settings.Header"/> + app:cardCornerRadius="8dp"> + + \ No newline at end of file diff --git a/app/src/main/res/layout/glance_provider_settings_layout.xml b/app/src/main/res/layout/glance_provider_settings_layout.xml index f3445fb..895c8bd 100644 --- a/app/src/main/res/layout/glance_provider_settings_layout.xml +++ b/app/src/main/res/layout/glance_provider_settings_layout.xml @@ -173,6 +173,72 @@ style="@style/AnotherWidget.Settings.Subtitle"/> + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 3ad6bbe..181eff5 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -127,7 +127,7 @@ Der kan gå op til 10 minutter inden din API nøgle er aktiveret. Vejret vil blive opdateret så snart det er tilgængeligt. Ikonpakke Ikonpakke %d - Vi indsamler placeringsdata for at opdatere vejrinformationer, selv når app'en er lukket eller ikke er i brug.\nVi bruger ikke disse data på andre måder. + Vi indsamler placeringsdata for at opdatere vejrinformationer, selv når app\'en er lukket eller ikke er i brug.\nVi bruger ikke disse data på andre måder. Vejrudbyder Open Weather Map @@ -188,7 +188,6 @@ Vis næste alarm - Den næste alarm lader til at være forkert.\nDen er indstillet af %s. Overblik Aktuel sang Vi har brug for tilladelse til aflæsning af notifikationer, for at vise den aktuelle sang. diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index f74b707..82d47da 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -179,6 +179,7 @@ Glance Canzone in riproduzione È necessario l\'accesso alle notifiche per controllare la canzone in riproduzione. + È necessario l\'accesso alle notifiche per mostrare le ultime che ti sono arrivate. Sono necessari i permessi per accedere ai passi di oggi su Google Fit. Mostra At a Glance Informazioni visibili diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 84ed6d0..38b7a9a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -191,6 +191,7 @@ Glance Current playing song We need the notification access permission to check the current playing song. + We need the notification access permission to check your last notifications. We need a few permissions to get your daily steps from Google Fit. Show at a glance info Service enabled @@ -215,6 +216,10 @@ Alarm set by %s The next alarm clock seems to be wrong. The next alarm clock seems to be correct. + Last notifications + Take a quick view of the last notifications showed up on your device. + Greetings + View some cool phrase when you don\'t expect it. Share