From 0a0c5a90a72a0834e981db9f5eccf33347a0c9ac Mon Sep 17 00:00:00 2001 From: Tommaso Berlose Date: Tue, 13 Oct 2020 16:55:42 +0200 Subject: [PATCH] Update the glance section --- app/src/main/AndroidManifest.xml | 2 +- .../components/GlanceProviderSortMenu.kt | 98 ----- .../components/GlanceSettingsDialog.kt | 229 +++++++++++ .../anotherwidget/global/Constants.kt | 7 +- .../anotherwidget/global/Preferences.kt | 1 + .../helpers/ActiveNotificationsHelper.kt | 19 + .../helpers/GlanceProviderHelper.kt | 8 +- .../helpers/MediaPlayerHelper.kt | 7 +- ...ionListener.kt => NotificationListener.kt} | 10 +- .../ui/fragments/GlanceTabFragment.kt | 382 +++++++----------- .../drawable-hdpi/round_arrow_circle_down.png | Bin 0 -> 536 bytes .../round_arrow_circle_down_white_18.png | Bin 0 -> 466 bytes .../round_arrow_circle_down_white_36.png | Bin 0 -> 778 bytes .../round_arrow_circle_down_white_48.png | Bin 0 -> 1005 bytes .../main/res/drawable-hdpi/round_outbond.png | Bin 0 -> 327 bytes .../drawable-hdpi/round_outbond_white_24.png | Bin 0 -> 389 bytes .../drawable-hdpi/round_outbond_white_36.png | Bin 0 -> 554 bytes .../drawable-hdpi/round_outbond_white_48.png | Bin 0 -> 708 bytes .../drawable-mdpi/round_arrow_circle_down.png | Bin 0 -> 379 bytes .../round_arrow_circle_down_white_18.png | Bin 0 -> 271 bytes .../round_arrow_circle_down_white_36.png | Bin 0 -> 536 bytes .../round_arrow_circle_down_white_48.png | Bin 0 -> 707 bytes .../main/res/drawable-mdpi/round_outbond.png | Bin 0 -> 246 bytes .../drawable-mdpi/round_outbond_white_24.png | Bin 0 -> 282 bytes .../drawable-mdpi/round_outbond_white_36.png | Bin 0 -> 389 bytes .../drawable-mdpi/round_outbond_white_48.png | Bin 0 -> 501 bytes .../round_arrow_circle_down.png | Bin 0 -> 707 bytes .../round_arrow_circle_down_white_18.png | Bin 0 -> 536 bytes .../round_arrow_circle_down_white_36.png | Bin 0 -> 1005 bytes .../round_arrow_circle_down_white_48.png | Bin 0 -> 1267 bytes .../main/res/drawable-xhdpi/round_outbond.png | Bin 0 -> 389 bytes .../drawable-xhdpi/round_outbond_white_24.png | Bin 0 -> 501 bytes .../drawable-xhdpi/round_outbond_white_36.png | Bin 0 -> 708 bytes .../drawable-xhdpi/round_outbond_white_48.png | Bin 0 -> 930 bytes .../round_arrow_circle_down.png | Bin 0 -> 1005 bytes .../round_arrow_circle_down_white_18.png | Bin 0 -> 778 bytes .../round_arrow_circle_down_white_36.png | Bin 0 -> 1369 bytes .../round_arrow_circle_down_white_48.png | Bin 0 -> 1759 bytes .../res/drawable-xxhdpi/round_outbond.png | Bin 0 -> 554 bytes .../round_outbond_white_24.png | Bin 0 -> 708 bytes .../round_outbond_white_36.png | Bin 0 -> 1028 bytes .../round_outbond_white_48.png | Bin 0 -> 1302 bytes .../round_arrow_circle_down.png | Bin 0 -> 1267 bytes .../round_arrow_circle_down_white_18.png | Bin 0 -> 1005 bytes .../round_arrow_circle_down_white_36.png | Bin 0 -> 1759 bytes .../round_arrow_circle_down_white_48.png | Bin 0 -> 2246 bytes .../res/drawable-xxxhdpi/round_outbond.png | Bin 0 -> 708 bytes .../round_outbond_white_24.png | Bin 0 -> 930 bytes .../round_outbond_white_36.png | Bin 0 -> 1302 bytes .../round_outbond_white_48.png | Bin 0 -> 1614 bytes .../drawable/round_arrow_circle_down_24.xml | 10 + .../main/res/drawable/round_outbond_24.xml | 10 + .../res/layout/fragment_glance_settings.xml | 314 +------------- .../main/res/layout/glance_provider_item.xml | 37 +- .../glance_provider_settings_layout.xml | 178 ++++++++ .../glance_provider_sort_bottom_menu.xml | 41 -- .../weather_provider_settings_layout.xml | 2 +- app/src/main/res/values-it/strings.xml | 8 +- app/src/main/res/values/colors.xml | 1 + app/src/main/res/values/strings.xml | 10 +- 60 files changed, 665 insertions(+), 709 deletions(-) delete mode 100644 app/src/main/java/com/tommasoberlose/anotherwidget/components/GlanceProviderSortMenu.kt create mode 100644 app/src/main/java/com/tommasoberlose/anotherwidget/components/GlanceSettingsDialog.kt create mode 100644 app/src/main/java/com/tommasoberlose/anotherwidget/helpers/ActiveNotificationsHelper.kt rename app/src/main/java/com/tommasoberlose/anotherwidget/receivers/{MusicNotificationListener.kt => NotificationListener.kt} (77%) create mode 100644 app/src/main/res/drawable-hdpi/round_arrow_circle_down.png create mode 100644 app/src/main/res/drawable-hdpi/round_arrow_circle_down_white_18.png create mode 100644 app/src/main/res/drawable-hdpi/round_arrow_circle_down_white_36.png create mode 100644 app/src/main/res/drawable-hdpi/round_arrow_circle_down_white_48.png create mode 100644 app/src/main/res/drawable-hdpi/round_outbond.png create mode 100644 app/src/main/res/drawable-hdpi/round_outbond_white_24.png create mode 100644 app/src/main/res/drawable-hdpi/round_outbond_white_36.png create mode 100644 app/src/main/res/drawable-hdpi/round_outbond_white_48.png create mode 100644 app/src/main/res/drawable-mdpi/round_arrow_circle_down.png create mode 100644 app/src/main/res/drawable-mdpi/round_arrow_circle_down_white_18.png create mode 100644 app/src/main/res/drawable-mdpi/round_arrow_circle_down_white_36.png create mode 100644 app/src/main/res/drawable-mdpi/round_arrow_circle_down_white_48.png create mode 100644 app/src/main/res/drawable-mdpi/round_outbond.png create mode 100644 app/src/main/res/drawable-mdpi/round_outbond_white_24.png create mode 100644 app/src/main/res/drawable-mdpi/round_outbond_white_36.png create mode 100644 app/src/main/res/drawable-mdpi/round_outbond_white_48.png create mode 100644 app/src/main/res/drawable-xhdpi/round_arrow_circle_down.png create mode 100644 app/src/main/res/drawable-xhdpi/round_arrow_circle_down_white_18.png create mode 100644 app/src/main/res/drawable-xhdpi/round_arrow_circle_down_white_36.png create mode 100644 app/src/main/res/drawable-xhdpi/round_arrow_circle_down_white_48.png create mode 100644 app/src/main/res/drawable-xhdpi/round_outbond.png create mode 100644 app/src/main/res/drawable-xhdpi/round_outbond_white_24.png create mode 100644 app/src/main/res/drawable-xhdpi/round_outbond_white_36.png create mode 100644 app/src/main/res/drawable-xhdpi/round_outbond_white_48.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_arrow_circle_down.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_arrow_circle_down_white_18.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_arrow_circle_down_white_36.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_arrow_circle_down_white_48.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_outbond.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_outbond_white_24.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_outbond_white_36.png create mode 100644 app/src/main/res/drawable-xxhdpi/round_outbond_white_48.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_arrow_circle_down.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_arrow_circle_down_white_18.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_arrow_circle_down_white_36.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_arrow_circle_down_white_48.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_outbond.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_outbond_white_24.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_outbond_white_36.png create mode 100644 app/src/main/res/drawable-xxxhdpi/round_outbond_white_48.png create mode 100644 app/src/main/res/drawable/round_arrow_circle_down_24.xml create mode 100644 app/src/main/res/drawable/round_outbond_24.xml create mode 100644 app/src/main/res/layout/glance_provider_settings_layout.xml delete mode 100644 app/src/main/res/layout/glance_provider_sort_bottom_menu.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b6b658c..ed5a2ee 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -120,7 +120,7 @@ - diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/components/GlanceProviderSortMenu.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/components/GlanceProviderSortMenu.kt deleted file mode 100644 index 27a431c..0000000 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/components/GlanceProviderSortMenu.kt +++ /dev/null @@ -1,98 +0,0 @@ -package com.tommasoberlose.anotherwidget.components - -import android.content.Context -import android.content.res.ColorStateList -import android.view.View -import android.widget.ImageView -import android.widget.TextView -import androidx.appcompat.widget.AppCompatImageView -import androidx.core.content.ContextCompat -import androidx.core.view.isVisible -import androidx.recyclerview.widget.GridLayoutManager -import androidx.recyclerview.widget.ItemTouchHelper -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import com.google.android.material.bottomsheet.BottomSheetBehavior -import com.google.android.material.bottomsheet.BottomSheetDialog -import com.google.android.material.card.MaterialCardView -import com.tommasoberlose.anotherwidget.R -import com.tommasoberlose.anotherwidget.global.Constants -import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark -import com.tommasoberlose.anotherwidget.helpers.GlanceProviderHelper -import com.tommasoberlose.anotherwidget.models.GlanceProvider -import kotlinx.android.synthetic.main.glance_provider_sort_bottom_menu.view.* -import kotlinx.coroutines.* -import net.idik.lib.slimadapter.SlimAdapter -import java.util.* -import kotlin.collections.ArrayList - -class GlanceProviderSortMenu( - context: Context -) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) { - - private lateinit var adapter: SlimAdapter - - override fun show() { - val view = View.inflate(context, R.layout.glance_provider_sort_bottom_menu, null) - - // Header - view.header_text.text = context.getString(R.string.settings_sort_glance_providers_title) - - // List - adapter = SlimAdapter.create() - - view.menu.setHasFixedSize(true) - val mLayoutManager = LinearLayoutManager(context) - view.menu.layoutManager = mLayoutManager - - adapter = SlimAdapter.create() - adapter - .register(R.layout.glance_provider_item) { item, injector -> - injector - .text(R.id.title, item.title) - .with(R.id.icon) { - it.setImageDrawable(ContextCompat.getDrawable(context, item.icon)) - } - } - .attachTo(view.menu) - - val mIth = ItemTouchHelper( - object : ItemTouchHelper.SimpleCallback( - ItemTouchHelper.UP or ItemTouchHelper.DOWN, - ItemTouchHelper.LEFT - ) { - override fun onMove( - recyclerView: RecyclerView, - 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(context) - Collections.swap(list, fromPos, toPos) - GlanceProviderHelper.saveGlanceProviderOrder(list) - return true - } - - override fun onSwiped( - viewHolder: RecyclerView.ViewHolder, - direction: Int - ) { - // remove from adapter - } - }) - - mIth.attachToRecyclerView(view.menu) - - adapter.updateData( - GlanceProviderHelper.getGlanceProviders(context) - .mapNotNull { GlanceProviderHelper.getGlanceProviderById(context, it) } - ) - - setContentView(view) - super.show() - } -} - diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/components/GlanceSettingsDialog.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/components/GlanceSettingsDialog.kt new file mode 100644 index 0000000..8ed3a9d --- /dev/null +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/components/GlanceSettingsDialog.kt @@ -0,0 +1,229 @@ +package com.tommasoberlose.anotherwidget.components + +import android.Manifest +import android.app.Activity +import android.app.AlarmManager +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 +import androidx.core.view.isVisible +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.material.bottomsheet.BottomSheetDialog +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.tommasoberlose.anotherwidget.R +import com.tommasoberlose.anotherwidget.global.Constants +import com.tommasoberlose.anotherwidget.global.Preferences +import com.tommasoberlose.anotherwidget.helpers.AlarmHelper +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) { + + override fun show() { + val view = View.inflate(context, R.layout.glance_provider_settings_layout, null) + + /* TITLE */ + view.title.text = when (provider) { + Constants.GlanceProviderId.PLAYING_SONG -> context.getString(R.string.settings_show_music_title) + Constants.GlanceProviderId.NEXT_CLOCK_ALARM -> context.getString(R.string.settings_show_next_alarm_title) + 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) + } + + /* SUBTITLE*/ + view.subtitle.text = when (provider) { + Constants.GlanceProviderId.PLAYING_SONG -> context.getString(R.string.settings_show_music_subtitle) + Constants.GlanceProviderId.NEXT_CLOCK_ALARM -> context.getString(R.string.settings_show_next_alarm_subtitle) + 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) + } + + /* 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) { + checkNotificationPermission(view) + } + + /* ALARM */ + 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 */ + 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.divider.isVisible = false + } + + /* CUSTOM NOTES */ + view.subtitle.isVisible = provider != Constants.GlanceProviderId.CUSTOM_INFO + view.provider_switch.isVisible = provider != Constants.GlanceProviderId.CUSTOM_INFO + + /* TOGGLE */ + view.provider_switch.isChecked = when (provider) { + Constants.GlanceProviderId.PLAYING_SONG -> Preferences.showMusic + Constants.GlanceProviderId.NEXT_CLOCK_ALARM -> Preferences.showNextAlarm + Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> Preferences.showBatteryCharging + Constants.GlanceProviderId.CUSTOM_INFO -> true + Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> Preferences.showDailySteps + } + + view.provider_switch.setOnCheckedChangeListener { _, isChecked -> + when (provider) { + Constants.GlanceProviderId.PLAYING_SONG -> { + Preferences.showMusic = isChecked + checkNotificationPermission(view) + } + Constants.GlanceProviderId.NEXT_CLOCK_ALARM -> { + Preferences.showNextAlarm = isChecked + checkNextAlarm(view) + } + Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> { + Preferences.showBatteryCharging = isChecked + } + Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> { + if (isChecked) { + val account: GoogleSignInAccount? = GoogleSignIn.getLastSignedInAccount(context) + if (!GoogleSignIn.hasPermissions(account, + ActivityDetectionReceiver.FITNESS_OPTIONS + )) { + val mGoogleSignInClient = GoogleSignIn.getClient(context, GoogleSignInOptions.Builder( + GoogleSignInOptions.DEFAULT_SIGN_IN).addExtension( + ActivityDetectionReceiver.FITNESS_OPTIONS + ).build()) + context.startActivityForResult(mGoogleSignInClient.signInIntent, 2) + } else { + Preferences.showDailySteps = true + } + } else { + Preferences.showDailySteps = false + } + checkFitnessPermission(view) + } + else -> {} + } + statusCallback?.invoke() + } + + setContentView(view) + super.show() + } + + private fun checkNextAlarm(view: View) { + with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) { + val alarm = nextAlarmClock + if (alarm != null && alarm.showIntent != null) { + val pm = context.packageManager as PackageManager + val appNameOrPackage = try { + pm.getApplicationLabel(pm.getApplicationInfo(alarm.showIntent?.creatorPackage ?: "", 0)) + } catch (e: Exception) { + alarm.showIntent?.creatorPackage ?: "" + } + view.alarm_set_by_title.text = context.getString(R.string.settings_show_next_alarm_app_title).format(appNameOrPackage) + view.alarm_set_by_subtitle.text = if (AlarmHelper.isAlarmProbablyWrong(context)) context.getString(R.string.settings_show_next_alarm_app_subtitle_wrong) else context.getString(R.string.settings_show_next_alarm_app_subtitle_correct) + view.alarm_set_by_title.isVisible = true + } else { + view.alarm_set_by_title.isVisible = false + } + } + statusCallback?.invoke() + } + + private fun checkNotificationPermission(view: View) { + when { + NotificationManagerCompat.getEnabledListenerPackages(context).contains(context.packageName) -> { + view.warning_container.isVisible = false + MediaPlayerHelper.updatePlayingMediaInfo(context) + } + Preferences.showMusic -> { + view.warning_container.isVisible = true + view.warning_title.text = context.getString(R.string.settings_request_notification_access) + 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 checkFitnessPermission(view: View) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || context.checkGrantedPermission( + Manifest.permission.ACTIVITY_RECOGNITION) + ) { + view.warning_container.isVisible = false + if (Preferences.showDailySteps) { + ActivityDetectionReceiver.registerFence(context) + } else { + ActivityDetectionReceiver.unregisterFence(context) + } + } else if (Preferences.showDailySteps) { + ActivityDetectionReceiver.unregisterFence(context) + view.warning_container.isVisible = true + view.warning_title.text = context.getString(R.string.settings_request_fitness_access) + view.warning_container.setOnClickListener { + requireFitnessPermission(view) + } + } else { + ActivityDetectionReceiver.unregisterFence(context) + view.warning_container.isVisible = false + } + statusCallback?.invoke() + } + + private fun requireFitnessPermission(view: View) { + Dexter.withContext(context) + .withPermissions( + "com.google.android.gms.permission.ACTIVITY_RECOGNITION", + "android.gms.permission.ACTIVITY_RECOGNITION", + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACTIVITY_RECOGNITION else "com.google.android.gms.permission.ACTIVITY_RECOGNITION" + ).withListener(object: MultiplePermissionsListener { + override fun onPermissionsChecked(report: MultiplePermissionsReport?) { + checkFitnessPermission(view) + } + override fun onPermissionRationaleShouldBeShown( + permissions: MutableList?, + token: PermissionToken? + ) { + // Remember to invoke this method when the custom rationale is closed + // or just by default if you don't want to use any custom rationale. + token?.continuePermissionRequest() + } + }) + .check() + } +} \ 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 75b5dd5..9aff1ec 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,12 @@ 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"); + + companion object { + private val map = GlanceProviderId.values().associateBy(GlanceProviderId::id) + fun from(type: String) = map[type] + } } enum class WidgetUpdateFrequency(val value: Int) { 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 90c2a71..0de6864 100755 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/global/Preferences.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/global/Preferences.kt @@ -123,6 +123,7 @@ object Preferences : KotprefModel() { var isCharging by booleanPref(default = false) var googleFitSteps by longPref(default = -1) var showDailySteps by booleanPref(default = false) + var showNotifications by booleanPref(default = false) var showMusic by booleanPref(default = false) var mediaInfoFormat 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 new file mode 100644 index 0000000..4a9da77 --- /dev/null +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/ActiveNotificationsHelper.kt @@ -0,0 +1,19 @@ +package com.tommasoberlose.anotherwidget.helpers + +import android.app.NotificationManager +import android.content.Context +import android.service.notification.StatusBarNotification +import android.util.Log +import com.google.gson.Gson + +object ActiveNotificationsHelper { + fun getLastNotification(context: Context): StatusBarNotification? { + with(context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager) { + activeNotifications.forEach { + Log.d("ciao", Gson().toJson(it).toString()) + } + + return activeNotifications.lastOrNull() + } + } +} \ 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 9ba8763..a9f8436 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/GlanceProviderHelper.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/GlanceProviderHelper.kt @@ -82,13 +82,15 @@ object GlanceProviderHelper { val eventRepository = EventRepository(context) BatteryHelper.updateBatteryInfo(context) - val showGlance = Preferences.showGlance && (eventRepository.getEventsCount() == 0 || !Preferences.showEvents) && ( + val showGlance = Preferences.showGlance && (eventRepository.getEventsCount() == 0 || !Preferences.showEvents) + && ( (Preferences.showNextAlarm && AlarmHelper.getNextAlarm(context) != "") || (MediaPlayerHelper.isSomeonePlaying(context)) || (Preferences.showBatteryCharging && Preferences.isCharging || Preferences.isBatteryLevelLow) || (Preferences.customNotes.isNotEmpty()) || - (Preferences.showDailySteps && Preferences.googleFitSteps > 0) - ) + (Preferences.showDailySteps && Preferences.googleFitSteps > 0) || + (Preferences.showNotifications && ActiveNotificationsHelper.getLastNotification(context) != null) + ) eventRepository.close() return showGlance } diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/MediaPlayerHelper.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/MediaPlayerHelper.kt index d749e9f..1b63b19 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/MediaPlayerHelper.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/helpers/MediaPlayerHelper.kt @@ -1,20 +1,17 @@ package com.tommasoberlose.anotherwidget.helpers -import android.app.Notification import android.content.ComponentName import android.content.Context import android.media.MediaMetadata import android.media.session.MediaController -import android.media.session.MediaSession import android.media.session.MediaSessionManager import android.media.session.PlaybackState -import android.util.Log import androidx.core.app.NotificationManagerCompat import com.chibatching.kotpref.Kotpref import com.chibatching.kotpref.blockingBulk import com.chibatching.kotpref.bulk import com.tommasoberlose.anotherwidget.global.Preferences -import com.tommasoberlose.anotherwidget.receivers.MusicNotificationListener +import com.tommasoberlose.anotherwidget.receivers.NotificationListener import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget import java.lang.Exception @@ -34,7 +31,7 @@ object MediaPlayerHelper { if (NotificationManagerCompat.getEnabledListenerPackages(context).contains(context.packageName)) { val list = try { (context.getSystemService(Context.MEDIA_SESSION_SERVICE) as MediaSessionManager).getActiveSessions( - ComponentName(context.packageName, MusicNotificationListener::class.java.name) + ComponentName(context.packageName, NotificationListener::class.java.name) ) } catch (ex: Exception) { emptyList() diff --git a/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/MusicNotificationListener.kt b/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/NotificationListener.kt similarity index 77% rename from app/src/main/java/com/tommasoberlose/anotherwidget/receivers/MusicNotificationListener.kt rename to app/src/main/java/com/tommasoberlose/anotherwidget/receivers/NotificationListener.kt index 8780339..e77a428 100644 --- a/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/MusicNotificationListener.kt +++ b/app/src/main/java/com/tommasoberlose/anotherwidget/receivers/NotificationListener.kt @@ -9,15 +9,17 @@ 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.Preferences import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper import com.tommasoberlose.anotherwidget.helpers.WidgetHelper import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget -class MusicNotificationListener : NotificationListenerService() { +class NotificationListener : NotificationListenerService() { override fun onListenerConnected() { MediaPlayerHelper.updatePlayingMediaInfo(this) + MainWidget.updateWidget(this) super.onListenerConnected() } @@ -27,11 +29,17 @@ class MusicNotificationListener : NotificationListenerService() { MediaPlayerHelper.updatePlayingMediaInfo(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) + MainWidget.updateWidget(this) super.onNotificationRemoved(sbn) } } \ No newline at end of file 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 df8053a..669c662 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 @@ -16,13 +16,18 @@ 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.databinding.DataBindingUtil import androidx.fragment.app.Fragment import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope +import androidx.recyclerview.widget.ItemTouchHelper +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 @@ -33,14 +38,14 @@ import com.karumi.dexter.PermissionToken import com.karumi.dexter.listener.PermissionRequest import com.karumi.dexter.listener.multi.MultiplePermissionsListener import com.tommasoberlose.anotherwidget.R -import com.tommasoberlose.anotherwidget.components.BottomSheetMenu -import com.tommasoberlose.anotherwidget.components.CustomNotesDialog -import com.tommasoberlose.anotherwidget.components.GlanceProviderSortMenu -import com.tommasoberlose.anotherwidget.components.MaterialBottomSheetDialog +import com.tommasoberlose.anotherwidget.components.* import com.tommasoberlose.anotherwidget.databinding.FragmentGlanceSettingsBinding +import com.tommasoberlose.anotherwidget.global.Constants import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.helpers.AlarmHelper +import com.tommasoberlose.anotherwidget.helpers.GlanceProviderHelper import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper +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 @@ -54,6 +59,8 @@ 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 +import java.util.* class GlanceTabFragment : Fragment() { @@ -62,6 +69,8 @@ class GlanceTabFragment : Fragment() { fun newInstance() = GlanceTabFragment() } + private var dialog: GlanceSettingsDialog? = null + private lateinit var adapter: SlimAdapter private lateinit var viewModel: MainViewModel override fun onCreate(savedInstanceState: Bundle?) { @@ -87,10 +96,125 @@ class GlanceTabFragment : Fragment() { override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - action_show_steps.isVisible = requireContext().checkIfFitInstalled() + // List + adapter = SlimAdapter.create() + + providers_list.setHasFixedSize(true) + val mLayoutManager = LinearLayoutManager(context) + providers_list.layoutManager = mLayoutManager + + adapter = SlimAdapter.create() + adapter + .register(R.layout.glance_provider_item) { item, injector -> + val provider = Constants.GlanceProviderId.from(item.id)!! + injector + .text(R.id.title, item.title) + .with(R.id.icon) { + it.setImageDrawable(ContextCompat.getDrawable(requireContext(), item.icon)) + } + .clicked(R.id.item) { + if (Preferences.showGlance) { + if (provider == Constants.GlanceProviderId.CUSTOM_INFO) { + CustomNotesDialog(requireContext()).show() + } else { + dialog = GlanceSettingsDialog(requireActivity(), provider) { + adapter.notifyItemRangeChanged(0, adapter.data.size) + } + dialog?.setOnDismissListener { + dialog = null + } + dialog?.show() + } + } + } + when (provider) { + Constants.GlanceProviderId.PLAYING_SONG -> { + when { + 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)) + } + Preferences.showMusic -> { + injector.visible(R.id.error_icon) + injector.text(R.id.label, getString(R.string.settings_not_visible)) + } + else -> { + injector.invisible(R.id.error_icon) + 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) + } + 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) + } + 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) + } + 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) + } else if (Preferences.showDailySteps) { + ActivityDetectionReceiver.unregisterFence(requireContext()) + injector.visible(R.id.error_icon) + 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) + } + } + } + } + .attachTo(providers_list) + + val mIth = ItemTouchHelper( + object : ItemTouchHelper.SimpleCallback( + ItemTouchHelper.UP or ItemTouchHelper.DOWN, + 0 + ) { + override fun onMove( + recyclerView: RecyclerView, + 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 onSwiped( + viewHolder: RecyclerView.ViewHolder, + direction: Int + ) { + // remove from adapter + } + }) + + mIth.attachToRecyclerView(providers_list) + adapter.updateData( + GlanceProviderHelper.getGlanceProviders(requireContext()) + .mapNotNull { GlanceProviderHelper.getGlanceProviderById(requireContext(), it) } + ) + providers_list.isNestedScrollingEnabled = false setupListener() - updateNextAlarmWarningUi() } private fun subscribeUi( @@ -105,45 +229,9 @@ class GlanceTabFragment : Fragment() { show_glance_label.text = if (it) getString(R.string.description_show_glance_visible) else getString(R.string.description_show_glance_not_visible) } }) - - viewModel.showMusic.observe(viewLifecycleOwner, Observer { - maintainScrollPosition { - checkNotificationPermission() - } - }) - - viewModel.showNextAlarm.observe(viewLifecycleOwner, Observer { - maintainScrollPosition { - updateNextAlarmWarningUi() - } - }) - - viewModel.showBatteryCharging.observe(viewLifecycleOwner, Observer { - maintainScrollPosition { - show_low_battery_level_warning_label?.text = if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible) - } - }) - - viewModel.showDailySteps.observe(viewLifecycleOwner, Observer { - maintainScrollPosition { - show_steps_label?.text = if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible) - } - checkFitnessPermission() - }) - - viewModel.customInfo.observe(viewLifecycleOwner, Observer { - maintainScrollPosition { - show_custom_notes_label?.text = if (it == "") getString(R.string.settings_not_visible) else it - } - }) - - viewModel.musicPlayersFilter.observe(viewLifecycleOwner, Observer { - - }) } private fun setupListener() { - action_show_glance.setOnClickListener { Preferences.showGlance = !Preferences.showGlance } @@ -151,134 +239,20 @@ class GlanceTabFragment : Fragment() { show_glance_switch.setOnCheckedChangeListener { _, enabled: Boolean -> Preferences.showGlance = enabled } - - action_sort_glance_providers.setOnClickListener { - GlanceProviderSortMenu(requireContext()) - .show() - } - - action_show_music.setOnClickListener { - if (Preferences.showGlance) { - BottomSheetMenu( - requireContext(), - header = getString(R.string.settings_show_music_title) - ).setSelectedValue(Preferences.showMusic) - .addItem(getString(R.string.settings_visible), true) - .addItem(getString(R.string.settings_not_visible), false) - .addOnSelectItemListener { value -> - Preferences.showMusic = value - }.show() - } - } - - action_show_next_alarm.setOnClickListener { - if (Preferences.showGlance) { - BottomSheetMenu( - requireContext(), - header = getString(R.string.settings_show_next_alarm_title) - ).setSelectedValue(Preferences.showNextAlarm) - .addItem(getString(R.string.settings_visible), true) - .addItem(getString(R.string.settings_not_visible), false) - .addOnSelectItemListener { value -> - Preferences.showNextAlarm = value - }.show() - } - } - - action_show_next_alarm.setOnLongClickListener { - with(requireContext().getSystemService(Context.ALARM_SERVICE) as AlarmManager) { - val alarm = nextAlarmClock - if (alarm != null && alarm.showIntent != null) { - val pm = requireContext().packageManager as PackageManager - val appNameOrPackage = try { - pm.getApplicationLabel(pm.getApplicationInfo(alarm.showIntent?.creatorPackage ?: "", 0)) - } catch (e: Exception) { - alarm.showIntent?.creatorPackage ?: "" - } - MaterialBottomSheetDialog(requireContext(), message = getString(R.string.next_alarm_warning).format(appNameOrPackage)) - .setPositiveButton(getString(android.R.string.ok)) - .show() - } - } - true - } - - action_show_low_battery_level_warning.setOnClickListener { - if (Preferences.showGlance) { - BottomSheetMenu( - requireContext(), - header = getString(R.string.settings_low_battery_level_title) - ).setSelectedValue(Preferences.showBatteryCharging) - .addItem(getString(R.string.settings_visible), true) - .addItem(getString(R.string.settings_not_visible), false) - .addOnSelectItemListener { value -> - Preferences.showBatteryCharging = value - }.show() - } - } - - action_show_steps.setOnClickListener { - if (Preferences.showGlance) { - BottomSheetMenu( - requireContext(), - header = getString(R.string.settings_daily_steps_title) - ).setSelectedValue(Preferences.showDailySteps) - .addItem(getString(R.string.settings_visible), true) - .addItem(getString(R.string.settings_not_visible), false) - .addOnSelectItemListener { value -> - if (value) { - val account: GoogleSignInAccount? = GoogleSignIn.getLastSignedInAccount(requireContext()) - if (!GoogleSignIn.hasPermissions(account, FITNESS_OPTIONS)) { - val mGoogleSignInClient = GoogleSignIn.getClient(requireActivity(), GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).addExtension(FITNESS_OPTIONS).build()) - startActivityForResult(mGoogleSignInClient.signInIntent, 2) - } else { - Preferences.showDailySteps = true - } - } else { - Preferences.showDailySteps = false - } - }.show() - } - } - - action_show_custom_notes.setOnClickListener { - if (Preferences.showGlance) { - CustomNotesDialog(requireContext()).show() - } - } - - action_filter_music_players.setOnClickListener { - startActivity(Intent(requireContext(), MusicPlayersFilterActivity::class.java)) - } - } - - private fun updateNextAlarmWarningUi() { - with(requireContext().getSystemService(Context.ALARM_SERVICE) as AlarmManager) { - val alarm = nextAlarmClock - if (AlarmHelper.isAlarmProbablyWrong(requireContext()) && alarm != null && alarm.showIntent != null) { - val pm = requireContext().packageManager as PackageManager - val appNameOrPackage = try { - pm.getApplicationLabel(pm.getApplicationInfo(alarm.showIntent?.creatorPackage ?: "", 0)) - } catch (e: Exception) { - alarm.showIntent?.creatorPackage ?: "" - } - show_next_alarm_warning.text = getString(R.string.next_alarm_warning).format(appNameOrPackage) - } else { - show_next_alarm_label?.text = if (Preferences.showNextAlarm) getString(R.string.settings_visible) else getString( - R.string.settings_not_visible) - } - } } private val nextAlarmChangeBroadcastReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { - updateNextAlarmWarningUi() + adapter.notifyItemChanged(1) } } override fun onStart() { super.onStart() activity?.registerReceiver(nextAlarmChangeBroadcastReceiver, IntentFilter(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED)) + if (dialog != null) { + dialog?.show() + } } override fun onStop() { @@ -286,50 +260,6 @@ class GlanceTabFragment : Fragment() { super.onStop() } - private fun checkNotificationPermission() { - when { - NotificationManagerCompat.getEnabledListenerPackages(requireContext()).contains(requireContext().packageName) -> { - notification_permission_alert?.isVisible = false - MediaPlayerHelper.updatePlayingMediaInfo(requireContext()) - show_music_label?.text = if (Preferences.showMusic) getString(R.string.settings_visible) else getString(R.string.settings_not_visible) - } - Preferences.showMusic -> { - notification_permission_alert?.isVisible = true - show_music_label?.text = getString(R.string.settings_request_notification_access) - notification_permission_alert?.setOnClickListener { - activity?.startActivity(Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS")) - } - } - else -> { - show_music_label?.text = getString(R.string.settings_not_visible) - notification_permission_alert?.isVisible = false - } - } - } - - private fun checkFitnessPermission() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || activity?.checkGrantedPermission(Manifest.permission.ACTIVITY_RECOGNITION) == true) { - fitness_permission_alert?.isVisible = false - if (Preferences.showDailySteps) { - ActivityDetectionReceiver.registerFence(requireContext()) - } else { - ActivityDetectionReceiver.unregisterFence(requireContext()) - } - show_steps_label?.text = if (Preferences.showDailySteps) getString(R.string.settings_visible) else getString(R.string.settings_not_visible) - } else if (Preferences.showDailySteps) { - ActivityDetectionReceiver.unregisterFence(requireContext()) - fitness_permission_alert?.isVisible = true - show_steps_label?.text = getString(R.string.settings_request_fitness_access) - fitness_permission_alert?.setOnClickListener { - requireFitnessPermission() - } - } else { - ActivityDetectionReceiver.unregisterFence(requireContext()) - show_steps_label?.text = getString(R.string.settings_not_visible) - fitness_permission_alert?.isVisible = false - } - } - override fun onActivityResult( requestCode: Int, resultCode: Int, @@ -338,9 +268,15 @@ class GlanceTabFragment : Fragment() { when (requestCode) { 1 -> { if (resultCode == Activity.RESULT_OK) { - checkFitnessPermission() + adapter.notifyItemChanged(2) + if (dialog != null) { + dialog?.show() + } } else { Preferences.showDailySteps = false + if (dialog != null) { + dialog?.show() + } } } 2-> { @@ -353,42 +289,22 @@ class GlanceTabFragment : Fragment() { account, FITNESS_OPTIONS) } else { - checkFitnessPermission() + adapter.notifyItemChanged(2) + if (dialog != null) { + dialog?.show() + } } } catch (e: ApiException) { e.printStackTrace() Preferences.showDailySteps = false + if (dialog != null) { + dialog?.show() + } } } } } - private fun requireFitnessPermission() { - Dexter.withContext(requireContext()) - .withPermissions( - "com.google.android.gms.permission.ACTIVITY_RECOGNITION", - "android.gms.permission.ACTIVITY_RECOGNITION", - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACTIVITY_RECOGNITION else "com.google.android.gms.permission.ACTIVITY_RECOGNITION" - ).withListener(object: MultiplePermissionsListener { - override fun onPermissionsChecked(report: MultiplePermissionsReport?) { - report?.let { - if (report.areAllPermissionsGranted()){ - checkFitnessPermission() - } - } - } - override fun onPermissionRationaleShouldBeShown( - permissions: MutableList?, - token: PermissionToken? - ) { - // Remember to invoke this method when the custom rationale is closed - // or just by default if you don't want to use any custom rationale. - token?.continuePermissionRequest() - } - }) - .check() - } - private fun maintainScrollPosition(callback: () -> Unit) { scrollView.isScrollable = false callback.invoke() @@ -400,6 +316,6 @@ class GlanceTabFragment : Fragment() { override fun onResume() { super.onResume() - checkNotificationPermission() + adapter.notifyItemRangeChanged(0, adapter.data.size) } } diff --git a/app/src/main/res/drawable-hdpi/round_arrow_circle_down.png b/app/src/main/res/drawable-hdpi/round_arrow_circle_down.png new file mode 100644 index 0000000000000000000000000000000000000000..67dcaca0a342eee67e3a5e5fd777ddb5ce429765 GIT binary patch literal 536 zcmV+z0_XjSP)?s{*v(!c0lk|Zw(FvSwPiv>b-@m%x}9y-{=wGEm@3{%4vS&QK3 zHB11r1IDQ14Nn(78kpdObU$d_`Voal7o!8u;ra>!9FcC2b)X*7&GC@ob*fk)UF+Hx z`7rMa-VIN?jL`V_{A(_bA9}5W zgfzD&X6w1`U`J?bn7cNx`!rqNEhDvvvUly z2mxO4XnZC3=wl1BULJ=;_S6wsi}6v)F*$t$oZ;FL0m`L2-mXEQglm;rVanmH3=d~rX|}H zi!Qe5)U_C!lBpzT4>C(cw=g9)k_-!q-ywvZx)veyOSb#Nlw3=4T2OodQ+yZbSCWrx zog@Xt9mDf=gie8eE1HQZ8K~R;YBel3YN>{Nli*EV#z3V^hB0(3no!m`fm1eVM{sMt zAT9McgjI!WaBBR2yYhzh_d+N`x9TIThT;N#)egru6Bk&9#)T1N%4ksM1I?A`84{R6 z2s21;G?{#ywGTU%Zf%jn92&KZ4A&xnC9GisDMZkhbA96Y1qGL*ls^|!#{d8T07*qo IM6N<$f>JlZ1ONa4 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/round_arrow_circle_down_white_36.png b/app/src/main/res/drawable-hdpi/round_arrow_circle_down_white_36.png new file mode 100644 index 0000000000000000000000000000000000000000..d2a60c82157194f93eaafa277feeb0ab6855ed1a GIT binary patch literal 778 zcmV+l1NHogP)mO=a4b?=1-{?$yP4rA27wcx&lFi%_*JI)(P&JWGZcBQV?ww8Cv_PW|kf~9PHX~Pu-+ClH_Gkdv`sUVZ9H1P)NFA9a_6UgWW?bC%uAc z^#Toc1Fe>1!#=c&0u2^GYbM$7c`JETpusMo^)eYu-ma%eTZnSPeOy56C)w~0TE%df zB<&)_2S{2g$%Y+hzU6^6K?6^-|9tk}h;cX_%H0tq8&(WEPcWQ$-I1)ZNwe`xHeMLs zqg)PkjU(5)ta@|w20SpVGl5o4yU0@CeQ;%ZVu0ft{imyk z&5>u%<>xPLm!C7-{=ra>&_c_Cx6sz`a~!IL$kki8zD;XORB{-qiZ!&MtM8G&V}|oH z9IA;Gv>8e+zq#B%TjMr^p&k%H`@xm#oplk{$g)GZe}?$2NZ;dJ54YK~<2U#R-s6Ud zYlUVWU#Nd$UkeP-f{%*4DAv)&JC@kj9MwGkG35(cH?~|TtoOMETsO5JdTzc6xyKUL z=ID9_Nv~=zm?3FjctZ7<{z0sP4({;0(?=V1l)ao~*M?ES$hR#P2e zAAii>0NbffaDu|~75IVAIKq4EVhdZ?!v`GW3_UM1!asHSI$e045w7qN8ztAZLv%6r zJnb|uXrLFrh=zXzuCbP839GpEv`aKoMX-$}#qy+{hb;j7rdzH$o$DVQu3VZtyO+ zm@MRVBE}a*)rA+1{oir*g{{Z*H}Fy3FtXmkuUx?y+`EnCm9O}575->u$ddx0EALDB zhLn-K{RIr@P~PwIZAIP)s|y&=rpexvxnMh>r3eTp4tnxhWiECh?`VMoI+OP)vcP(` zzyTeH6}-5Ux3jG#+rgjuL79sU zp~-q;Y>v-ON6eHx8d`;k(JYSV=X3HQbx*EJZ^Th3bDa z{$|E+eaS=1bZ7H?lCX+zCM!zRJ>l&^cOGjJ8n`pv$*lGOc1`zy=8O;M4Fjf-p{4tS z>BeYdz2c|lD+<%~X8!8q4IVu05huaD+Zx&!dD<-+^E@Bc^*nui!CslLu!?+^*)d^ZC%-;wHsgBUZck@x8gGQ=5?BJ)_ zxkfWB8XTaf8U?!8O^XhV62~c@I@YxUK`#p!5Rq;*kOfnTahj{xT$u<5^s-&CdkCOU=$mgqwtttOq+(L@u6UF zR2S;ut{s=k9b&6p%c_@`tCt35zl2@OVl&NT82+36P;MNGC7MekVyjT>sF^bc5wTq; zmd1oIK#E~a>^l@YMTX9R3_r>xq1Zku)Z980TPQbrFa(oOtdBz2Cr0rhx6)q(2kqK) z%HSQjc4X+*pO@zq!Ci%5^<-!se?ZB_xz``g>Kz_XsFq`kUgufpV}U(RNO44h8M>X9 Z_6KRUN9HEfGzI_w002ovPDHLkV1hPLiAewe literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/round_outbond_white_24.png b/app/src/main/res/drawable-hdpi/round_outbond_white_24.png new file mode 100644 index 0000000000000000000000000000000000000000..3bc389d817eb32741f640b68c7124bf8235ba0de GIT binary patch literal 389 zcmV;00eb$4P)416gFvAeEYzn^tQ8A^LNQREgF^72KEYyq0(A})3c)}iaBvU^1_Dogrn7h1 z>{9zUyz~8k_!Iu&4h=r>g&lTSVTl=TOGi|w(Hd@pX^EH#w$iQfkSnH<#|f{Oo@gn* zd1}zRLe5?aFUmR%{wa*mDQ{i;i4#nRtaC`1e;j^+H*uT3phxHHB0)F$-Nu4Gq}gDc z7&MCoeM>h@3|hv5T50O^lUYTAE|0+z#>0c`(u4YAo^iqkW8CZ4#)7&GF#vm<^!thh ztuKm6^BD_T=r_w415GSwB5sc=V+`EIg065B_kar13^8r!gSmctdDKIKu5nP_7F8Gm zwelw699Sr)3FpEHEBP%$DvYp@&pWDcDbzSf*Wo4Pglo)kG~59VMxhj3VS)wL=m5~- j8y|SY&o~%{I~WB3FBP|i4(|HB00000NkvXXu0mjfNEW0b literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/round_outbond_white_36.png b/app/src/main/res/drawable-hdpi/round_outbond_white_36.png new file mode 100644 index 0000000000000000000000000000000000000000..15faf242014d94559a2815a8c44806d75e3379fc GIT binary patch literal 554 zcmV+_0@eMAP)RfFQxNt;ni+( zyx>n2f;yOp?-{N1LDVr)t{hLOrHVSmOga-Z%Z|FhLV6!KD=Vst-2SYh$DxI#{rf;O z=1|O4$0W+2V61wcB79esl%usv*qiEl-ZrYQ`oe#|Fc-%f*9AxFRhXCXd5^0e@K+Ne zM?EC$UR?i+Of-HA*AEGsLV~y$VWXl^4dofd53?#7)>e)j*YU$ZqexgUK~(Ipvm#-` z1W~cWy4g?gkRl4#7@-y+Y!D$VT2#KdmOF+Gi-g@KjIt5;3j^D^EE0B=IBL_{cFv20 zbrM9y)+`d%Jg}&BRupE!{Y@VQ#vx&k!Ypx;J_-y&!rD88rHm4MwZW$_|8Rm6+$M^8 z%|hW$xFr_S>4k?;!@KI5WZS}x>gr^>z*O~&V%?FyRL2bUn3v17{afHPiwS-EmE$5S z1NvA?Z;5V-gZh_r=4hpSm@-wqG3r@rxWT*l-q6kV2{qi|)9&WzXH|nX9x+qg6!&Ny s(gU#$u5gP7JYa|(+Gu1)M@I+g8z^eKLhX&eDF6Tf07*qoM6N<$g6d)Wd;kCd literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-hdpi/round_outbond_white_48.png b/app/src/main/res/drawable-hdpi/round_outbond_white_48.png new file mode 100644 index 0000000000000000000000000000000000000000..528e702f0ee4c3ea70b4e2861d5268fb31453564 GIT binary patch literal 708 zcmV;#0z3VQP)WYu0)!A2A%wwV z@H+@N(3_bzZ|3I50>Iyz@xFOq_7S~auh;AKaDXAkm|%_-p5K2<%y5Y_46)zkAX_-X z1Z&}*aE`;Sg!zJNs!n=}NlBO~x5uDSdP7#E!F#mG+p&4m8z1<5+P{wbzfj;~b;VUOB$j`B2Wa z-x}L>1e)lM)2id_q0k*~m7d)&*F6_i#rdY2HkFJ@uu#7h_5(&LGv!RG7+)0X_dR$Z zSI%qMKtIKCnFYXS+$bp6- zfvy^gbJD;+=qx1AZDVob2f7Ribl-fOXn|%Sf!3+S!Jy_q%YZ=1#5qKcQH_C~0|F%# z2VhiFpmj)~m&D@y6A6c^u?h+FkYF5u2~P0P*k>UunvWCBB>dY~_v64g{HW3WIKfAa zlm8?R9E1eg!A5y!iN{$tIgj385I;_&xio$$=P~g(a8xGHKzRoV$H}pkm4T&l?z~6B zE`B4IhU=It*0!LY$ zaG||Mv2NEdw9i%St)55ivBXvu6ZTsYX@x|nqoVJjh_o?DR7#l1Va>>m*Y4~ z5%zGS83iU7v}G^;PCRq$Wo?6FEY+jH0^hQ>!vMdqz(%+nGyKGE)?j>-BoQUhgj+&tJ_6%y$X^00000fhdEP)Bgatr=01yB|2mu0w za5yXigb?)OV`Q4U?SO^{H-G=1y{6lM6UfOCc;M=okH7_(#o$5g)GJ|d1xwHeDRI;U zYMx+THDE0dfyB@@@NsAyBTVjQpm$i8&dlejuZ;;XgweBZPa|=wa#PMQpiE3HY%nfYT9?D zSPoZ+dBX157YdNW?73s1#7g%qosq#6&U};zhko5IQY5${LV*AGR^6`2q9& VG}g4o%pd>&002ovPDHLkV1k1=ZSDX7 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/round_arrow_circle_down_white_36.png b/app/src/main/res/drawable-mdpi/round_arrow_circle_down_white_36.png new file mode 100644 index 0000000000000000000000000000000000000000..67dcaca0a342eee67e3a5e5fd777ddb5ce429765 GIT binary patch literal 536 zcmV+z0_XjSP)?s{*v(!c0lk|Zw(FvSwPiv>b-@m%x}9y-{=wGEm@3{%4vS&QK3 zHB11r1IDQ14Nn(78kpdObU$d_`Voal7o!8u;ra>!9FcC2b)X*7&GC@ob*fk)UF+Hx z`7rMa-VIN?jL`V_{A(_bA9}5W zgfzD&X6w1`U`J?bn7cNx`!rqNEhDvvvUly z2mxO4XnZC3=wl1BULJ=;_S6wsi}6v)F*$t$oZ;FL0m`L!%zgnFdT|v2!bIf zilFylcp^FZzxUD}^6>-Y^}WbT(l}LBRd%{uE-g&3#1?P({1#w?XN=JJUnX6LhX9fi zykd&lEhb*W3^7cLFoAom$v+~5?GEUbJ$VoRD!>y4=%M|sk0CsKAg=`DGA4e9HL{8^ zMMJpZ=Qty)-*9a%V3TvU7N{GH+r%<&5w<2j&)Il=izjG+6Vi=M2Oj2Zwsr}ZX$KM1 z67)>&@n0EdzU4@gFXEJO!d#uf7En72&W7pbly0K4xz13VIaexUV@Ie-2JkfpP{-(F zj~yN?oWQAMfTQW%fMfnB$L}oM{az&-N$rH1cmk<3-)_|sG<04UwhoyuKwidc$Ee6b zJHbI_3y`18=OPEaL#=zm1q`9KDRNK1050Lh=z_>lAz3JS#I?|_ifqc#PqHU3bUZ6H~$l@Y=!FW$lTk5=pt{t+p z2wyl>0JVwEtt*CWz6kN;8zA{DJ?mL8aL8a0zQ*xWs0EUPS5P~`)q0Xb^WR_$HBU0Y z4(yTINsC p1zzxx+Mprcv4e+>W2LI9s=v$Z`wIIQ2onGR002ovPDHLkV1kD?KllIu literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/round_outbond.png b/app/src/main/res/drawable-mdpi/round_outbond.png new file mode 100644 index 0000000000000000000000000000000000000000..aab5ec2971e1c21fbd608c507c1ed4c797236b3f GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rhey`C z#N_mXBeAhh@Q|EBNrR=s3l7416gFvAeEYzn^tQ8A^LNQREgF^72KEYyq0(A})3c)}iaBvU^1_Dogrn7h1 z>{9zUyz~8k_!Iu&4h=r>g&lTSVTl=TOGi|w(Hd@pX^EH#w$iQfkSnH<#|f{Oo@gn* zd1}zRLe5?aFUmR%{wa*mDQ{i;i4#nRtaC`1e;j^+H*uT3phxHHB0)F$-Nu4Gq}gDc z7&MCoeM>h@3|hv5T50O^lUYTAE|0+z#>0c`(u4YAo^iqkW8CZ4#)7&GF#vm<^!thh ztuKm6^BD_T=r_w415GSwB5sc=V+`EIg065B_kar13^8r!gSmctdDKIKu5nP_7F8Gm zwelw699Sr)3FpEHEBP%$DvYp@&pWDcDbzSf*Wo4Pglo)kG~59VMxhj3VS)wL=m5~- j8y|SY&o~%{I~WB3FBP|i4(|HB00000NkvXXu0mjfNEW0b literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/round_outbond_white_48.png b/app/src/main/res/drawable-mdpi/round_outbond_white_48.png new file mode 100644 index 0000000000000000000000000000000000000000..bf9f8fe17508a75a8a0894711b53b7ec2bdb0f5d GIT binary patch literal 501 zcmV3~=gGC5o5iUZ203iS%Tm%RqKnNFM5dwq|77GY42qA=vMF;^xSPTXsgfMt6 z0C1gY&de_M0f6(paQv~hww4FBaf&JK@r(r)n4`okj_?w4(XR$4ksCH}XE@g=A{Uf~cO5z4((;@{7dWz94febI@gJ7& z4MnttE34x)+Q1m!R!5Cdq{5Bv{=|QvKq=jMq{6%IekZ*1OS-2>fjxQD*v%NwU@QN* zkQk960FF}v9^^I67;u{s@FJfQMaFEx&T~q@YxeQ^+@}OQuIPA}_Hl*YXBeOFD#d|x4Ymgw58IIfl{7Vq zfyU1x6=u?%qre!Y{!AhjcF;&yqtTyFY(^WHS{)bB7RLCpd=*CV6F9SchtUOQmS+-O zp}=3myNg^f9yp@JM&yJ7GyS`aKH&^s^83J13;| literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/round_arrow_circle_down.png b/app/src/main/res/drawable-xhdpi/round_arrow_circle_down.png new file mode 100644 index 0000000000000000000000000000000000000000..f52ac9d4a8a2ab932de744b04f1a9dc6f243acd4 GIT binary patch literal 707 zcmV;!0zCbRP)!%zgnFdT|v2!bIf zilFylcp^FZzxUD}^6>-Y^}WbT(l}LBRd%{uE-g&3#1?P({1#w?XN=JJUnX6LhX9fi zykd&lEhb*W3^7cLFoAom$v+~5?GEUbJ$VoRD!>y4=%M|sk0CsKAg=`DGA4e9HL{8^ zMMJpZ=Qty)-*9a%V3TvU7N{GH+r%<&5w<2j&)Il=izjG+6Vi=M2Oj2Zwsr}ZX$KM1 z67)>&@n0EdzU4@gFXEJO!d#uf7En72&W7pbly0K4xz13VIaexUV@Ie-2JkfpP{-(F zj~yN?oWQAMfTQW%fMfnB$L}oM{az&-N$rH1cmk<3-)_|sG<04UwhoyuKwidc$Ee6b zJHbI_3y`18=OPEaL#=zm1q`9KDRNK1050Lh=z_>lAz3JS#I?|_ifqc#PqHU3bUZ6H~$l@Y=!FW$lTk5=pt{t+p z2wyl>0JVwEtt*CWz6kN;8zA{DJ?mL8aL8a0zQ*xWs0EUPS5P~`)q0Xb^WR_$HBU0Y z4(yTINsC p1zzxx+Mprcv4e+>W2LI9s=v$Z`wIIQ2onGR002ovPDHLkV1kD?KllIu literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/round_arrow_circle_down_white_18.png b/app/src/main/res/drawable-xhdpi/round_arrow_circle_down_white_18.png new file mode 100644 index 0000000000000000000000000000000000000000..67dcaca0a342eee67e3a5e5fd777ddb5ce429765 GIT binary patch literal 536 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/round_outbond_white_24.png b/app/src/main/res/drawable-xhdpi/round_outbond_white_24.png new file mode 100644 index 0000000000000000000000000000000000000000..bf9f8fe17508a75a8a0894711b53b7ec2bdb0f5d GIT binary patch literal 501 zcmV3~=gGC5o5iUZ203iS%Tm%RqKnNFM5dwq|77GY42qA=vMF;^xSPTXsgfMt6 z0C1gY&de_M0f6(paQv~hww4FBaf&JK@r(r)n4`okj_?w4(XR$4ksCH}XE@g=A{Uf~cO5z4((;@{7dWz94febI@gJ7& z4MnttE34x)+Q1m!R!5Cdq{5Bv{=|QvKq=jMq{6%IekZ*1OS-2>fjxQD*v%NwU@QN* zkQk960FF}v9^^I67;u{s@FJfQMaFEx&T~q@YxeQ^+@}OQuIPA}_Hl*YXBeOFD#d|x4Ymgw58IIfl{7Vq zfyU1x6=u?%qre!Y{!AhjcF;&yqtTyFY(^WHS{)bB7RLCpd=*CV6F9SchtUOQmS+-O zp}=3myNg^f9yp@JM&yJ7GyS`aKH&^s^83J13;| literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/round_outbond_white_36.png b/app/src/main/res/drawable-xhdpi/round_outbond_white_36.png new file mode 100644 index 0000000000000000000000000000000000000000..528e702f0ee4c3ea70b4e2861d5268fb31453564 GIT binary patch literal 708 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/round_arrow_circle_down_white_48.png b/app/src/main/res/drawable-xxhdpi/round_arrow_circle_down_white_48.png new file mode 100644 index 0000000000000000000000000000000000000000..3d7ea40c1d546d4ef7bcd32482f9ba7287fc2576 GIT binary patch literal 1759 zcmdUv`9Bj30LIs(R&B23c*C5Lp_)kK7@LgA*d}roixz9;+z>B{Ox`9}j4Y9h{rUOj$@Fk{hHT%p9RL78Trg<-hME5bB(u?j z*OeF>YV&X-I&FCUe@^Q~)3S{j4$*jb0zhrQb5L?&&C}OC&AhU!;V2N6wf<%EPQOnT z1h6)B_1nV`lYzE44TY?PsHtJxp*l&JP1?-ckqmuvz>M8gLo)K@?*XEBX6|?$-`ZX-rJEdXC;PC&6=_%q`%P$ zBRyzHyh%G%9Ln|Q`i@x0B)bTP_-1s+JEZ3kYqiTY!C67mFQYZru1f-ilXd)GEiLl( zJ@Q5e8=IXPJG=^gZNgK(y1{JD%(%^9oPXYL!>pBLzZE5Bw6_6sl zwq`c?AvRSaltiZ&Op@!X-*yBml$U#7SC;n-b!>TPOc6fz0Ylp!@mK84Pv>M`PAr(axd z|DaWxgl2|am!OEtR9L5jq~v6&NpL3}yr43eM@EoV(|uIzP-}=sY6d7cwA~zL#(9Ty zF4DoO-?!SDd3*4)BJUii`vov~86Hbk-ucU{J)YQLp|AgxX?4-S&I^a>rQQyWX91<$DYbh9_b%{se?*rM;U;ldd5e> zo}Nu6sB)|j5XAC~qwk5bfC7D~O6aOt;?-gpM+a0Ok^ zpIv0gXA;ovB=XVtj3@gF^w3914&m-2dG3;ql}rx(MrBkRLRkjwN+KtvP@Y##p4_&{ z*cBEbl%>L16r*Yo9SBeA3iH!q);{_&5g6iLCmlbGHhE=JFAa2RvVMg;kh6clSlPBz zRaGa1JlV=*_?3>Sl*K67BHybjqwccK{-ynFPF0=Bt*Nqb?8I9*OXG?4amC4JMqgk? zNfoQ#(lxzg^dpX5vP^H$f+udx+?7DIL9TmG#OZgzGLvPFCE_idQj3YUjvdpS7*Ra2 zCH+g%7?`VT$9uxu9le>AhCUb^ zSpYu%k4{u5=AfAZw)PZeMy~jVT4<;OiqfV~r&yPsbJt2YA+l@qxp*(3mT@s)B1IiN z6u8jBgOW?lfwL8H&Wj&$b6Z~-SVqX#&mCqN?#Ff|gf|a1XYJOwL)LFx_`_*>L{f4hk zl9C3FEMCDC=Fom@6Dh9Uw5ua)8#q`pjkjRDA2;3{#hy(0I#wfQ03R*^?F|lSE@CU5 z0_-Ca13rA_6iV6I&26*`4^~bM&oUE@mRLU=LM%IkzpRfFQxNt;ni+( zyx>n2f;yOp?-{N1LDVr)t{hLOrHVSmOga-Z%Z|FhLV6!KD=Vst-2SYh$DxI#{rf;O z=1|O4$0W+2V61wcB79esl%usv*qiEl-ZrYQ`oe#|Fc-%f*9AxFRhXCXd5^0e@K+Ne zM?EC$UR?i+Of-HA*AEGsLV~y$VWXl^4dofd53?#7)>e)j*YU$ZqexgUK~(Ipvm#-` z1W~cWy4g?gkRl4#7@-y+Y!D$VT2#KdmOF+Gi-g@KjIt5;3j^D^EE0B=IBL_{cFv20 zbrM9y)+`d%Jg}&BRupE!{Y@VQ#vx&k!Ypx;J_-y&!rD88rHm4MwZW$_|8Rm6+$M^8 z%|hW$xFr_S>4k?;!@KI5WZS}x>gr^>z*O~&V%?FyRL2bUn3v17{afHPiwS-EmE$5S z1NvA?Z;5V-gZh_r=4hpSm@-wqG3r@rxWT*l-q6kV2{qi|)9&WzXH|nX9x+qg6!&Ny s(gU#$u5gP7JYa|(+Gu1)M@I+g8z^eKLhX&eDF6Tf07*qoM6N<$g6d)Wd;kCd literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/round_outbond_white_24.png b/app/src/main/res/drawable-xxhdpi/round_outbond_white_24.png new file mode 100644 index 0000000000000000000000000000000000000000..528e702f0ee4c3ea70b4e2861d5268fb31453564 GIT binary patch literal 708 zcmV;#0z3VQP)WYu0)!A2A%wwV z@H+@N(3_bzZ|3I50>Iyz@xFOq_7S~auh;AKaDXAkm|%_-p5K2<%y5Y_46)zkAX_-X z1Z&}*aE`;Sg!zJNs!n=}NlBO~x5uDSdP7#E!F#mG+p&4m8z1<5+P{wbzfj;~b;VUOB$j`B2Wa z-x}L>1e)lM)2id_q0k*~m7d)&*F6_i#rdY2HkFJ@uu#7h_5(&LGv!RG7+)0X_dR$Z zSI%qMKtIKCnFYXS+$bp6- zfvy^gbJD;+=qx1AZDVob2f7Ribl-fOXn|%Sf!3+S!Jy_q%YZ=1#5qKcQH_C~0|F%# z2VhiFpmj)~m&D@y6A6c^u?h+FkYF5u2~P0P*k>UunvWCBB>dY~_v64g{HW3WIKfAa zlm8?R9E1eg!A5y!iN{$tIgj385I;_&xio$$=P~g(a8xGHKzRoV$H}pkm4T&l?z~6B zE`B4IhU=It*0!LY$ zaG||Mv2NEdw9i%St)55ivBXvu6ZTsYX@x|nqoVJjh_o?DR7#l1Va>>m*Y4~ z5%zGS83iU7v}G^;PCRq$Wo?6FEY+jH0^hQ>!vMdqz(%+nGyKGE)?j>-BoQUhgj+&tJ_6%y$X^0000+tx4Lr5xm0M|i5IMsg}2r@m`>VuqB7HCuS|$# zoAps$MP@9N;VVJ=0V$-EFRGlbCeh=S$NUs?L~Yb|r(2Gpc#l zZJW9N7n1H5+E{Z%9b;UZ^($6<%d^;wEfV_bd4+6qZ6BX4W^8!V_iovRm2X!FKKm`m z8daJx^<^Y~)z=Aex`p1;;z|p=1uia@%#*&n*n}tSOB&1MFAeirq$PS^9#7)twyc`i zI@Qkh#^G~Mnmc8gBW|_$Xv{irtL%Wwp{?t;hW=l@W;TD<++77GFN0Ue9*FG|`fTiS zjM<7?U%+eq3yu2LI~I$Yo!C2BZcdmMm8=q`|2{);4%>%?+ww0aM9w=fJ8P%I+@G&D zw588}nd5j=VgA~OdTO^nnwVSZI&b<}nDgY^{P(3cHa0c!`x#cvds@8nC^t7SXE1oW L`njxgN@xNAwsSQT literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/round_outbond_white_48.png b/app/src/main/res/drawable-xxhdpi/round_outbond_white_48.png new file mode 100644 index 0000000000000000000000000000000000000000..c06b367dbc4175eeef346bccef493b235771d908 GIT binary patch literal 1302 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=4hQ&zxB}__LmV7z(VY+UhGR*P zUoeA&fqQ)Y^!3N@pWeTFet)(zhxhFNpIJnr-!Bg4QON)OeRHzT`NQQh0^QZc&oBF1 zY`@)Za$V)M&GPWckJFnqRy%y`v764oz_Feykz>{{H$MRuI@PTPi5JU$b+xrR1_zlOfj1Ie`n0T0G-&W>vd1B3dzs<>So-| zow?Qey4ZiW?Lqms4AzuKzcXsNEYFj8CZp!D(IoSk&k_!-F-gzq-Yxhg>ROD}$5+}f zHb+&5Jj;o?uy||fjE?v%is$vBd~(Y9Gg~c#SH4qR`Tf9^Ea#4yvKk9EwM;0RuJp&& zB`1dKW0%MJtIHS2n+2VU4Zf1n5h7R1Wj$}gp#|QB&(&47eP40#XG_a8yR8;{6Hjb# z@>MgNRI$v=eu6`%l<2}Y^QbTFxt01nrg**>j=6Hfb}z$%3vM z$4nl{8Lq97+PL{?ey3Yrzh!^h58Wdd7aB?*DJaV9+3d8%hZ0 zk>8>b9um4yFy~-FdB-QW(D#{gPTaiiZ^RVcdL}sU;MZEcjBA$CoxWGcGMm&mN|S^h zi#XmBNZcl(CuMkwAyG_3uZ!=MvP-{buQ0o%S(C43tVz<6Wy_x5u*eLMJ$TONp>5&? zrp79tga3UbQWP)5t#emA;ksaDOuv&rHOD5gH-Q|p6g?t0xGS#cR0#bj*ArCBD|@8c z!0YSVM9yy-EPItsL@rSe58?UcBrtQH^6@N3ZWh5;ipRYi#hN_6PDq}*z?|jd(y9|1 zPsq*c{`x1hBx#FflT8PRHT#wIDzzKVd5k>kgITAlRG;|y<=u>T>>qb0^f!gG>=b_? z_;=Oq_$BSEERwNH+Lc*$dGxm@{9~=MaNjVS`^$#rgkB)oo8awM^!bqOT`{LKl1o+Y z95yZNu!TnlRA`i}~sF}+AUi$CioiANSpVj(!4p&%4@`uv@UiiJ(Buml8~potz0U=q2^oPEnA19FMZDP*=l6&y0Xf; zc~SYRC)*aTaqcw>NDp7>EARP*@5+;1tuAS?Sr4C22)MnJ?XJ6u*|mTtyewf4IX-=7 zyQV1_yYb5EpbMV`R^F8D(sVqs+gtE%HAm(=%>$>L&tx9IvdWTU)BW0IMHP)35>F;3 z{kze&=g#WWE_*IqnA^by*;jKG}A|I^3V9+l6-xBBG;4c Rj{-{u22WQ%mvv4FO#px-#2x?u literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/round_arrow_circle_down.png b/app/src/main/res/drawable-xxxhdpi/round_arrow_circle_down.png new file mode 100644 index 0000000000000000000000000000000000000000..ecca5930b7dc62abb5395797ea78ccba9a2f2327 GIT binary patch literal 1267 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 YYQEps*l8qqU~)bSb8E8~rf#Hv0S5G=!2kdN literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/round_outbond.png b/app/src/main/res/drawable-xxxhdpi/round_outbond.png new file mode 100644 index 0000000000000000000000000000000000000000..528e702f0ee4c3ea70b4e2861d5268fb31453564 GIT binary patch literal 708 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 Rj{-{u22WQ%mvv4FO#px-#2x?u literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/round_outbond_white_48.png b/app/src/main/res/drawable-xxxhdpi/round_outbond_white_48.png new file mode 100644 index 0000000000000000000000000000000000000000..d471bb6beef565faad63ae9fea6ae9e542d0beb7 GIT binary patch literal 1614 zcmdUv*H@DV0L23dQ3w#x$dW1AU<75u34}dlZ$;Gj0onvq5{{8Q5|(TPrLu=YWfc$^ zVM!n;C@LTnkgx?wLz!U|0;KVwe?;#&_x{d(ye~J=$-zoQNLmO40*P2(F?ZpS_S46~ zyu8bwugwG9$6M!3O7`i z%})qAI8-%yc1+`sn64e}RgDAaCB*}Yz_33fpK`s{TO!10x4V3!`ffT;+RhgBV`ZEf zc!Qj7r8k#V(_TsMksX%QD z+je5N(=ByWUqPvQ$Dy4CUVLD@(A%Z1ELR#!brmO-o3DOhfaI^b{& zs5r3^C6$n?Dm`lC(^HBt4I7|qF(FRs6QC0AMR~tT0J<*$%$#>0`6aCh9(7|$1;_qb*!yd|1m>HGp%anaBMfx8`!JY=|+afx|>;tITauxG{U__=W zv0S>NzK0@*=s2lL%+?M4H94kK3Zq#`HSBd6Luww>s_DrJ6_DKH(^lE+l-AKScrwa6`SM4)Qsg|(Z9zkt7F z;FM+v8pSaNGYcGhXujgW@^ zJ+}xZSKXPSbDqO(nf(e@Yeo5v_t;AmU@`I>G( zk^v68%Z7xYvAdeag+0rWSDzr=40m-i2(tl3oIZ)L$pO@6BW4u`-&^IS#GXq!=dq%e zaQg~Q9{t0hZ~B&zqrg$a(T}YQHgtTq2q@TeR+8u%%=nfQI} zxC~5kSq)JB-c;4gZ|5U_qp766e7)LBgg6NS)A+kPsYBio0OM481gk6dH$?9Pc1wkT z>pv#Fm30?oI1$1N3^oAf!;vhe%zCgxiF2Bd0yFO zy#%iu7G|6w=O-m1Ty-HyC$D{7uQKX3MIw-)4IdpZUGMX0Gl^jBV8}t@1$$&^>6Im^ z@T}?P@09tdKCDq88Ww!n4vk||u>>8Z%y!?J + + diff --git a/app/src/main/res/drawable/round_outbond_24.xml b/app/src/main/res/drawable/round_outbond_24.xml new file mode 100644 index 0000000..5495c98 --- /dev/null +++ b/app/src/main/res/drawable/round_outbond_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 172cdb2..987e8f3 100644 --- a/app/src/main/res/layout/fragment_glance_settings.xml +++ b/app/src/main/res/layout/fragment_glance_settings.xml @@ -85,317 +85,19 @@ android:textColor="@color/colorAccent" android:textAppearance="@style/AnotherWidget.Settings.Header" app:textAllCaps="false" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + android:id="@+id/providers_list" /> + app:cardBackgroundColor="@color/colorPrimaryDark" + app:cardCornerRadius="3dp"> @@ -35,20 +39,21 @@ + - + android:src="@drawable/round_error" + app:tint="@color/errorColorText" + android:id="@+id/error_icon"/> \ 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 new file mode 100644 index 0000000..f3445fb --- /dev/null +++ b/app/src/main/res/layout/glance_provider_settings_layout.xml @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/glance_provider_sort_bottom_menu.xml b/app/src/main/res/layout/glance_provider_sort_bottom_menu.xml deleted file mode 100644 index 3a20279..0000000 --- a/app/src/main/res/layout/glance_provider_sort_bottom_menu.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/weather_provider_settings_layout.xml b/app/src/main/res/layout/weather_provider_settings_layout.xml index 7c8f534..f2aca83 100644 --- a/app/src/main/res/layout/weather_provider_settings_layout.xml +++ b/app/src/main/res/layout/weather_provider_settings_layout.xml @@ -40,7 +40,7 @@ + android:background="@color/disabledButtonBackground" /> Prossimo allarme - Il prossimo allarme non sembra corretto. È stato impostato dall\'app %s. Glance Canzone in riproduzione È necessario l\'accesso alle notifiche per controllare la canzone in riproduzione. @@ -197,6 +196,13 @@ Glance info will show up only when there are no events displayed and only when a few conditions are verified. Player Musica Scegli i player musical che ti interessano + Utilizziamo la notifica del tuo player di musica per mostrare la canzone in riproduzione. + Visualizza quando il dispositivo è in carica o ha la batteria scarica. + Visualizza rapidamente i passi giornalieri una volta finita una camminata o una corsa. + Guarda la tua prossima sveglia e verifica che la tua app Orologio sia l\'unica a impostare allarmi. + Allarme impostato da %s + La prossima sveglia sembra impostata da un\'app errata. Disinstalla l\'app che imposta allarmi errati. + La prossima sveglia sembra corretta. Condividi diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index c6d6d69..9bcb96a 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -29,6 +29,7 @@ #99000000 #FBD8D8 #E93B3B + #1AE93B3B #FB8C00 #efefef #43A047 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1aa6b0c..84ed6d0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -188,7 +188,6 @@ Next clock alarm - The next alarm clock seems to be wrong.\nIt has been set by %s. Glance Current playing song We need the notification access permission to check the current playing song. @@ -197,7 +196,7 @@ Service enabled Service disabled Data source priority - Change the data provider importance + Change the data provider priority sorting the list below with a drag and drop of the rows. Custom notes Battery Daily steps @@ -209,6 +208,13 @@ Glance info will show up only when there are no events displayed and only when a few conditions are verified. Music Players Choose your relevant music players + We use the music players\' notification to show the current playing song. + Get notified when the device has the battery low or is charging. + View your daily steps for a brief moment after when finishing a walk or a run. + View your next clock alarm, check if your default clock app is the only one setting device alarms. + Alarm set by %s + The next alarm clock seems to be wrong. + The next alarm clock seems to be correct. Share