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 0000000..67dcaca Binary files /dev/null and b/app/src/main/res/drawable-hdpi/round_arrow_circle_down.png differ diff --git a/app/src/main/res/drawable-hdpi/round_arrow_circle_down_white_18.png b/app/src/main/res/drawable-hdpi/round_arrow_circle_down_white_18.png new file mode 100644 index 0000000..e1b3034 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/round_arrow_circle_down_white_18.png differ 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 0000000..d2a60c8 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/round_arrow_circle_down_white_36.png differ diff --git a/app/src/main/res/drawable-hdpi/round_arrow_circle_down_white_48.png b/app/src/main/res/drawable-hdpi/round_arrow_circle_down_white_48.png new file mode 100644 index 0000000..8c1a00c Binary files /dev/null and b/app/src/main/res/drawable-hdpi/round_arrow_circle_down_white_48.png differ diff --git a/app/src/main/res/drawable-hdpi/round_outbond.png b/app/src/main/res/drawable-hdpi/round_outbond.png new file mode 100644 index 0000000..6d5f780 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/round_outbond.png differ 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 0000000..3bc389d Binary files /dev/null and b/app/src/main/res/drawable-hdpi/round_outbond_white_24.png differ 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 0000000..15faf24 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/round_outbond_white_36.png differ 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 0000000..528e702 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/round_outbond_white_48.png differ diff --git a/app/src/main/res/drawable-mdpi/round_arrow_circle_down.png b/app/src/main/res/drawable-mdpi/round_arrow_circle_down.png new file mode 100644 index 0000000..db0938b Binary files /dev/null and b/app/src/main/res/drawable-mdpi/round_arrow_circle_down.png differ diff --git a/app/src/main/res/drawable-mdpi/round_arrow_circle_down_white_18.png b/app/src/main/res/drawable-mdpi/round_arrow_circle_down_white_18.png new file mode 100644 index 0000000..ec90135 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/round_arrow_circle_down_white_18.png differ 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 0000000..67dcaca Binary files /dev/null and b/app/src/main/res/drawable-mdpi/round_arrow_circle_down_white_36.png differ diff --git a/app/src/main/res/drawable-mdpi/round_arrow_circle_down_white_48.png b/app/src/main/res/drawable-mdpi/round_arrow_circle_down_white_48.png new file mode 100644 index 0000000..f52ac9d Binary files /dev/null and b/app/src/main/res/drawable-mdpi/round_arrow_circle_down_white_48.png differ 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 0000000..aab5ec2 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/round_outbond.png differ diff --git a/app/src/main/res/drawable-mdpi/round_outbond_white_24.png b/app/src/main/res/drawable-mdpi/round_outbond_white_24.png new file mode 100644 index 0000000..94afe95 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/round_outbond_white_24.png differ diff --git a/app/src/main/res/drawable-mdpi/round_outbond_white_36.png b/app/src/main/res/drawable-mdpi/round_outbond_white_36.png new file mode 100644 index 0000000..3bc389d Binary files /dev/null and b/app/src/main/res/drawable-mdpi/round_outbond_white_36.png differ 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 0000000..bf9f8fe Binary files /dev/null and b/app/src/main/res/drawable-mdpi/round_outbond_white_48.png differ 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 0000000..f52ac9d Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/round_arrow_circle_down.png differ 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 0000000..67dcaca Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/round_arrow_circle_down_white_18.png differ diff --git a/app/src/main/res/drawable-xhdpi/round_arrow_circle_down_white_36.png b/app/src/main/res/drawable-xhdpi/round_arrow_circle_down_white_36.png new file mode 100644 index 0000000..8c1a00c Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/round_arrow_circle_down_white_36.png differ diff --git a/app/src/main/res/drawable-xhdpi/round_arrow_circle_down_white_48.png b/app/src/main/res/drawable-xhdpi/round_arrow_circle_down_white_48.png new file mode 100644 index 0000000..ecca593 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/round_arrow_circle_down_white_48.png differ diff --git a/app/src/main/res/drawable-xhdpi/round_outbond.png b/app/src/main/res/drawable-xhdpi/round_outbond.png new file mode 100644 index 0000000..3bc389d Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/round_outbond.png differ 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 0000000..bf9f8fe Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/round_outbond_white_24.png differ 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 0000000..528e702 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/round_outbond_white_36.png differ diff --git a/app/src/main/res/drawable-xhdpi/round_outbond_white_48.png b/app/src/main/res/drawable-xhdpi/round_outbond_white_48.png new file mode 100644 index 0000000..dafe81a Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/round_outbond_white_48.png differ diff --git a/app/src/main/res/drawable-xxhdpi/round_arrow_circle_down.png b/app/src/main/res/drawable-xxhdpi/round_arrow_circle_down.png new file mode 100644 index 0000000..8c1a00c Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/round_arrow_circle_down.png differ diff --git a/app/src/main/res/drawable-xxhdpi/round_arrow_circle_down_white_18.png b/app/src/main/res/drawable-xxhdpi/round_arrow_circle_down_white_18.png new file mode 100644 index 0000000..d2a60c8 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/round_arrow_circle_down_white_18.png differ diff --git a/app/src/main/res/drawable-xxhdpi/round_arrow_circle_down_white_36.png b/app/src/main/res/drawable-xxhdpi/round_arrow_circle_down_white_36.png new file mode 100644 index 0000000..dfd337b Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/round_arrow_circle_down_white_36.png differ 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 0000000..3d7ea40 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/round_arrow_circle_down_white_48.png differ diff --git a/app/src/main/res/drawable-xxhdpi/round_outbond.png b/app/src/main/res/drawable-xxhdpi/round_outbond.png new file mode 100644 index 0000000..15faf24 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/round_outbond.png differ 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 0000000..528e702 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/round_outbond_white_24.png differ diff --git a/app/src/main/res/drawable-xxhdpi/round_outbond_white_36.png b/app/src/main/res/drawable-xxhdpi/round_outbond_white_36.png new file mode 100644 index 0000000..7b199c5 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/round_outbond_white_36.png differ 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 0000000..c06b367 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/round_outbond_white_48.png differ 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 0000000..ecca593 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/round_arrow_circle_down.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/round_arrow_circle_down_white_18.png b/app/src/main/res/drawable-xxxhdpi/round_arrow_circle_down_white_18.png new file mode 100644 index 0000000..8c1a00c Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/round_arrow_circle_down_white_18.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/round_arrow_circle_down_white_36.png b/app/src/main/res/drawable-xxxhdpi/round_arrow_circle_down_white_36.png new file mode 100644 index 0000000..3d7ea40 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/round_arrow_circle_down_white_36.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/round_arrow_circle_down_white_48.png b/app/src/main/res/drawable-xxxhdpi/round_arrow_circle_down_white_48.png new file mode 100644 index 0000000..ecef6dd Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/round_arrow_circle_down_white_48.png differ 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 0000000..528e702 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/round_outbond.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/round_outbond_white_24.png b/app/src/main/res/drawable-xxxhdpi/round_outbond_white_24.png new file mode 100644 index 0000000..dafe81a Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/round_outbond_white_24.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/round_outbond_white_36.png b/app/src/main/res/drawable-xxxhdpi/round_outbond_white_36.png new file mode 100644 index 0000000..c06b367 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/round_outbond_white_36.png differ 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 0000000..d471bb6 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/round_outbond_white_48.png differ diff --git a/app/src/main/res/drawable/round_arrow_circle_down_24.xml b/app/src/main/res/drawable/round_arrow_circle_down_24.xml new file mode 100644 index 0000000..8cafd5b --- /dev/null +++ b/app/src/main/res/drawable/round_arrow_circle_down_24.xml @@ -0,0 +1,10 @@ + + + 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