Compare commits

...

12 Commits

87 changed files with 1651 additions and 995 deletions

32
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,32 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: tommasoberlose
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Smartphone (please complete the following information):**
- Device: [e.g. OnePlus 6]
- OS Version: [e.g. Android 9.0]
- App Version (that you can find inside the advanced settings) [e.g. v2.0.5 (71)]
**Additional context**
Add any other context about the problem here.

View File

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: tommasoberlose
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

Binary file not shown.

52
.idea/navEditor.xml generated Normal file
View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="navEditor-manualLayoutAlgorithm2">
<option name="myPositions">
<map>
<entry key="nav_graph.xml">
<value>
<LayoutPositions>
<option name="myPositions">
<map>
<entry key="appMainFragment">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="242" />
<option name="y" value="352" />
</Point>
</option>
<option name="myPositions">
<map>
<entry key="action_appMainFragment_to_appSettingsFragment">
<value>
<LayoutPositions />
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
<entry key="appSettingsFragment">
<value>
<LayoutPositions>
<option name="myPosition">
<Point>
<option name="x" value="532" />
<option name="y" value="353" />
</Point>
</option>
</LayoutPositions>
</value>
</entry>
</map>
</option>
</LayoutPositions>
</value>
</entry>
</map>
</option>
</component>
</project>

View File

@ -18,7 +18,7 @@ android {
applicationId "com.tommasoberlose.anotherwidget" applicationId "com.tommasoberlose.anotherwidget"
minSdkVersion 23 minSdkVersion 23
targetSdkVersion 29 targetSdkVersion 29
versionCode 69 versionCode 77
versionName "2.0.5" versionName "2.0.5"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

Binary file not shown.

View File

@ -13,6 +13,7 @@
<application <application
android:allowBackup="true" android:allowBackup="true"
android:fullBackupContent="@xml/my_backup_rules"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:name=".AWApplication" android:name=".AWApplication"
@ -90,6 +91,34 @@
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver
android:name=".receivers.PlayerReceiver"
android:enabled="true"
android:exported="true"
tools:ignore="ExportedReceiver">
<intent-filter>
<action android:name="com.android.music.metachanged" />
<action android:name="com.android.music.playstatechanged" />
<action android:name="com.android.music.playbackcomplete" />
<action android:name="com.android.music.queuechanged" />
<action android:name="com.htc.music.metachanged" />
<action android:name="fm.last.android.metachanged" />
<action android:name="com.sec.android.app.music.metachanged" />
<action android:name="com.nullsoft.winamp.metachanged" />
<action android:name="com.amazon.mp3.metachanged" />
<action android:name="com.miui.player.metachanged" />
<action android:name="com.real.IMP.metachanged" />
<action android:name="com.sonyericsson.music.metachanged" />
<action android:name="com.rdio.android.metachanged" />
<action android:name="com.samsung.sec.android.MusicPlayer.metachanged" />
<action android:name="com.andrew.apollo.metachanged" />
<action android:name="com.spotify.music.playbackstatechanged"/>
<action android:name="com.spotify.music.metadatachanged"/>
<action android:name="com.spotify.music.queuechanged"/>
</intent-filter>
</receiver>
<receiver <receiver
android:name=".receivers.WidgetClickListenerReceiver" android:name=".receivers.WidgetClickListenerReceiver"
android:enabled="true" android:enabled="true"
@ -99,6 +128,15 @@
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver
android:name=".receivers.CrashlyticsReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="com.tommasoberlose.anotherwidget.action.ACTION_REPORT_CRASH" />
</intent-filter>
</receiver>
<service android:name=".services.EventListenerJob" android:permission="android.permission.BIND_JOB_SERVICE" /> <service android:name=".services.EventListenerJob" android:permission="android.permission.BIND_JOB_SERVICE" />
</application> </application>

View File

@ -8,18 +8,24 @@ import android.text.TextWatcher
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import android.widget.GridLayout import android.widget.GridLayout
import android.widget.ImageView
import android.widget.SeekBar import android.widget.SeekBar
import androidx.annotation.ColorInt import androidx.annotation.ColorInt
import androidx.appcompat.widget.AppCompatImageView
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.widget.addTextChangedListener import androidx.core.widget.addTextChangedListener
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.card.MaterialCardView
import com.tommasoberlose.anotherwidget.R import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.helpers.ColorHelper import com.tommasoberlose.anotherwidget.helpers.ColorHelper
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark
import com.tommasoberlose.anotherwidget.utils.expand import com.tommasoberlose.anotherwidget.utils.expand
import com.tommasoberlose.anotherwidget.utils.reveal import com.tommasoberlose.anotherwidget.utils.reveal
import com.tommasoberlose.anotherwidget.utils.toPixel
import com.warkiz.widget.IndicatorSeekBar import com.warkiz.widget.IndicatorSeekBar
import com.warkiz.widget.OnSeekChangeListener import com.warkiz.widget.OnSeekChangeListener
import com.warkiz.widget.SeekParams import com.warkiz.widget.SeekParams
@ -28,13 +34,14 @@ import kotlinx.android.synthetic.main.bottom_sheet_menu_hor.view.*
import kotlinx.android.synthetic.main.bottom_sheet_menu_hor.view.color_loader import kotlinx.android.synthetic.main.bottom_sheet_menu_hor.view.color_loader
import kotlinx.android.synthetic.main.color_picker_menu_item.view.* import kotlinx.android.synthetic.main.color_picker_menu_item.view.*
import kotlinx.coroutines.* import kotlinx.coroutines.*
import net.idik.lib.slimadapter.SlimAdapter
import java.lang.Exception import java.lang.Exception
import java.util.prefs.Preferences import java.util.prefs.Preferences
class BottomSheetColorPicker( class BottomSheetColorPicker(
context: Context, context: Context,
private val colors: IntArray = intArrayOf(), private val colors: IntArray = intArrayOf(),
private val selected: Int? = null, private val getSelected: (() -> Int)? = null,
private val header: String? = null, private val header: String? = null,
private val onColorSelected: ((selectedValue: Int) -> Unit)? = null, private val onColorSelected: ((selectedValue: Int) -> Unit)? = null,
private val showAlphaSelector: Boolean = false, private val showAlphaSelector: Boolean = false,
@ -42,15 +49,19 @@ class BottomSheetColorPicker(
private val onAlphaChangeListener: ((alpha: Int) -> Unit)? = null private val onAlphaChangeListener: ((alpha: Int) -> Unit)? = null
) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) { ) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) {
private val loadingJob: Job? = null private var loadingJobs: ArrayList<Job> = ArrayList()
private lateinit var adapter: SlimAdapter
override fun show() { override fun show() {
val view = View.inflate(context, R.layout.bottom_sheet_menu_hor, null) val view = View.inflate(context, R.layout.bottom_sheet_menu_hor, null)
window?.setDimAmount(0f)
// Header // Header
view.header.isVisible = header != null view.header.isVisible = header != null
view.header_text.text = header ?: "" view.header_text.text = header ?: ""
// Alpha
view.alpha_selector_container.isVisible = showAlphaSelector view.alpha_selector_container.isVisible = showAlphaSelector
view.alpha_selector.setProgress(alpha.toFloat()) view.alpha_selector.setProgress(alpha.toFloat())
view.text_alpha.text = "%s: %s%%".format(context.getString(R.string.alpha), alpha) view.text_alpha.text = "%s: %s%%".format(context.getString(R.string.alpha), alpha)
@ -67,44 +78,62 @@ class BottomSheetColorPicker(
} }
} }
val itemViews: ArrayList<View> = ArrayList() // List
GlobalScope.launch(Dispatchers.IO) { adapter = SlimAdapter.create()
for (@ColorInt color: Int in colors) {
val itemView = View.inflate(context, R.layout.color_picker_menu_item, null) loadingJobs.add(GlobalScope.launch(Dispatchers.IO) {
itemView.color.setCardBackgroundColor(ColorStateList.valueOf(color)) val listView = View.inflate(context, R.layout.bottom_sheet_menu_list, null) as RecyclerView
itemView.check.setColorFilter(ContextCompat.getColor(context, listView.setHasFixedSize(true)
if (color.isColorDark()) android.R.color.white else android.R.color.black val mLayoutManager = GridLayoutManager(context, 6)
), android.graphics.PorterDuff.Mode.MULTIPLY) listView.layoutManager = mLayoutManager
itemView.check.isVisible = selected == color
itemView.color.setOnClickListener { adapter
onColorSelected?.invoke(color) .register<Int>(R.layout.color_picker_menu_item) { item, injector ->
this@BottomSheetColorPicker.dismiss() injector
.with<MaterialCardView>(R.id.color) {
it.setCardBackgroundColor(ColorStateList.valueOf(item))
}
.with<AppCompatImageView>(R.id.check) {
if (getSelected?.invoke() == item) {
it.setColorFilter(
ContextCompat.getColor(
context,
if (item.isColorDark()) android.R.color.white else android.R.color.black
),
android.graphics.PorterDuff.Mode.MULTIPLY
)
it.isVisible = true
} else {
it.isVisible = false
}
}
.clicked(R.id.color) {
adapter.notifyItemChanged(adapter.data.indexOf(getSelected?.invoke()))
onColorSelected?.invoke(item)
val position = adapter.data.indexOf(item)
adapter.notifyItemChanged(position)
(listView.layoutManager as GridLayoutManager).scrollToPositionWithOffset(position,0)
}
} }
itemViews.add(itemView) .attachTo(listView)
}
adapter.updateData(colors.toList())
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
itemViews.forEach { view.color_loader.isVisible = false
view.menu.addView(it, GridLayout.LayoutParams( view.list_container.addView(listView)
GridLayout.spec(GridLayout.UNDEFINED, 1f),
GridLayout.spec(GridLayout.UNDEFINED, 1f)
))
}
color_loader.isVisible = false
view.menu.isVisible = true
this@BottomSheetColorPicker.behavior.state = BottomSheetBehavior.STATE_EXPANDED this@BottomSheetColorPicker.behavior.state = BottomSheetBehavior.STATE_EXPANDED
view.list_container.isVisible = true
} }
} })
// Menu
setContentView(view) setContentView(view)
super.show() super.show()
} }
override fun onStop() { override fun onStop() {
loadingJob?.cancel() loadingJobs.forEach { it.cancel() }
super.onStop() super.onStop()
} }

View File

@ -1,17 +1,11 @@
package com.tommasoberlose.anotherwidget.components package com.tommasoberlose.anotherwidget.components
import android.app.Dialog
import android.content.Context import android.content.Context
import android.os.Bundle
import android.view.View import android.view.View
import android.view.ViewGroup
import androidx.annotation.MenuRes
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.card.MaterialCardView
import com.tommasoberlose.anotherwidget.R import com.tommasoberlose.anotherwidget.R
import kotlinx.android.synthetic.main.bottom_sheet_menu.view.* import kotlinx.android.synthetic.main.bottom_sheet_menu.view.*
import kotlinx.android.synthetic.main.bottom_sheet_menu_item.view.* import kotlinx.android.synthetic.main.bottom_sheet_menu_item.view.*
@ -21,7 +15,7 @@ import kotlinx.android.synthetic.main.bottom_sheet_menu_item.view.*
* theme which sets a rounded background to the dialog * theme which sets a rounded background to the dialog
* and doesn't dim the navigation bar * and doesn't dim the navigation bar
*/ */
open class BottomSheetMenu<T>(context: Context, private val header: String? = null, private val isMultiSelection: Boolean = false) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) { open class BottomSheetMenu<T>(context: Context, private val header: String? = null, private val message: String? = null, private val isMessageWarning: Boolean = false, private val isMultiSelection: Boolean = false) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) {
private val items: ArrayList<MenuItem<T>> = ArrayList() private val items: ArrayList<MenuItem<T>> = ArrayList()
private var selectedRes: ArrayList<T> = ArrayList() private var selectedRes: ArrayList<T> = ArrayList()
@ -60,6 +54,10 @@ open class BottomSheetMenu<T>(context: Context, private val header: String? = nu
view.header.isVisible = header != null view.header.isVisible = header != null
view.header_text.text = header ?: "" view.header_text.text = header ?: ""
view.warning_text.isVisible = message != null
view.warning_text.text = message ?: ""
view.warning_text.setTextColor(ContextCompat.getColor(context, if (isMessageWarning) R.color.warningColorText else R.color.colorSecondaryText))
// Menu // Menu
for (item in items) { for (item in items) {
if (item.value != null) { if (item.value != null) {

View File

@ -41,7 +41,7 @@ class EventRepository(val context: Context) {
fun getNextEvent(): Event? = realm.where(Event::class.java).equalTo("id", Preferences.nextEventId).findFirst() ?: realm.where(Event::class.java).findFirst() fun getNextEvent(): Event? = realm.where(Event::class.java).equalTo("id", Preferences.nextEventId).findFirst() ?: realm.where(Event::class.java).findFirst()
fun getEventById(id: Long): Event? = realm.where(Event::class.java).equalTo("id", id).findFirst() fun getEventByEventId(id: Long): Event? = realm.where(Event::class.java).equalTo("eventID", id).findFirst()
fun goToNextEvent() { fun goToNextEvent() {
val eventList = realm.where(Event::class.java).findAll() val eventList = realm.where(Event::class.java).findAll()

View File

@ -4,10 +4,11 @@ object Actions {
const val ACTION_EXTRA_OPEN_WEATHER_PROVIDER = "ACTION_EXTRA_OPEN_WEATHER_PROVIDER" const val ACTION_EXTRA_OPEN_WEATHER_PROVIDER = "ACTION_EXTRA_OPEN_WEATHER_PROVIDER"
const val ACTION_EXTRA_DISABLE_GPS_NOTIFICATION = "ACTION_EXTRA_DISABLE_GPS_NOTIFICATION" const val ACTION_EXTRA_DISABLE_GPS_NOTIFICATION = "ACTION_EXTRA_DISABLE_GPS_NOTIFICATION"
const val ACTION_TIME_UPDATE = "com.tommasoberlose.anotherwidget.action.ACTION_TIME_UPDATE" const val ACTION_TIME_UPDATE = "com.tommasoberlose.anotherwidget.action.TIME_UPDATE"
const val ACTION_CALENDAR_UPDATE = "com.tommasoberlose.anotherwidget.action.ACTION_CALENDAR_UPDATE" const val ACTION_CALENDAR_UPDATE = "com.tommasoberlose.anotherwidget.action.CALENDAR_UPDATE"
const val ACTION_WEATHER_UPDATE = "com.tommasoberlose.anotherwidget.action.ACTION_WEATHER_UPDATE" const val ACTION_WEATHER_UPDATE = "com.tommasoberlose.anotherwidget.action.WEATHER_UPDATE"
const val ACTION_OPEN_WEATHER_INTENT = "com.tommasoberlose.anotherwidget.action.ACTION_OPEN_WEATHER_INTENT" const val ACTION_OPEN_WEATHER_INTENT = "com.tommasoberlose.anotherwidget.action.OPEN_WEATHER_INTENT"
const val ACTION_GO_TO_NEXT_EVENT = "com.tommasoberlose.anotherwidget.action.GO_TO_NEXT_EVENT" const val ACTION_GO_TO_NEXT_EVENT = "com.tommasoberlose.anotherwidget.action.GO_TO_NEXT_EVENT"
const val ACTION_GO_TO_PREVIOUS_EVENT = "com.tommasoberlose.anotherwidget.action.GO_TO_PREVIOUS_EVENT" const val ACTION_GO_TO_PREVIOUS_EVENT = "com.tommasoberlose.anotherwidget.action.GO_TO_PREVIOUS_EVENT"
const val ACTION_REPORT_CRASH = "com.tommasoberlose.anotherwidget.action.REPORT_CRASH"
} }

View File

@ -7,7 +7,7 @@ import com.chibatching.kotpref.KotprefModel
object Preferences : KotprefModel() { object Preferences : KotprefModel() {
override val commitAllPropertiesByDefault: Boolean = true override val commitAllPropertiesByDefault: Boolean = true
var darkThemePreference by intPref(default = if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) MODE_NIGHT_FOLLOW_SYSTEM else MODE_NIGHT_AUTO_BATTERY) var darkThemePreference by intPref(default = MODE_NIGHT_FOLLOW_SYSTEM)
var showEvents by booleanPref(key = "PREF_SHOW_EVENTS", default = false) var showEvents by booleanPref(key = "PREF_SHOW_EVENTS", default = false)
var showWeather by booleanPref(key = "PREF_SHOW_WEATHER", default = false) var showWeather by booleanPref(key = "PREF_SHOW_WEATHER", default = false)

View File

@ -23,4 +23,14 @@ object AlarmHelper {
"" ""
} }
} }
fun isAlarmProbablyWrong(context: Context): Boolean {
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
val alarm = nextAlarmClock
return (
alarm != null
&& alarm.triggerTime - Calendar.getInstance().timeInMillis < 5 * 60 * 1000
)
}
}
} }

View File

@ -15,20 +15,27 @@ object BitmapHelper {
fun getBitmapFromView(view: View, width: Int? = null, height: Int? = null, draw: Boolean = true): Bitmap { fun getBitmapFromView(view: View, width: Int? = null, height: Int? = null, draw: Boolean = true): Bitmap {
//Define a bitmap with the same size as the view //Define a bitmap with the same size as the view
val measuredWidth = View.MeasureSpec.makeMeasureSpec(width ?: view.width, if (width != null) View.MeasureSpec.EXACTLY else View.MeasureSpec.UNSPECIFIED) val measuredWidth = View.MeasureSpec.makeMeasureSpec(width ?: view.width, if (width != null) View.MeasureSpec.EXACTLY else View.MeasureSpec.AT_MOST)
val measuredHeight = View.MeasureSpec.makeMeasureSpec(height ?: view.height, if (height != null) View.MeasureSpec.EXACTLY else View.MeasureSpec.UNSPECIFIED) val measuredHeight = View.MeasureSpec.makeMeasureSpec(height ?: view.height, if (height != null) View.MeasureSpec.EXACTLY else View.MeasureSpec.UNSPECIFIED)
view.measure(measuredWidth, measuredHeight) view.measure(measuredWidth, measuredHeight)
if (draw) {
FirebaseCrashlytics.getInstance().setCustomKey("initialWidth", width ?: -1)
FirebaseCrashlytics.getInstance().setCustomKey("initialHeight", height ?: -1)
FirebaseCrashlytics.getInstance().setCustomKey("measuredWidth", view.measuredWidth)
FirebaseCrashlytics.getInstance().setCustomKey("measuredWidth_spec", measuredWidth)
FirebaseCrashlytics.getInstance().setCustomKey("measuredHeight", view.measuredHeight)
FirebaseCrashlytics.getInstance()
.setCustomKey("measuredHeight_spec", measuredHeight)
}
return try { return try {
if (draw) {
Log.d("ciao", "bitmap ${view.measuredWidth}, ${view.measuredHeight}")
}
val btm = Bitmap.createBitmap( val btm = Bitmap.createBitmap(
view.measuredWidth, view.measuredWidth,
view.measuredHeight, view.measuredHeight,
if (true || draw) Bitmap.Config.ARGB_8888 else Bitmap.Config.ALPHA_8 if (draw) Bitmap.Config.ARGB_8888 else Bitmap.Config.ALPHA_8
) )
if (true || draw) { if (draw) {
//Bind a canvas to it //Bind a canvas to it
val canvas = Canvas(btm) val canvas = Canvas(btm)
// draw the view on the canvas // draw the view on the canvas

View File

@ -11,6 +11,7 @@ import com.tommasoberlose.anotherwidget.models.Event
import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.fragments.AppMainFragment
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
import me.everything.providers.android.calendar.CalendarProvider import me.everything.providers.android.calendar.CalendarProvider
@ -125,10 +126,9 @@ object CalendarHelper {
} }
UpdatesReceiver.setUpdates(context) UpdatesReceiver.setUpdates(context)
Log.d("ciao", "force update? 7")
MainWidget.updateWidget(context) MainWidget.updateWidget(context)
EventBus.getDefault().post(MainActivity.UpdateUiMessageEvent()) EventBus.getDefault().post(AppMainFragment.UpdateUiMessageEvent())
} }
fun getCalendarList(context: Context): List<me.everything.providers.android.calendar.Calendar> { fun getCalendarList(context: Context): List<me.everything.providers.android.calendar.Calendar> {

View File

@ -15,6 +15,22 @@ object ColorHelper {
} }
} }
fun getFontColorAlpha(): Int {
return try {
Preferences.textGlobalAlpha.toIntValue().toDouble() * 255 / 100
} catch (e: Exception) {
"FF".toIntValue().toDouble() * 255 / 100
}.roundToInt()
}
fun getFontColorRgb(): Int {
return try {
Color.parseColor(Preferences.textGlobalColor)
} catch (e: Exception) {
Color.parseColor("#000000")
}
}
fun getBackgroundColor(): Int { fun getBackgroundColor(): Int {
return try { return try {
Color.parseColor("#%s%s".format(Preferences.backgroundCardAlpha, Preferences.backgroundCardColor.replace("#", ""))) Color.parseColor("#%s%s".format(Preferences.backgroundCardAlpha, Preferences.backgroundCardColor.replace("#", "")))

View File

@ -1,5 +1,6 @@
package com.tommasoberlose.anotherwidget.helpers package com.tommasoberlose.anotherwidget.helpers
import android.appwidget.AppWidgetManager
import android.content.ComponentName import android.content.ComponentName
import android.content.ContentUris import android.content.ContentUris
import android.content.Context import android.content.Context
@ -12,11 +13,23 @@ import android.provider.CalendarContract.Events
import android.util.Log import android.util.Log
import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.models.Event import com.tommasoberlose.anotherwidget.models.Event
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
import java.util.*
object IntentHelper { object IntentHelper {
fun getGoogleMapsIntentFromAddress(context: Context, address:String): Intent { fun getWidgetUpdateIntent(context: Context): Intent {
val widgetManager = AppWidgetManager.getInstance(context)
val widgetComponent = ComponentName(context, MainWidget::class.java)
val widgetIds = widgetManager.getAppWidgetIds(widgetComponent)
return Intent(context, MainWidget::class.java).apply {
putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, widgetIds)
action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
}
}
fun getGoogleMapsIntentFromAddress(context: Context, address: String): Intent {
val gmmIntentUri: Uri = Uri.parse("geo:0,0?q=$address") val gmmIntentUri: Uri = Uri.parse("geo:0,0?q=$address")
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri) val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
mapIntent.`package` = "com.google.android.apps.maps" mapIntent.`package` = "com.google.android.apps.maps"
@ -63,11 +76,15 @@ object IntentHelper {
} }
fun getCalendarIntent(context: Context): Intent { fun getCalendarIntent(context: Context): Intent {
val calendarUri = CalendarContract.CONTENT_URI
.buildUpon()
.appendPath("time")
.appendPath(Calendar.getInstance().timeInMillis.toString())
.build()
return when (Preferences.calendarAppPackage) { return when (Preferences.calendarAppPackage) {
"" -> { "" -> {
Intent(Intent.ACTION_MAIN).apply { Intent(Intent.ACTION_VIEW).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) data = calendarUri
addCategory(Intent.CATEGORY_APP_CALENDAR)
} }
} }
"_" -> { "_" -> {
@ -77,14 +94,13 @@ object IntentHelper {
val pm: PackageManager = context.packageManager val pm: PackageManager = context.packageManager
try { try {
pm.getLaunchIntentForPackage(Preferences.calendarAppPackage)!!.apply { pm.getLaunchIntentForPackage(Preferences.calendarAppPackage)!!.apply {
addCategory(Intent.CATEGORY_LAUNCHER) action = Intent.ACTION_VIEW
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) data = calendarUri
} }
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
Intent(Intent.ACTION_MAIN).apply { Intent(Intent.ACTION_VIEW).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) data = calendarUri
addCategory(Intent.CATEGORY_APP_CALENDAR)
} }
} }
} }
@ -98,9 +114,10 @@ object IntentHelper {
if (Preferences.calendarAppPackage == "") { if (Preferences.calendarAppPackage == "") {
Intent(Intent.ACTION_VIEW).apply { Intent(Intent.ACTION_VIEW).apply {
data = uri data = uri
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, e.startDate) putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, e.startDate)
putExtra(CalendarContract.EXTRA_EVENT_END_TIME, e.endDate) putExtra(CalendarContract.EXTRA_EVENT_END_TIME, e.endDate)
// putExtra(CalendarContract.EXTRA_EVENT_ALL_DAY, if (e.allDay) 1 else 0)
// type = "vnd.android.cursor.item/event"
} }
} else { } else {
getCalendarIntent(context).apply { getCalendarIntent(context).apply {
@ -108,6 +125,8 @@ object IntentHelper {
data = uri data = uri
putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, e.startDate) putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, e.startDate)
putExtra(CalendarContract.EXTRA_EVENT_END_TIME, e.endDate) putExtra(CalendarContract.EXTRA_EVENT_END_TIME, e.endDate)
// putExtra(CalendarContract.EXTRA_EVENT_ALL_DAY, if (e.allDay) 1 else 0)
// type = "vnd.android.cursor.item/event"
} }
} }
} }

View File

@ -73,7 +73,7 @@ object SettingsStringHelper {
return "" return ""
} }
TimeUnit.MILLISECONDS.toHours(difference) < 12 -> { TimeUnit.MILLISECONDS.toHours(difference) < 12 -> {
return DateUtils.getRelativeTimeSpanString(start, now, DateUtils.HOUR_IN_MILLIS).toString() return DateUtils.getRelativeTimeSpanString(start, now, DateUtils.HOUR_IN_MILLIS, DateUtils.FORMAT_ABBREV_RELATIVE).toString()
} }
eventDate.dayOfYear == nowDate.plusDays(1).dayOfYear -> { eventDate.dayOfYear == nowDate.plusDays(1).dayOfYear -> {
return String.format("%s", context.getString(R.string.tomorrow)) return String.format("%s", context.getString(R.string.tomorrow))
@ -82,7 +82,7 @@ object SettingsStringHelper {
return String.format("%s", context.getString(R.string.today)) return String.format("%s", context.getString(R.string.today))
} }
else -> { else -> {
return DateUtils.getRelativeTimeSpanString(start, now, DateUtils.DAY_IN_MILLIS).toString() return DateUtils.getRelativeTimeSpanString(start, now, DateUtils.DAY_IN_MILLIS, DateUtils.FORMAT_ABBREV_RELATIVE).toString()
} }
} }

View File

@ -3,6 +3,7 @@ package com.tommasoberlose.anotherwidget.helpers
import android.Manifest import android.Manifest
import android.content.Context import android.content.Context
import android.os.Build import android.os.Build
import android.util.EventLog
import android.util.Log import android.util.Log
import com.google.android.gms.location.LocationServices import com.google.android.gms.location.LocationServices
import com.kwabenaberko.openweathermaplib.constants.Units import com.kwabenaberko.openweathermaplib.constants.Units
@ -12,8 +13,11 @@ import com.kwabenaberko.openweathermaplib.models.currentweather.CurrentWeather
import com.tommasoberlose.anotherwidget.R import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.network.WeatherNetworkApi import com.tommasoberlose.anotherwidget.network.WeatherNetworkApi
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.fragments.AppMainFragment
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
import org.greenrobot.eventbus.EventBus
/** /**
@ -35,6 +39,7 @@ object WeatherHelper {
Preferences.customLocationLon = location.longitude.toString() Preferences.customLocationLon = location.longitude.toString()
networkApi.updateWeather() networkApi.updateWeather()
EventBus.getDefault().post(AppMainFragment.UpdateUiMessageEvent())
} }
} }
} }

View File

@ -3,6 +3,7 @@ package com.tommasoberlose.anotherwidget.helpers
import android.appwidget.AppWidgetManager import android.appwidget.AppWidgetManager
import android.content.Context import android.content.Context
import android.content.res.Configuration.ORIENTATION_PORTRAIT import android.content.res.Configuration.ORIENTATION_PORTRAIT
import com.google.firebase.crashlytics.FirebaseCrashlytics
object WidgetHelper { object WidgetHelper {
class WidgetSizeProvider( class WidgetSizeProvider(
@ -16,6 +17,8 @@ object WidgetHelper {
val height = getWidgetHeight(isPortrait, widgetId) val height = getWidgetHeight(isPortrait, widgetId)
val widthInPx = context.dip(width) val widthInPx = context.dip(width)
val heightInPx = context.dip(height) val heightInPx = context.dip(height)
FirebaseCrashlytics.getInstance().setCustomKey("widthInPx", widthInPx)
FirebaseCrashlytics.getInstance().setCustomKey("heightInPx", heightInPx)
return widthInPx to heightInPx return widthInPx to heightInPx
} }

View File

@ -16,6 +16,6 @@ open class Event(var id: Long = 0,
var allDay: Boolean = false, var allDay: Boolean = false,
var address: String = "") : RealmObject() { var address: String = "") : RealmObject() {
override fun toString(): String { override fun toString(): String {
return "Event:\nID: " + eventID + "\nTITLE: " + title + "\nSTART DATE: " + Date(startDate) + "\nEND DATE: " + Date(endDate) + "\nCAL ID: " + calendarID + "\nADDRESS: " + address return "Event:\nEVENT ID: " + eventID + "\nTITLE: " + title + "\nSTART DATE: " + Date(startDate) + "\nEND DATE: " + Date(endDate) + "\nCAL ID: " + calendarID + "\nADDRESS: " + address
} }
} }

View File

@ -9,6 +9,7 @@ import com.kwabenaberko.openweathermaplib.models.currentweather.CurrentWeather
import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.WeatherHelper import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.fragments.AppMainFragment
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
@ -26,7 +27,7 @@ class WeatherNetworkApi(val context: Context) {
Preferences.weatherRealTempUnit = Preferences.weatherTempUnit Preferences.weatherRealTempUnit = Preferences.weatherTempUnit
MainWidget.updateWidget(context) MainWidget.updateWidget(context)
EventBus.getDefault().post(MainActivity.UpdateUiMessageEvent()) EventBus.getDefault().post(AppMainFragment.UpdateUiMessageEvent())
} }
} }

View File

@ -0,0 +1,32 @@
package com.tommasoberlose.anotherwidget.receivers
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.util.Log
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.tommasoberlose.anotherwidget.global.Actions
import java.lang.Exception
class CrashlyticsReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == Actions.ACTION_REPORT_CRASH) {
val exception: Exception = intent.getSerializableExtra(EXCEPTION) as Exception
FirebaseCrashlytics.getInstance().recordException(exception)
FirebaseCrashlytics.getInstance().sendUnsentReports()
}
}
companion object {
private const val EXCEPTION = "EXCEPTION"
fun sendCrash(context: Context, exception: Exception) {
context.sendBroadcast(Intent(context, CrashlyticsReceiver::class.java).apply {
action = Actions.ACTION_REPORT_CRASH
putExtra(EXCEPTION, exception)
})
}
}
}

View File

@ -0,0 +1,22 @@
package com.tommasoberlose.anotherwidget.receivers
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.util.Log
class PlayerReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.d("ciao", "player ok")
// val cmd = intent.getStringExtra("command")
// Log.v("tag ", "$action / $cmd")
// val artist = intent.getStringExtra("artist")
// val album = intent.getStringExtra("album")
// val track = intent.getStringExtra("track")
// Log.v("tag", "$artist:$album:$track")
}
}

View File

@ -19,7 +19,6 @@ import java.util.*
class UpdatesReceiver : BroadcastReceiver() { class UpdatesReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
Log.d("ciao", "che palle - ${intent.action}")
when (intent.action) { when (intent.action) {
Intent.ACTION_BOOT_COMPLETED, Intent.ACTION_BOOT_COMPLETED,
Intent.ACTION_MY_PACKAGE_REPLACED, Intent.ACTION_MY_PACKAGE_REPLACED,
@ -32,7 +31,6 @@ class UpdatesReceiver : BroadcastReceiver() {
Intent.ACTION_DATE_CHANGED, Intent.ACTION_DATE_CHANGED,
AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED, AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED,
Actions.ACTION_TIME_UPDATE -> { Actions.ACTION_TIME_UPDATE -> {
Log.d("ciao", "force update? 4 - ${intent.action}")
MainWidget.updateWidget(context) MainWidget.updateWidget(context)
} }
} }
@ -55,13 +53,12 @@ class UpdatesReceiver : BroadcastReceiver() {
if (event.startDate > now.timeInMillis) { if (event.startDate > now.timeInMillis) {
// Update the widget every hour till the event // Update the widget every hour till the event
(0..diff.hours).forEach { (0..diff.hours).forEach {
AlarmManagerCompat.setExactAndAllowWhileIdle( setExactAndAllowWhileIdle(
this, AlarmManager.RTC,
AlarmManager.RTC_WAKEUP, if (event.startDate - it * 1000 * 60 * 60 > 60 * 1000) event.startDate - it * 1000 * 60 * 60 else now.timeInMillis + 120000,
if (event.startDate - it * 1000 * 60 * 60 > 60 * 1000) event.startDate - it * 1000 * 60 * 60 else 120000,
PendingIntent.getBroadcast( PendingIntent.getBroadcast(
context, context,
0, event.eventID.toInt() + it,
Intent(context, UpdatesReceiver::class.java).apply { Intent(context, UpdatesReceiver::class.java).apply {
action = Actions.ACTION_TIME_UPDATE action = Actions.ACTION_TIME_UPDATE
}, },
@ -72,17 +69,23 @@ class UpdatesReceiver : BroadcastReceiver() {
} }
// Update the widget one second after the event is finished // Update the widget one second after the event is finished
AlarmManagerCompat.setExactAndAllowWhileIdle(this, setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP, AlarmManager.RTC,
if (event.endDate > 60 *1000) event.endDate else 120000, if (event.endDate > 60 *1000) event.endDate else now.timeInMillis + 120000,
PendingIntent.getBroadcast(context, 0, Intent(context, UpdatesReceiver::class.java).apply { action = Actions.ACTION_TIME_UPDATE }, 0)) PendingIntent.getBroadcast(context, 1, Intent(context, UpdatesReceiver::class.java).apply { action = Actions.ACTION_TIME_UPDATE }, 0)
)
} }
} }
} }
fun removeUpdates(context: Context) { fun removeUpdates(context: Context) {
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) { with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
cancel(PendingIntent.getBroadcast(context, 0, Intent(context, UpdatesReceiver::class.java), 0)) cancel(PendingIntent.getBroadcast(context, 1, Intent(context, UpdatesReceiver::class.java), 0))
EventRepository(context).getEvents().forEach {
(0..24).forEach { hour ->
cancel(PendingIntent.getBroadcast(context, it.eventID.toInt() * hour, Intent(context, UpdatesReceiver::class.java), 0))
}
}
} }
} }
} }

View File

@ -5,10 +5,10 @@ import android.app.PendingIntent
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.util.Log
import com.tommasoberlose.anotherwidget.global.Actions import com.tommasoberlose.anotherwidget.global.Actions
import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.WeatherHelper import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
import com.tommasoberlose.anotherwidget.services.WeatherWorker
import java.util.* import java.util.*
@ -20,7 +20,61 @@ class WeatherReceiver : BroadcastReceiver() {
Intent.ACTION_MY_PACKAGE_REPLACED, Intent.ACTION_MY_PACKAGE_REPLACED,
Intent.ACTION_TIMEZONE_CHANGED, Intent.ACTION_TIMEZONE_CHANGED,
Intent.ACTION_LOCALE_CHANGED, Intent.ACTION_LOCALE_CHANGED,
Intent.ACTION_TIME_CHANGED -> WeatherWorker.setUpdates(context) Intent.ACTION_TIME_CHANGED -> setUpdates(context)
Actions.ACTION_WEATHER_UPDATE -> {
WeatherHelper.updateWeather(context)
}
}
}
companion object {
private const val MINUTE = 60 * 1000L
fun setUpdates(context: Context) {
removeUpdates(context)
if (Preferences.showWeather && Preferences.weatherProviderApi != "") {
val interval = MINUTE * when (Preferences.weatherRefreshPeriod) {
0 -> 30
1 -> 60
2 -> 60L * 3
3 -> 60L * 6
4 -> 60L * 12
5 -> 60L * 24
else -> 60
}
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
setRepeating(
AlarmManager.RTC,
Calendar.getInstance().timeInMillis,
interval,
PendingIntent.getBroadcast(context, 0, Intent(context, WeatherReceiver::class.java).apply { action = Actions.ACTION_WEATHER_UPDATE }, 0)
)
}
}
}
fun setOneTimeUpdate(context: Context) {
if (Preferences.showWeather && Preferences.weatherProviderApi != "") {
listOf(10, 20, 30).forEach {
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
setExactAndAllowWhileIdle(
AlarmManager.RTC,
it * MINUTE,
PendingIntent.getBroadcast(context, it, Intent(context, WeatherReceiver::class.java).apply { action = Actions.ACTION_WEATHER_UPDATE }, 0)
)
}
}
}
}
fun removeUpdates(context: Context) {
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
cancel(PendingIntent.getBroadcast(context, 0, Intent(context, WeatherReceiver::class.java).apply { action = Actions.ACTION_WEATHER_UPDATE }, 0))
listOf(10, 20, 30).forEach {
cancel(PendingIntent.getBroadcast(context, it, Intent(context, WeatherReceiver::class.java).apply { action = Actions.ACTION_WEATHER_UPDATE }, 0))
}
}
} }
} }
} }

View File

@ -1,64 +0,0 @@
package com.tommasoberlose.anotherwidget.services
import android.app.AlarmManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.util.Log
import androidx.work.*
import com.tommasoberlose.anotherwidget.global.Actions
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
import com.tommasoberlose.anotherwidget.receivers.WeatherReceiver
import java.util.*
import java.util.concurrent.TimeUnit
class WeatherWorker(appContext: Context, workerParams: WorkerParameters) : Worker(appContext, workerParams) {
override fun doWork(): Result {
Log.d("ciao1", "weather ok")
WeatherHelper.updateWeather(applicationContext)
return Result.success()
}
companion object {
private const val JOB_TAG = "WEATHER_WORKER"
fun setUpdates(context: Context) {
removeUpdates(context)
if (Preferences.showWeather && Preferences.weatherProviderApi != "") {
WeatherHelper.updateWeather(context)
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
"WEATHER_JOB_PERIODIC",
ExistingPeriodicWorkPolicy.KEEP,
PeriodicWorkRequestBuilder<WeatherWorker>(
when (Preferences.weatherRefreshPeriod) {
0 -> 30
1 -> 60
2 -> 60L * 3
3 -> 60L * 6
4 -> 60L * 12
5 -> 60L * 24
else -> 60
}
, TimeUnit.MINUTES
)
.addTag(JOB_TAG)
.build()
)
}
}
fun setOneTimeUpdate(context: Context) {
val workManager = WorkManager.getInstance(context)
listOf(10L, 20L, 30L).forEach {
workManager.enqueueUniqueWork("WEATHER_JOB_ONE_TIME_$it", ExistingWorkPolicy.KEEP, OneTimeWorkRequestBuilder<WeatherWorker>().setInitialDelay(it, TimeUnit.MINUTES).addTag(JOB_TAG).build())
}
}
fun removeUpdates(context: Context) {
WorkManager.getInstance(context).cancelAllWorkByTag(JOB_TAG)
}
}
}

View File

@ -6,12 +6,15 @@ import android.app.Activity
import android.appwidget.AppWidgetManager import android.appwidget.AppWidgetManager
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.graphics.Bitmap
import android.graphics.Matrix
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.provider.Settings import android.provider.Settings
import android.util.DisplayMetrics
import android.util.Log
import android.util.TypedValue import android.util.TypedValue
import android.view.Gravity
import android.view.View import android.view.View
import android.widget.RelativeLayout import android.widget.RelativeLayout
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
@ -21,8 +24,15 @@ import androidx.core.view.isVisible
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavController
import androidx.navigation.Navigation
import com.google.android.material.badge.BadgeDrawable import com.google.android.material.badge.BadgeDrawable
import com.google.android.material.tabs.TabLayoutMediator import com.google.android.material.tabs.TabLayoutMediator
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.R
import com.tommasoberlose.anotherwidget.components.MaterialBottomSheetDialog import com.tommasoberlose.anotherwidget.components.MaterialBottomSheetDialog
import com.tommasoberlose.anotherwidget.global.Actions import com.tommasoberlose.anotherwidget.global.Actions
@ -47,10 +57,16 @@ import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode import org.greenrobot.eventbus.ThreadMode
class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceChangeListener { class MainActivity : AppCompatActivity() {
private var mAppWidgetId: Int = -1 private var mAppWidgetId: Int = -1
private lateinit var viewModel: MainViewModel private lateinit var viewModel: MainViewModel
private val mainNavController: NavController? by lazy {
Navigation.findNavController(
this,
R.id.content_fragment
)
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -59,228 +75,19 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
viewModel = ViewModelProvider(this).get(MainViewModel::class.java) viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
controlExtras(intent) controlExtras(intent)
requirePermission()
// Viewpager
pager.adapter = ViewPagerAdapter(this)
pager.offscreenPageLimit = 4
TabLayoutMediator(tabs, pager) { tab, position ->
tab.text = when (position) {
0 -> getString(R.string.settings_general_title)
1 -> getString(R.string.settings_calendar_title)
2 -> getString(R.string.settings_weather_title)
3 -> getString(R.string.settings_clock_title)
4 -> getString(R.string.advanced_settings_title)
else -> ""
}
}.attach()
// Init clock
time.setTextColor(ColorHelper.getFontColor())
time.setTextSize(TypedValue.COMPLEX_UNIT_SP, Preferences.clockTextSize.toPixel(this@MainActivity))
time_am_pm.setTextColor(ColorHelper.getFontColor())
time_am_pm.setTextSize(TypedValue.COMPLEX_UNIT_SP, Preferences.clockTextSize.toPixel(this@MainActivity) / 5 * 2)
time_container.isVisible = Preferences.showClock
preview.layoutParams = preview.layoutParams.apply {
height = 160.toPixel(this@MainActivity) + if (Preferences.showClock) 100.toPixel(this@MainActivity) else 0
}
Preferences.preferences.registerOnSharedPreferenceChangeListener(this)
subscribeUi(viewModel)
updateUI()
WeatherHelper.updateWeather(this)
// Warnings
if (getString(R.string.xiaomi_manufacturer).equals(Build.MANUFACTURER, ignoreCase = true) && Preferences.showXiaomiWarning) {
MaterialBottomSheetDialog(this, getString(R.string.xiaomi_warning_title), getString(R.string.xiaomi_warning_message))
.setNegativeButton(getString(R.string.action_ignore)) {
Preferences.showXiaomiWarning = false
}
.setPositiveButton(getString(R.string.action_grant_permission)) {
Preferences.showXiaomiWarning = false
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
data = Uri.parse("package:$packageName")
}
startActivity(intent)
}
.show()
}
}
private var uiJob: Job? = null
private fun updateUI() {
uiJob?.cancel()
if (Preferences.showPreview) {
preview.setCardBackgroundColor(
getColor(
if (ColorHelper.getFontColor()
.isColorDark()
) android.R.color.white else R.color.colorAccent
)
)
widget_shape_background.setImageDrawable(BitmapHelper.getTintedDrawable(this, R.drawable.card_background, ColorHelper.getBackgroundColor()))
uiJob = lifecycleScope.launch(Dispatchers.IO) {
delay(200)
val generatedView = MainWidget.generateWidgetView(this@MainActivity)
withContext(Dispatchers.Main) {
generatedView.measure(0, 0)
preview.measure(0, 0)
}
val bitmap = BitmapHelper.getBitmapFromView(
generatedView,
if (preview.width > 0) preview.width else generatedView.measuredWidth,
generatedView.measuredHeight
)
withContext(Dispatchers.Main) {
// Clock
time.setTextColor(ColorHelper.getFontColor())
time_am_pm.setTextColor(ColorHelper.getFontColor())
time.setTextSize(
TypedValue.COMPLEX_UNIT_SP,
Preferences.clockTextSize.toPixel(this@MainActivity)
)
time_am_pm.setTextSize(
TypedValue.COMPLEX_UNIT_SP,
Preferences.clockTextSize.toPixel(this@MainActivity) / 5 * 2
)
// Clock bottom margin
clock_bottom_margin_none.isVisible =
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.NONE.value
clock_bottom_margin_small.isVisible =
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.SMALL.value
clock_bottom_margin_medium.isVisible =
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.MEDIUM.value
clock_bottom_margin_large.isVisible =
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.LARGE.value
if ((Preferences.showClock && !time_container.isVisible) || (!Preferences.showClock && time_container.isVisible)) {
if (Preferences.showClock) {
time_container.layoutParams = time_container.layoutParams.apply {
height = RelativeLayout.LayoutParams.WRAP_CONTENT
}
time_container.measure(0, 0)
}
val initialHeight = time_container.measuredHeight
ValueAnimator.ofFloat(
if (Preferences.showClock) 0f else 1f,
if (Preferences.showClock) 1f else 0f
).apply {
duration = 500L
addUpdateListener {
val animatedValue = animatedValue as Float
time_container.layoutParams = time_container.layoutParams.apply {
height = (initialHeight * animatedValue).toInt()
}
}
addListener(
onStart = {
if (Preferences.showClock) {
time_container.isVisible = true
}
},
onEnd = {
if (!Preferences.showClock) {
time_container.isVisible = false
}
}
)
}.start()
ValueAnimator.ofInt(
preview.height,
160.toPixel(this@MainActivity) + if (Preferences.showClock) 100.toPixel(
this@MainActivity
) else 0
).apply {
duration = 500L
addUpdateListener {
val animatedValue = animatedValue as Int
val layoutParams = preview.layoutParams
layoutParams.height = animatedValue
preview.layoutParams = layoutParams
}
}.start()
} else {
time_container.layoutParams = time_container.layoutParams.apply {
height = RelativeLayout.LayoutParams.WRAP_CONTENT
}
time_container.measure(0, 0)
}
if (preview.height == 0) {
ValueAnimator.ofInt(
preview.height,
160.toPixel(this@MainActivity) + if (Preferences.showClock) 100.toPixel(
this@MainActivity
) else 0
).apply {
duration = 300L
addUpdateListener {
val animatedValue = animatedValue as Int
val layoutParams = preview.layoutParams
layoutParams.height = animatedValue
preview.layoutParams = layoutParams
}
}.start()
}
bitmap_container.setImageBitmap(bitmap)
widget_loader.animate().scaleX(0f).scaleY(0f).start()
widget.animate().alpha(1f).start()
}
}
} else {
ValueAnimator.ofInt(
preview.height,
0
).apply {
duration = 300L
addUpdateListener {
val animatedValue = animatedValue as Int
val layoutParams = preview.layoutParams
layoutParams.height = animatedValue
preview.layoutParams = layoutParams
}
}.start()
}
// Calendar error indicator
tabs.getTabAt(1)?.orCreateBadge?.apply {
backgroundColor = ContextCompat.getColor(this@MainActivity, R.color.errorColorText)
badgeGravity = BadgeDrawable.TOP_END
}?.isVisible = Preferences.showEvents && !checkGrantedPermission(Manifest.permission.READ_CALENDAR)
// Weather error indicator
tabs.getTabAt(2)?.orCreateBadge?.apply {
backgroundColor = ContextCompat.getColor(this@MainActivity, R.color.errorColorText)
badgeGravity = BadgeDrawable.TOP_END
}?.isVisible = Preferences.showWeather && (Preferences.weatherProviderApi == "" || (Preferences.customLocationAdd == "" && !checkGrantedPermission(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION)))
}
private fun subscribeUi(viewModel: MainViewModel) {
viewModel.showWallpaper.observe(this, Observer {
widget_bg.setImageDrawable(if (it) getCurrentWallpaper() else null)
})
logo.setOnClickListener {
// startActivity(Intent(this, SupportDevActivity::class.java))
}
} }
override fun onBackPressed() { override fun onBackPressed() {
if (mAppWidgetId > 0) { if (mainNavController?.currentDestination?.id == R.id.appMainFragment) {
addNewWidget() if (mAppWidgetId > 0) {
addNewWidget()
} else {
setResult(Activity.RESULT_OK)
finish()
}
} else { } else {
setResult(Activity.RESULT_OK) super.onBackPressed()
finish()
} }
} }
@ -320,30 +127,27 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
finish() finish()
} }
override fun onDestroy() { private fun requirePermission() {
super.onDestroy() Dexter.withContext(this)
Preferences.preferences.unregisterOnSharedPreferenceChangeListener(this) .withPermissions(
} Manifest.permission.READ_EXTERNAL_STORAGE
).withListener(object : MultiplePermissionsListener {
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
report?.let {
Preferences.showWallpaper = false
Preferences.showWallpaper = report.areAllPermissionsGranted()
}
}
override fun onSharedPreferenceChanged(preferences: SharedPreferences, p1: String) { override fun onPermissionRationaleShouldBeShown(
updateUI() permissions: MutableList<PermissionRequest>?,
MainWidget.updateWidget(this) token: PermissionToken?
} ) {
// Remember to invoke this method when the custom rationale is closed
override fun onStart() { // or just by default if you don't want to use any custom rationale.
super.onStart() token?.cancelPermissionRequest()
EventBus.getDefault().register(this) }
} })
.check()
override fun onStop() {
super.onStop()
EventBus.getDefault().unregister(this)
}
class UpdateUiMessageEvent
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(ignore: UpdateUiMessageEvent?) {
updateUI()
} }
} }

View File

@ -8,14 +8,13 @@ import com.tommasoberlose.anotherwidget.ui.fragments.*
class ViewPagerAdapter(fragmentActivity: FragmentActivity) : class ViewPagerAdapter(fragmentActivity: FragmentActivity) :
FragmentStateAdapter(fragmentActivity) { FragmentStateAdapter(fragmentActivity) {
override fun getItemCount(): Int = 5 override fun getItemCount(): Int = 4
override fun createFragment(position: Int): Fragment { override fun createFragment(position: Int): Fragment {
return when (position) { return when (position) {
1 -> CalendarSettingsFragment.newInstance() 1 -> CalendarSettingsFragment.newInstance()
2 -> WeatherSettingsFragment.newInstance() 2 -> WeatherSettingsFragment.newInstance()
3 -> ClockSettingsFragment.newInstance() 3 -> ClockSettingsFragment.newInstance()
4 -> AdvancedSettingsFragment.newInstance()
else -> GeneralSettingsFragment.newInstance() else -> GeneralSettingsFragment.newInstance()
} }
} }

View File

@ -0,0 +1,333 @@
package com.tommasoberlose.anotherwidget.ui.fragments
import android.Manifest
import android.animation.ValueAnimator
import android.content.Intent
import android.content.SharedPreferences
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.util.DisplayMetrics
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.RelativeLayout
import androidx.core.animation.addListener
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.navigation.Navigation
import androidx.navigation.fragment.FragmentNavigator
import com.google.android.material.badge.BadgeDrawable
import com.google.android.material.tabs.TabLayoutMediator
import com.google.android.material.transition.MaterialSharedAxis
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.components.MaterialBottomSheetDialog
import com.tommasoberlose.anotherwidget.databinding.FragmentAdvancedSettingsBinding
import com.tommasoberlose.anotherwidget.databinding.FragmentAppMainBinding
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.BitmapHelper
import com.tommasoberlose.anotherwidget.helpers.ColorHelper
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.adapters.ViewPagerAdapter
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
import com.tommasoberlose.anotherwidget.utils.getCurrentWallpaper
import com.tommasoberlose.anotherwidget.utils.toPixel
import kotlinx.android.synthetic.main.fragment_app_main.*
import kotlinx.android.synthetic.main.the_widget_sans.*
import kotlinx.coroutines.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
class AppMainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeListener {
companion object {
fun newInstance() = AppMainFragment()
}
private lateinit var viewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enterTransition = MaterialSharedAxis.create(MaterialSharedAxis.X, true)
reenterTransition = MaterialSharedAxis.create(MaterialSharedAxis.X, false)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
return inflater.inflate(R.layout.fragment_app_main, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
subscribeUi(viewModel)
// Viewpager
pager.adapter = ViewPagerAdapter(requireActivity())
pager.offscreenPageLimit = 4
TabLayoutMediator(tabs, pager) { tab, position ->
tab.text = when (position) {
0 -> getString(R.string.settings_general_title)
1 -> getString(R.string.settings_calendar_title)
2 -> getString(R.string.settings_weather_title)
3 -> getString(R.string.settings_clock_title)
else -> ""
}
}.attach()
// Init clock
time.setTextColor(ColorHelper.getFontColor())
time.setTextSize(TypedValue.COMPLEX_UNIT_SP, Preferences.clockTextSize.toPixel(requireContext()))
time_am_pm.setTextColor(ColorHelper.getFontColor())
time_am_pm.setTextSize(TypedValue.COMPLEX_UNIT_SP, Preferences.clockTextSize.toPixel(requireContext()) / 5 * 2)
time_container.isVisible = Preferences.showClock
preview.layoutParams = preview.layoutParams.apply {
height = 160.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(requireContext()) else 0
}
subscribeUi(viewModel)
updateUI()
// Warnings
if (getString(R.string.xiaomi_manufacturer).equals(Build.MANUFACTURER, ignoreCase = true) && Preferences.showXiaomiWarning) {
MaterialBottomSheetDialog(requireContext(), getString(R.string.xiaomi_warning_title), getString(R.string.xiaomi_warning_message))
.setNegativeButton(getString(R.string.action_ignore)) {
Preferences.showXiaomiWarning = false
}
.setPositiveButton(getString(R.string.action_grant_permission)) {
Preferences.showXiaomiWarning = false
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
data = Uri.parse("package:${activity?.packageName}")
}
startActivity(intent)
}
.show()
}
}
private var uiJob: Job? = null
private fun updateUI() {
uiJob?.cancel()
if (Preferences.showPreview) {
preview.setCardBackgroundColor(
ContextCompat.getColor(
requireContext(),
if (ColorHelper.getFontColor()
.isColorDark()
) android.R.color.white else R.color.colorAccent
)
)
widget_shape_background.setImageDrawable(BitmapHelper.getTintedDrawable(requireContext(), R.drawable.card_background, ColorHelper.getBackgroundColor()))
uiJob = viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
delay(200)
val generatedView = MainWidget.generateWidgetView(requireContext())
withContext(Dispatchers.Main) {
generatedView.measure(0, 0)
preview.measure(0, 0)
}
val bitmap = BitmapHelper.getBitmapFromView(
generatedView,
if (preview.width > 0) preview.width else generatedView.measuredWidth,
generatedView.measuredHeight
)
withContext(Dispatchers.Main) {
// Clock
time.setTextColor(ColorHelper.getFontColor())
time_am_pm.setTextColor(ColorHelper.getFontColor())
time.setTextSize(
TypedValue.COMPLEX_UNIT_SP,
Preferences.clockTextSize.toPixel(requireContext())
)
time_am_pm.setTextSize(
TypedValue.COMPLEX_UNIT_SP,
Preferences.clockTextSize.toPixel(requireContext()) / 5 * 2
)
// Clock bottom margin
clock_bottom_margin_none.isVisible =
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.NONE.value
clock_bottom_margin_small.isVisible =
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.SMALL.value
clock_bottom_margin_medium.isVisible =
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.MEDIUM.value
clock_bottom_margin_large.isVisible =
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.LARGE.value
if ((Preferences.showClock && !time_container.isVisible) || (!Preferences.showClock && time_container.isVisible)) {
if (Preferences.showClock) {
time_container.layoutParams = time_container.layoutParams.apply {
height = RelativeLayout.LayoutParams.WRAP_CONTENT
}
time_container.measure(0, 0)
}
val initialHeight = time_container.measuredHeight
ValueAnimator.ofFloat(
if (Preferences.showClock) 0f else 1f,
if (Preferences.showClock) 1f else 0f
).apply {
duration = 500L
addUpdateListener {
val animatedValue = animatedValue as Float
time_container.layoutParams = time_container.layoutParams.apply {
height = (initialHeight * animatedValue).toInt()
}
}
addListener(
onStart = {
if (Preferences.showClock) {
time_container.isVisible = true
}
},
onEnd = {
if (!Preferences.showClock) {
time_container.isVisible = false
}
}
)
}.start()
ValueAnimator.ofInt(
preview.height,
160.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(
requireContext()
) else 0
).apply {
duration = 500L
addUpdateListener {
val animatedValue = animatedValue as Int
val layoutParams = preview.layoutParams
layoutParams.height = animatedValue
preview.layoutParams = layoutParams
}
}.start()
} else {
time_container.layoutParams = time_container.layoutParams.apply {
height = RelativeLayout.LayoutParams.WRAP_CONTENT
}
time_container.measure(0, 0)
}
if (preview.height == 0) {
ValueAnimator.ofInt(
preview.height,
160.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(
requireContext()
) else 0
).apply {
duration = 300L
addUpdateListener {
val animatedValue = animatedValue as Int
val layoutParams = preview.layoutParams
layoutParams.height = animatedValue
preview.layoutParams = layoutParams
}
}.start()
}
bitmap_container.setImageBitmap(bitmap)
widget_loader.animate().scaleX(0f).scaleY(0f).start()
widget.animate().alpha(1f).start()
}
}
} else {
ValueAnimator.ofInt(
preview.height,
0
).apply {
duration = 300L
addUpdateListener {
val animatedValue = animatedValue as Int
val layoutParams = preview.layoutParams
layoutParams.height = animatedValue
preview.layoutParams = layoutParams
}
}.start()
}
// Calendar error indicator
tabs?.getTabAt(1)?.orCreateBadge?.apply {
backgroundColor = ContextCompat.getColor(requireContext(), R.color.errorColorText)
badgeGravity = BadgeDrawable.TOP_END
}?.isVisible = Preferences.showEvents && activity?.checkGrantedPermission(Manifest.permission.READ_CALENDAR) != true
// Weather error indicator
tabs?.getTabAt(2)?.orCreateBadge?.apply {
backgroundColor = ContextCompat.getColor(requireContext(), R.color.errorColorText)
badgeGravity = BadgeDrawable.TOP_END
}?.isVisible = Preferences.showWeather && (Preferences.weatherProviderApi == "" || (Preferences.customLocationAdd == "" && activity?.checkGrantedPermission(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION) != true))
}
private fun subscribeUi(viewModel: MainViewModel) {
viewModel.showWallpaper.observe(viewLifecycleOwner, Observer {
activity?.let { act ->
val wallpaper = act.getCurrentWallpaper()
widget_bg.setImageDrawable(if (it) wallpaper else null)
widget_bg.layoutParams = widget_bg.layoutParams.apply {
val metrics = DisplayMetrics()
act.windowManager.defaultDisplay.getMetrics(metrics)
height = metrics.heightPixels
width = (wallpaper?.intrinsicWidth ?: 1) * metrics.heightPixels / (wallpaper?.intrinsicWidth ?: 1)
}
}
})
logo.setOnClickListener {
// startActivity(Intent(this, SupportDevActivity::class.java))
}
action_settings.setOnClickListener {
Navigation.findNavController(it).navigate(R.id.action_appMainFragment_to_appSettingsFragment)
}
}
override fun onDestroy() {
super.onDestroy()
}
override fun onSharedPreferenceChanged(preferences: SharedPreferences, p1: String) {
updateUI()
MainWidget.updateWidget(requireContext())
}
override fun onResume() {
super.onResume()
Preferences.preferences.registerOnSharedPreferenceChangeListener(this)
EventBus.getDefault().register(this)
}
override fun onPause() {
Preferences.preferences.unregisterOnSharedPreferenceChangeListener(this)
EventBus.getDefault().unregister(this)
super.onPause()
}
class UpdateUiMessageEvent
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(ignore: UpdateUiMessageEvent?) {
updateUI()
}
}

View File

@ -156,6 +156,9 @@ class CalendarSettingsFragment : Fragment() {
action_show_events.setOnClickListener { action_show_events.setOnClickListener {
Preferences.showEvents = !Preferences.showEvents Preferences.showEvents = !Preferences.showEvents
if (Preferences.showEvents) {
requirePermission()
}
} }
action_filter_calendar.setOnClickListener { action_filter_calendar.setOnClickListener {

View File

@ -1,7 +1,13 @@
package com.tommasoberlose.anotherwidget.ui.fragments package com.tommasoberlose.anotherwidget.ui.fragments
import android.app.Activity import android.app.Activity
import android.app.AlarmManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -19,12 +25,16 @@ import com.tommasoberlose.anotherwidget.databinding.FragmentClockSettingsBinding
import com.tommasoberlose.anotherwidget.global.Constants import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.global.RequestCode import com.tommasoberlose.anotherwidget.global.RequestCode
import com.tommasoberlose.anotherwidget.helpers.AlarmHelper
import com.tommasoberlose.anotherwidget.ui.activities.ChooseApplicationActivity import com.tommasoberlose.anotherwidget.ui.activities.ChooseApplicationActivity
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
import com.tommasoberlose.anotherwidget.utils.toast
import kotlinx.android.synthetic.main.fragment_clock_settings.* import kotlinx.android.synthetic.main.fragment_clock_settings.*
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.lang.Exception
class ClockSettingsFragment : Fragment() { class ClockSettingsFragment : Fragment() {
@ -58,6 +68,7 @@ class ClockSettingsFragment : Fragment() {
super.onActivityCreated(savedInstanceState) super.onActivityCreated(savedInstanceState)
setupListener() setupListener()
updateNextAlarmWarningUi()
} }
private fun subscribeUi( private fun subscribeUi(
@ -95,9 +106,7 @@ class ClockSettingsFragment : Fragment() {
}) })
viewModel.showNextAlarm.observe(viewLifecycleOwner, Observer { viewModel.showNextAlarm.observe(viewLifecycleOwner, Observer {
maintainScrollPosition { updateNextAlarmWarningUi()
show_next_alarm_label?.text = if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
}
}) })
viewModel.clockAppName.observe(viewLifecycleOwner, Observer { viewModel.clockAppName.observe(viewLifecycleOwner, Observer {
@ -156,6 +165,41 @@ class ClockSettingsFragment : Fragment() {
} }
} }
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 {
maintainScrollPosition {
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()
}
}
override fun onStart() {
super.onStart()
activity?.registerReceiver(nextAlarmChangeBroadcastReceiver, IntentFilter(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED))
}
override fun onStop() {
activity?.unregisterReceiver(nextAlarmChangeBroadcastReceiver)
super.onStop()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK && requestCode == RequestCode.CLOCK_APP_REQUEST_CODE.code) { if (resultCode == Activity.RESULT_OK && requestCode == RequestCode.CLOCK_APP_REQUEST_CODE.code) {
Preferences.bulk { Preferences.bulk {

View File

@ -184,7 +184,7 @@ class GeneralSettingsFragment : Fragment() {
BottomSheetColorPicker(requireContext(), BottomSheetColorPicker(requireContext(),
colors = colors, colors = colors,
header = getString(R.string.settings_font_color_title), header = getString(R.string.settings_font_color_title),
selected = ColorHelper.getFontColor(), getSelected = ColorHelper::getFontColorRgb,
onColorSelected = { color: Int -> onColorSelected = { color: Int ->
val colorString = Integer.toHexString(color) val colorString = Integer.toHexString(color)
Preferences.textGlobalColor = "#" + if (colorString.length > 6) colorString.substring(2) else colorString Preferences.textGlobalColor = "#" + if (colorString.length > 6) colorString.substring(2) else colorString
@ -201,7 +201,7 @@ class GeneralSettingsFragment : Fragment() {
BottomSheetColorPicker(requireContext(), BottomSheetColorPicker(requireContext(),
colors = colors, colors = colors,
header = getString(R.string.settings_background_color_title), header = getString(R.string.settings_background_color_title),
selected = ColorHelper.getBackgroundColor(), getSelected = { ColorHelper.getBackgroundColorRgb() },
onColorSelected = { color: Int -> onColorSelected = { color: Int ->
val colorString = Integer.toHexString(color) val colorString = Integer.toHexString(color)
Preferences.backgroundCardColor = "#" + if (colorString.length > 6) colorString.substring(2) else colorString Preferences.backgroundCardColor = "#" + if (colorString.length > 6) colorString.substring(2) else colorString

View File

@ -2,10 +2,8 @@ package com.tommasoberlose.anotherwidget.ui.fragments
import android.Manifest import android.Manifest
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -15,6 +13,9 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.navigation.Navigation
import com.google.android.material.transition.MaterialContainerTransform
import com.google.android.material.transition.MaterialSharedAxis
import com.karumi.dexter.Dexter import com.karumi.dexter.Dexter
import com.karumi.dexter.MultiplePermissionsReport import com.karumi.dexter.MultiplePermissionsReport
import com.karumi.dexter.PermissionToken import com.karumi.dexter.PermissionToken
@ -29,7 +30,7 @@ import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.activities.SupportDevActivity import com.tommasoberlose.anotherwidget.ui.activities.SupportDevActivity
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper import com.tommasoberlose.anotherwidget.helpers.CalendarHelper
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
import com.tommasoberlose.anotherwidget.utils.openURI import com.tommasoberlose.anotherwidget.utils.openURI
import kotlinx.android.synthetic.main.fragment_advanced_settings.* import kotlinx.android.synthetic.main.fragment_advanced_settings.*
@ -37,16 +38,18 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class AdvancedSettingsFragment : Fragment() { class SettingsFragment : Fragment() {
companion object { companion object {
fun newInstance() = AdvancedSettingsFragment() fun newInstance() = SettingsFragment()
} }
private lateinit var viewModel: MainViewModel private lateinit var viewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enterTransition = MaterialSharedAxis.create(MaterialSharedAxis.X, true)
returnTransition = MaterialSharedAxis.create(MaterialSharedAxis.X, false)
} }
override fun onCreateView( override fun onCreateView(
@ -57,8 +60,6 @@ class AdvancedSettingsFragment : Fragment() {
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java) viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
val binding = DataBindingUtil.inflate<FragmentAdvancedSettingsBinding>(inflater, R.layout.fragment_advanced_settings, container, false) val binding = DataBindingUtil.inflate<FragmentAdvancedSettingsBinding>(inflater, R.layout.fragment_advanced_settings, container, false)
subscribeUi(viewModel)
binding.lifecycleOwner = this binding.lifecycleOwner = this
binding.viewModel = viewModel binding.viewModel = viewModel
@ -68,10 +69,15 @@ class AdvancedSettingsFragment : Fragment() {
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState) super.onActivityCreated(savedInstanceState)
action_back.setOnClickListener {
Navigation.findNavController(it).popBackStack()
}
subscribeUi(viewModel)
setupListener() setupListener()
app_version.text = "v%s (%s)".format(BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE) app_version.text = "v%s (%s)".format(BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE)
requirePermission()
} }
private fun subscribeUi( private fun subscribeUi(
@ -187,7 +193,7 @@ class AdvancedSettingsFragment : Fragment() {
} }
action_refresh_widget.setOnClickListener { action_refresh_widget.setOnClickListener {
MainWidget.updateWidget(requireContext()) WeatherHelper.updateWeather(requireContext())
CalendarHelper.updateEventList(requireContext()) CalendarHelper.updateEventList(requireContext())
} }
} }

View File

@ -29,7 +29,6 @@ import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.global.RequestCode import com.tommasoberlose.anotherwidget.global.RequestCode
import com.tommasoberlose.anotherwidget.helpers.SettingsStringHelper import com.tommasoberlose.anotherwidget.helpers.SettingsStringHelper
import com.tommasoberlose.anotherwidget.receivers.WeatherReceiver import com.tommasoberlose.anotherwidget.receivers.WeatherReceiver
import com.tommasoberlose.anotherwidget.services.WeatherWorker
import com.tommasoberlose.anotherwidget.ui.activities.ChooseApplicationActivity import com.tommasoberlose.anotherwidget.ui.activities.ChooseApplicationActivity
import com.tommasoberlose.anotherwidget.ui.activities.CustomLocationActivity import com.tommasoberlose.anotherwidget.ui.activities.CustomLocationActivity
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
@ -82,12 +81,14 @@ class WeatherSettingsFragment : Fragment() {
) { ) {
viewModel.showWeatherWarning.observe(viewLifecycleOwner, Observer { viewModel.showWeatherWarning.observe(viewLifecycleOwner, Observer {
weather_warning?.isVisible = it weather_warning?.isVisible = it
checkLocationPermission()
}) })
viewModel.showWeather.observe(viewLifecycleOwner, Observer { viewModel.showWeather.observe(viewLifecycleOwner, Observer {
maintainScrollPosition { maintainScrollPosition {
show_weather_label?.text = show_weather_label?.text =
if (it) getString(R.string.show_weather_visible) else getString(R.string.show_weather_not_visible) if (it) getString(R.string.show_weather_visible) else getString(R.string.show_weather_not_visible)
checkWeatherProviderConfig()
binding.isWeatherVisible = it binding.isWeatherVisible = it
} }
checkLocationPermission() checkLocationPermission()
@ -95,11 +96,7 @@ class WeatherSettingsFragment : Fragment() {
viewModel.weatherProviderApi.observe(viewLifecycleOwner, Observer { viewModel.weatherProviderApi.observe(viewLifecycleOwner, Observer {
maintainScrollPosition { maintainScrollPosition {
label_weather_provider_api_key?.text = checkWeatherProviderConfig()
if (it == "") getString(R.string.settings_weather_provider_api_key_subtitle_not_set) else getString(
R.string.settings_weather_provider_api_key_subtitle_all_set
)
label_weather_provider_api_key?.setTextColor(ContextCompat.getColor(requireContext(), if (it == "") R.color.errorColorText else R.color.colorSecondaryText))
} }
checkLocationPermission() checkLocationPermission()
}) })
@ -137,21 +134,31 @@ class WeatherSettingsFragment : Fragment() {
private fun checkLocationPermission() { private fun checkLocationPermission() {
// Background permission // Background permission
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && activity?.checkGrantedPermission(Manifest.permission.ACCESS_FINE_LOCATION) == true) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && activity?.checkGrantedPermission(Manifest.permission.ACCESS_FINE_LOCATION) == true && activity?.checkGrantedPermission(Manifest.permission.ACCESS_BACKGROUND_LOCATION) != true) {
requirePermission() requirePermission()
} }
if (activity?.checkGrantedPermission(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION) == true) { if (activity?.checkGrantedPermission(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION) == true) {
location_permission_alert?.isVisible = false location_permission_alert?.isVisible = false
WeatherWorker.setUpdates(requireContext()) WeatherReceiver.setUpdates(requireContext())
} else if (Preferences.showWeather && Preferences.customLocationAdd == "") { } else if (Preferences.showWeather && Preferences.customLocationAdd == "") {
location_permission_alert?.isVisible = true location_permission_alert?.isVisible = true
location_permission_alert?.setOnClickListener { location_permission_alert?.setOnClickListener {
requirePermission() requirePermission()
} }
} else {
location_permission_alert?.isVisible = false
} }
} }
private fun checkWeatherProviderConfig() {
label_weather_provider_api_key?.text =
if (Preferences.weatherProviderApi == "") getString(R.string.settings_weather_provider_api_key_subtitle_not_set) else getString(
R.string.settings_weather_provider_api_key_subtitle_all_set
)
label_weather_provider_api_key?.setTextColor(ContextCompat.getColor(requireContext(), if (Preferences.weatherProviderApi == "" && Preferences.showWeather) R.color.errorColorText else R.color.colorSecondaryText))
}
private fun setupListener() { private fun setupListener() {
action_hide_weather_warning.setOnClickListener { action_hide_weather_warning.setOnClickListener {
Preferences.showWeatherWarning = false Preferences.showWeatherWarning = false
@ -218,7 +225,7 @@ class WeatherSettingsFragment : Fragment() {
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
when (requestCode) { when (requestCode) {
Constants.RESULT_CODE_CUSTOM_LOCATION -> { Constants.RESULT_CODE_CUSTOM_LOCATION -> {
WeatherWorker.setUpdates(requireContext()) WeatherReceiver.setUpdates(requireContext())
checkLocationPermission() checkLocationPermission()
} }
RequestCode.WEATHER_APP_REQUEST_CODE.code -> { RequestCode.WEATHER_APP_REQUEST_CODE.code -> {
@ -229,7 +236,7 @@ class WeatherSettingsFragment : Fragment() {
MainWidget.updateWidget(requireContext()) MainWidget.updateWidget(requireContext())
} }
RequestCode.WEATHER_PROVIDER_REQUEST_CODE.code -> { RequestCode.WEATHER_PROVIDER_REQUEST_CODE.code -> {
WeatherWorker.setOneTimeUpdate(requireContext()) WeatherReceiver.setOneTimeUpdate(requireContext())
} }
} }
} }

View File

@ -12,7 +12,6 @@ import android.graphics.Color
import android.graphics.Typeface import android.graphics.Typeface
import android.os.Bundle import android.os.Bundle
import android.text.format.DateUtils import android.text.format.DateUtils
import android.util.Log
import android.util.TypedValue import android.util.TypedValue
import android.view.View import android.view.View
import android.widget.ImageView import android.widget.ImageView
@ -28,15 +27,11 @@ import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.* import com.tommasoberlose.anotherwidget.helpers.*
import com.tommasoberlose.anotherwidget.helpers.WidgetHelper.reduceDimensionWithMaxWidth import com.tommasoberlose.anotherwidget.helpers.WidgetHelper.reduceDimensionWithMaxWidth
import com.tommasoberlose.anotherwidget.receivers.NewCalendarEventReceiver import com.tommasoberlose.anotherwidget.receivers.*
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
import com.tommasoberlose.anotherwidget.receivers.WidgetClickListenerReceiver
import com.tommasoberlose.anotherwidget.services.WeatherWorker
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
import com.tommasoberlose.anotherwidget.utils.getCapWordString import com.tommasoberlose.anotherwidget.utils.getCapWordString
import com.tommasoberlose.anotherwidget.utils.toPixel import com.tommasoberlose.anotherwidget.utils.toPixel
import kotlinx.android.synthetic.main.the_widget.view.* import kotlinx.android.synthetic.main.the_widget.view.*
import kotlinx.android.synthetic.main.the_widget_sans.*
import java.lang.Exception import java.lang.Exception
import java.text.DateFormat import java.text.DateFormat
import java.util.* import java.util.*
@ -58,7 +53,7 @@ class MainWidget : AppWidgetProvider() {
override fun onEnabled(context: Context) { override fun onEnabled(context: Context) {
CalendarHelper.updateEventList(context) CalendarHelper.updateEventList(context)
WeatherWorker.setUpdates(context) WeatherReceiver.setUpdates(context)
if (Preferences.showEvents) { if (Preferences.showEvents) {
CalendarHelper.setEventUpdatesAndroidN(context) CalendarHelper.setEventUpdatesAndroidN(context)
@ -70,20 +65,14 @@ class MainWidget : AppWidgetProvider() {
override fun onDisabled(context: Context) { override fun onDisabled(context: Context) {
if (getWidgetCount(context) == 0) { if (getWidgetCount(context) == 0) {
UpdatesReceiver.removeUpdates(context) UpdatesReceiver.removeUpdates(context)
WeatherWorker.removeUpdates(context) WeatherReceiver.removeUpdates(context)
} }
} }
companion object { companion object {
fun updateWidget(context: Context) { fun updateWidget(context: Context) {
val widgetManager = AppWidgetManager.getInstance(context) context.sendBroadcast(IntentHelper.getWidgetUpdateIntent(context))
val widgetComponent = ComponentName(context, MainWidget::class.java)
val widgetIds = widgetManager.getAppWidgetIds(widgetComponent)
val update = Intent(context, MainWidget::class.java)
update.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, widgetIds)
update.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
context.sendBroadcast(update)
} }
fun getWidgetCount(context: Context): Int { fun getWidgetCount(context: Context): Int {
@ -104,19 +93,46 @@ class MainWidget : AppWidgetProvider() {
private fun generateWidgetView(context: Context, appWidgetId: Int, appWidgetManager: AppWidgetManager, w: Int) { private fun generateWidgetView(context: Context, appWidgetId: Int, appWidgetManager: AppWidgetManager, w: Int) {
var views = RemoteViews(context.packageName, R.layout.the_widget_sans) var views = RemoteViews(context.packageName, R.layout.the_widget_sans)
val generatedView = generateWidgetView(context) try {
views.setImageViewBitmap(R.id.bitmap_container, BitmapHelper.getBitmapFromView(generatedView, width = w)) // Background
views.setInt(
// Background R.id.widget_shape_background,
views.setInt(R.id.widget_shape_background, "setColorFilter", ColorHelper.getBackgroundColorRgb()) "setColorFilter",
views.setInt(R.id.widget_shape_background, "setImageAlpha", ColorHelper.getBackgroundAlpha()) ColorHelper.getBackgroundColorRgb()
)
views.setInt(
R.id.widget_shape_background,
"setImageAlpha",
ColorHelper.getBackgroundAlpha()
)
val refreshIntent = PendingIntent.getActivity(
context,
appWidgetId,
IntentHelper.getWidgetUpdateIntent(context),
0
)
views.setOnClickPendingIntent(R.id.widget_shape_background, refreshIntent)
} catch (ex: Exception) {
ex.printStackTrace()
CrashlyticsReceiver.sendCrash(context, ex)
}
// Clock // Clock
views = updateClockView(context, views, appWidgetId) views = updateClockView(context, views, appWidgetId)
// Setup listener // Setup listener
views = updateCalendarView(context, generatedView, views, appWidgetId) try {
views = updateWeatherView(context, generatedView, views, appWidgetId) val generatedView = generateWidgetView(context)
views.setImageViewBitmap(
R.id.bitmap_container,
BitmapHelper.getBitmapFromView(generatedView, width = w)
)
views = updateCalendarView(context, generatedView, views, appWidgetId)
views = updateWeatherView(context, generatedView, views, appWidgetId)
} catch (ex: Exception) {
ex.printStackTrace()
CrashlyticsReceiver.sendCrash(context, ex)
}
appWidgetManager.updateAppWidget(appWidgetId, views) appWidgetManager.updateAppWidget(appWidgetId, views)
} }
@ -269,7 +285,7 @@ class MainWidget : AppWidgetProvider() {
} }
} catch (ex: Exception) { } catch (ex: Exception) {
ex.printStackTrace() ex.printStackTrace()
FirebaseCrashlytics.getInstance().recordException(ex) CrashlyticsReceiver.sendCrash(context, ex)
} }
return views return views
@ -303,7 +319,7 @@ class MainWidget : AppWidgetProvider() {
} }
} catch (ex: Exception) { } catch (ex: Exception) {
ex.printStackTrace() ex.printStackTrace()
FirebaseCrashlytics.getInstance().recordException(ex) CrashlyticsReceiver.sendCrash(context, ex)
} }
return views return views
} }
@ -360,7 +376,7 @@ class MainWidget : AppWidgetProvider() {
} }
} catch (ex: Exception) { } catch (ex: Exception) {
ex.printStackTrace() ex.printStackTrace()
FirebaseCrashlytics.getInstance().recordException(ex) CrashlyticsReceiver.sendCrash(context, ex)
} }
return views return views

View File

@ -32,8 +32,8 @@ import java.util.*
fun PackageManager.missingSystemFeature(name: String): Boolean = !hasSystemFeature(name) fun PackageManager.missingSystemFeature(name: String): Boolean = !hasSystemFeature(name)
fun Context.toast(message: String) { fun Context.toast(message: String, long: Boolean = false) {
val toast = Toast.makeText(this, message, Toast.LENGTH_SHORT) val toast = Toast.makeText(this, message, if (long) Toast.LENGTH_LONG else Toast.LENGTH_SHORT)
// toast.setGravity(Gravity.CENTER, 0, 0) // toast.setGravity(Gravity.CENTER, 0, 0)
toast.show() toast.show()
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 B

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M19,11H7.83l4.88,-4.88c0.39,-0.39 0.39,-1.03 0,-1.42 -0.39,-0.39 -1.02,-0.39 -1.41,0l-6.59,6.59c-0.39,0.39 -0.39,1.02 0,1.41l6.59,6.59c0.39,0.39 1.02,0.39 1.41,0 0.39,-0.39 0.39,-1.02 0,-1.41L7.83,13H19c0.55,0 1,-0.45 1,-1s-0.45,-1 -1,-1z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M5,9h14c0.55,0 1,0.45 1,1s-0.45,1 -1,1L5,11c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1zM5,13h8c0.55,0 1,0.45 1,1s-0.45,1 -1,1L5,15c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1z"/>
</vector>

View File

@ -1,153 +1,42 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true" android:orientation="vertical"
android:background="?android:attr/colorPrimary" android:background="?android:attr/colorPrimary"
tools:context=".ui.activities.MainActivity"> tools:context=".ui.activities.MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/content_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="56dp"
app:layout_constraintTop_toTopOf="parent" android:visibility="gone"
app:cardElevation="2dp" app:cardBackgroundColor="@color/colorAccent"
app:cardCornerRadius="0dp" app:cardCornerRadius="0dp"
android:id="@+id/toolbar" android:id="@+id/action_add_widget"
app:cardBackgroundColor="@color/colorPrimary"> android:clickable="true"
<LinearLayout android:focusable="true"
app:cardElevation="4dp">
<com.google.android.material.button.MaterialButton
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="72dp"
android:orientation="vertical"> android:text="@string/add_widget"
<RelativeLayout android:layout_marginTop="-8dp"
android:layout_width="match_parent" android:clickable="false"
android:layout_height="56dp" android:focusable="false"
android:gravity="center_vertical" android:gravity="center"
android:paddingLeft="8dp" android:textColor="@android:color/white"
android:paddingRight="8dp"> app:cornerRadius="0dp"
<ImageView style="@style/Widget.MaterialComponents.Button.TextButton"/>
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/ic_splash_logo"
android:layout_alignParentBottom="true"
android:layout_marginBottom="3dp"
android:visibility="gone"
android:layout_alignParentLeft="true"
android:id="@+id/logo"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_centerInParent="true">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/app_name"
android:gravity="center"
android:layout_marginBottom="1dp"
style="@style/AnotherWidget.Main.Title"/>
</LinearLayout>
</RelativeLayout>
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="160dp"
android:id="@+id/preview"
android:animateLayoutChanges="true"
app:cardBackgroundColor="@color/colorPrimary"
android:layout_marginRight="16dp"
android:layout_marginLeft="16dp"
app:cardCornerRadius="9dp"
app:cardElevation="0dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:id="@+id/widget_bg" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:orientation="vertical"
android:id="@+id/widget"
android:alpha="0"
android:gravity="center">
<include layout="@layout/the_widget_sans" />
</LinearLayout>
<ProgressBar
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_centerInParent="true"
android:indeterminate="true"
android:indeterminateTint="@android:color/white"
android:id="@+id/widget_loader" />
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="56dp"
app:tabGravity="center"
app:tabIndicatorColor="@color/colorAccent"
app:tabBackground="@color/colorPrimary"
app:tabIndicatorFullWidth="false"
app:tabMode="scrollable"
app:tabIndicatorHeight="3dp"
app:tabUnboundedRipple="true"
app:tabRippleColor="@color/colorPrimary"
app:tabTextColor="@color/colorSecondaryText"
app:tabSelectedTextColor="@color/colorAccent"
app:tabIndicator="@drawable/custom_tab_indicator"
app:tabPadding="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:clipToPadding="false"
app:tabMinWidth="110dp"
android:background="@color/colorPrimary"
app:tabTextAppearance="@style/AnotherWidget.Settings.Header" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>
<LinearLayout </LinearLayout>
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@+id/toolbar"
app:layout_constraintBottom_toBottomOf="parent"
android:background="@color/colorPrimaryDark"
android:orientation="vertical">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/pager"
android:layout_width="match_parent"
android:elevation="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="56dp"
android:visibility="gone"
app:cardBackgroundColor="@color/colorAccent"
app:cardCornerRadius="0dp"
android:id="@+id/action_add_widget"
android:clickable="true"
android:focusable="true"
app:cardElevation="4dp">
<com.google.android.material.button.MaterialButton
android:layout_width="match_parent"
android:layout_height="72dp"
android:text="@string/add_widget"
android:layout_marginTop="-8dp"
android:clickable="false"
android:focusable="false"
android:gravity="center"
android:textColor="@android:color/white"
app:cornerRadius="0dp"
style="@style/Widget.MaterialComponents.Button.TextButton"/>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -26,6 +26,22 @@
android:id="@+id/header_text" android:id="@+id/header_text"
android:text="" android:text=""
android:textColor="@color/colorPrimaryText"/> android:textColor="@color/colorPrimaryText"/>
<androidx.appcompat.widget.AppCompatTextView
android:textAppearance="@style/TextAppearance.MaterialComponents.Button"
app:textAllCaps="false"
android:letterSpacing="0"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:textAlignment="viewStart"
android:layout_marginTop="-8dp"
android:paddingBottom="8dp"
android:paddingLeft="32dp"
android:paddingRight="32dp"
android:textSize="15sp"
android:id="@+id/warning_text"
android:text=""
android:textColor="@color/warningColorText"/>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1dp"

View File

@ -4,6 +4,14 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"> android:orientation="vertical">
<com.google.android.material.card.MaterialCardView
android:layout_width="40dp"
android:layout_height="6dp"
app:cardCornerRadius="3dp"
android:layout_marginBottom="2dp"
android:layout_gravity="center_horizontal"
app:cardBackgroundColor="@color/disabledButtonBackground"
app:cardElevation="0dp" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -32,80 +40,74 @@
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:background="@color/disabledButtonBackground" /> android:background="@color/disabledButtonBackground" />
</LinearLayout> </LinearLayout>
<androidx.core.widget.NestedScrollView <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/alpha_selector_container"
android:layout_marginTop="-2dp"
android:background="@color/colorPrimary"
android:gravity="center_vertical"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:textAppearance="@style/TextAppearance.MaterialComponents.Button"
app:textAllCaps="false"
android:letterSpacing="0"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="32dp"
android:paddingRight="32dp"
android:textSize="15sp"
android:gravity="start"
android:textAlignment="viewStart"
android:id="@+id/text_alpha"
android:text="Alpha : 20%"
android:textColor="@color/colorSecondaryText"/>
<com.warkiz.widget.IndicatorSeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:isb_max="100"
app:isb_min="0"
android:layout_marginRight="16dp"
android:layout_marginLeft="16dp"
app:isb_seek_smoothly="true"
app:isb_show_thumb_text="false"
app:isb_thumb_adjust_auto="true"
app:isb_track_rounded_corners="true"
app:isb_thumb_text_color="@color/colorAccent"
app:isb_progress_value_float="false"
app:isb_show_tick_texts="false"
app:isb_show_indicator="none"
app:isb_thumb_color="@color/colorAccent"
app:isb_thumb_size="12dp"
android:id="@+id/alpha_selector"
app:isb_track_background_color="@color/disabledButtonBackground"
app:isb_track_background_size="4dp"
app:isb_track_progress_color="@color/disabledButtonBackground"
app:isb_track_progress_size="4dp"
app:isb_only_thumb_draggable="false"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="16dp"
android:background="@color/disabledButtonBackground" />
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="260dp"
android:orientation="vertical"> android:id="@+id/list_container"
<LinearLayout android:orientation="vertical" />
android:layout_width="match_parent" <ProgressBar
android:layout_height="wrap_content" android:layout_width="32dp"
android:paddingTop="16dp" android:layout_height="32dp"
android:paddingBottom="16dp" android:indeterminateTint="@color/colorPrimaryText"
android:paddingRight="16dp" android:indeterminate="true"
android:paddingLeft="16dp" android:layout_margin="32dp"
android:id="@+id/alpha_selector_container" android:layout_centerInParent="true"
android:gravity="center_vertical" android:id="@+id/color_loader" />
android:orientation="vertical"> </RelativeLayout>
<androidx.appcompat.widget.AppCompatTextView
android:textAppearance="@style/TextAppearance.MaterialComponents.Button"
app:textAllCaps="false"
android:letterSpacing="0"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:textSize="15sp"
android:gravity="start"
android:textAlignment="viewStart"
android:id="@+id/text_alpha"
android:text="Alpha : 20%"
android:textColor="@color/colorSecondaryText"/>
<com.warkiz.widget.IndicatorSeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:isb_max="100"
app:isb_min="0"
app:isb_seek_smoothly="true"
app:isb_show_thumb_text="false"
app:isb_thumb_adjust_auto="true"
app:isb_track_rounded_corners="true"
app:isb_thumb_text_color="@color/colorAccent"
app:isb_progress_value_float="false"
app:isb_show_tick_texts="false"
app:isb_show_indicator="none"
app:isb_thumb_color="@color/colorAccent"
app:isb_thumb_size="12dp"
android:id="@+id/alpha_selector"
app:isb_track_background_color="@color/disabledButtonBackground"
app:isb_track_background_size="4dp"
app:isb_track_progress_color="@color/disabledButtonBackground"
app:isb_track_progress_size="4dp"
app:isb_only_thumb_draggable="false"/>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/menu"
android:visibility="gone"
android:layout_margin="16dp"
android:columnCount="6"/>
<ProgressBar
android:layout_width="32dp"
android:layout_height="32dp"
android:indeterminateTint="@color/colorPrimaryText"
android:indeterminate="true"
android:layout_margin="32dp"
android:layout_centerInParent="true"
android:id="@+id/color_loader" />
</RelativeLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout> </LinearLayout>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="260dp"
android:id="@+id/menu"
android:clipToPadding="false"
android:padding="16dp"/>

View File

@ -7,350 +7,393 @@
name="viewModel" name="viewModel"
type="com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel" /> type="com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel" />
</data> </data>
<ScrollView <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:id="@+id/scrollView" android:background="@color/colorPrimary"
android:scrollbarThumbVertical="@color/colorPrimary" android:orientation="vertical">
android:background="@color/colorPrimaryDark"> <com.google.android.material.card.MaterialCardView
<LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="56dp"
android:paddingTop="8dp" app:cardBackgroundColor="@color/colorPrimary"
android:paddingBottom="8dp" app:cardElevation="2dp"
android:orientation="vertical"> app:cardCornerRadius="0dp"
<LinearLayout android:background="@color/colorPrimary"
android:transitionName="@string/toolbar_transition_name"
android:id="@+id/toolbar">
<RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="56dp">
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_refresh_widget"
android:orientation="horizontal">
<ImageView <ImageView
android:layout_width="48dp" android:layout_width="48dp"
android:layout_height="48dp" android:layout_height="48dp"
android:padding="11dp" android:padding="10dp"
android:src="@drawable/round_refresh" android:src="@drawable/round_arrow_back"
android:tint="@color/colorPrimaryText"/> android:tint="@color/colorPrimaryText"
<LinearLayout android:layout_centerVertical="true"
android:layout_width="match_parent" android:clickable="true"
android:layout_height="wrap_content" android:focusable="true"
android:paddingLeft="8dp" android:layout_marginEnd="8dp"
android:paddingRight="8dp" android:layout_alignParentLeft="true"
android:orientation="vertical"> android:layout_marginStart="8dp"
<TextView android:background="?attr/selectableItemBackgroundBorderless"
android:layout_width="wrap_content" android:id="@+id/action_back" />
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/action_refresh_widget"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/support_refresh_widget_subtitle"
style="@style/AnotherWidget.Settings.Subtitle" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_show_widget_preview"
android:orientation="horizontal">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="13dp"
android:src="@drawable/round_aspect_ratio"
android:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/action_show_widget_preview"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/show_widget_preview_label"
style="@style/AnotherWidget.Settings.Subtitle" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_show_wallpaper"
android:orientation="horizontal">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:src="@drawable/round_wallpaper"
android:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/settings_title_show_wallpaper"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/show_wallpaper_label"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_change_theme"
android:orientation="horizontal">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:src="@drawable/ic_day_night"
android:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/settings_theme_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/theme"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_translate"
android:orientation="horizontal">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:src="@drawable/round_translate"
android:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/support_translations_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/second_text_size_label"
android:text="@string/support_translations_subtitle"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_feedback"
android:orientation="horizontal">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:src="@drawable/round_group_work"
android:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/settings_feedback_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settings_feedback_subtitle"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clickable="true"
android:focusable="true"
android:visibility="gone"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_website"
android:orientation="horizontal">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:src="@drawable/round_widgets"
android:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/support_website_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/font_color_label"
android:text="@string/support_website_subtitle"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_help_dev"
android:orientation="horizontal">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:src="@drawable/round_favorite"
android:tint="@color/errorColorText"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/support_main_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/support_main_subtitle"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/small_clock_warning"
android:gravity="start"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView <androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/settings_title"
android:textColor="@color/colorPrimaryText"
android:gravity="center"
android:textAppearance="@style/TextAppearance.AppCompat.Title"
tools:ignore="RelativeOverlap" />
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/scrollView"
android:scrollbarThumbVertical="@color/colorPrimary"
android:background="@color/colorPrimaryDark">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp" android:paddingTop="16dp"
android:paddingLeft="24dp" android:paddingBottom="16dp"
android:paddingRight="24dp" android:paddingLeft="8dp"
android:duplicateParentState="true" android:paddingRight="8dp"
android:textSize="16sp" android:clickable="true"
android:text="@string/settings_app_version_title" android:focusable="true"
android:textColor="@color/colorSecondaryText" android:background="?android:attr/selectableItemBackground"
android:letterSpacing="0" android:gravity="center_vertical"
android:textAppearance="@style/TextAppearance.AppCompat.Button" android:id="@+id/action_refresh_widget"
app:textAllCaps="false" /> android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatTextView <ImageView
android:layout_width="wrap_content" android:layout_width="48dp"
android:layout_height="48dp"
android:padding="11dp"
android:src="@drawable/round_refresh"
android:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/action_refresh_widget"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/support_refresh_widget_subtitle"
style="@style/AnotherWidget.Settings.Subtitle" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingLeft="24dp" android:paddingTop="16dp"
android:paddingRight="24dp" android:paddingBottom="16dp"
android:paddingBottom="32dp" android:paddingLeft="8dp"
android:duplicateParentState="true" android:paddingRight="8dp"
android:textSize="14sp" android:clickable="true"
android:textColor="@color/colorSecondaryText" android:focusable="true"
android:letterSpacing="0" android:background="?android:attr/selectableItemBackground"
android:id="@+id/app_version" android:gravity="center_vertical"
android:textAppearance="@style/TextAppearance.AppCompat.Medium" android:id="@+id/action_show_widget_preview"
app:textAllCaps="false" /> android:orientation="horizontal">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="13dp"
android:src="@drawable/round_aspect_ratio"
android:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/action_show_widget_preview"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/show_widget_preview_label"
style="@style/AnotherWidget.Settings.Subtitle" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_show_wallpaper"
android:orientation="horizontal">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:src="@drawable/round_wallpaper"
android:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/settings_title_show_wallpaper"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/show_wallpaper_label"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_change_theme"
android:orientation="horizontal">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:src="@drawable/ic_day_night"
android:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/settings_theme_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/theme"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_translate"
android:orientation="horizontal">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:src="@drawable/round_translate"
android:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/support_translations_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/second_text_size_label"
android:text="@string/support_translations_subtitle"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_feedback"
android:orientation="horizontal">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:src="@drawable/round_group_work"
android:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/settings_feedback_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settings_feedback_subtitle"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clickable="true"
android:focusable="true"
android:visibility="gone"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_website"
android:orientation="horizontal">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:src="@drawable/round_widgets"
android:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/support_website_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/font_color_label"
android:text="@string/support_website_subtitle"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_help_dev"
android:orientation="horizontal">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:src="@drawable/round_favorite"
android:tint="@color/errorColorText"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/support_main_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/support_main_subtitle"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/small_clock_warning"
android:gravity="start"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingLeft="24dp"
android:paddingRight="24dp"
android:duplicateParentState="true"
android:textSize="16sp"
android:text="@string/settings_app_version_title"
android:textColor="@color/colorSecondaryText"
android:letterSpacing="0"
android:textAppearance="@style/TextAppearance.AppCompat.Button"
app:textAllCaps="false" />
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="24dp"
android:paddingRight="24dp"
android:paddingBottom="32dp"
android:duplicateParentState="true"
android:textSize="14sp"
android:textColor="@color/colorSecondaryText"
android:letterSpacing="0"
android:id="@+id/app_version"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:textAllCaps="false" />
</LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> </ScrollView>
</ScrollView> </LinearLayout>
</layout> </layout>

View File

@ -0,0 +1,147 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:background="?android:attr/colorPrimary"
tools:context=".ui.activities.MainActivity">
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:cardElevation="2dp"
app:cardCornerRadius="0dp"
android:id="@+id/toolbar"
android:transitionName="@string/toolbar_transition_name"
app:cardBackgroundColor="@color/colorPrimary">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="56dp"
android:gravity="center_vertical"
android:paddingLeft="8dp"
android:paddingRight="8dp">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/ic_splash_logo"
android:layout_alignParentBottom="true"
android:layout_marginBottom="3dp"
android:visibility="gone"
android:layout_alignParentLeft="true"
android:id="@+id/logo"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_centerInParent="true">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/app_name"
android:gravity="center"
android:layout_marginBottom="1dp"
style="@style/AnotherWidget.Main.Title"/>
</LinearLayout>
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="8dp"
android:src="@drawable/round_short_text"
android:scaleX="-1"
android:clickable="true"
android:focusable="true"
android:background="?attr/selectableItemBackgroundBorderless"
android:tint="@color/colorPrimaryText"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:id="@+id/action_settings"/>
</RelativeLayout>
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="160dp"
android:id="@+id/preview"
android:animateLayoutChanges="true"
app:cardBackgroundColor="@color/colorPrimary"
android:layout_marginRight="16dp"
android:layout_marginLeft="16dp"
app:cardCornerRadius="9dp"
app:cardElevation="0dp">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="-80dp"
android:layout_marginStart="-80dp"
android:scaleType="fitStart"
android:adjustViewBounds="true"
android:id="@+id/widget_bg" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:orientation="vertical"
android:id="@+id/widget"
android:alpha="0"
android:gravity="center">
<include layout="@layout/the_widget_sans" />
</LinearLayout>
<ProgressBar
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_centerInParent="true"
android:indeterminate="true"
android:indeterminateTint="@android:color/white"
android:id="@+id/widget_loader" />
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="56dp"
app:tabGravity="center"
app:tabIndicatorColor="@color/colorAccent"
app:tabBackground="@color/colorPrimary"
app:tabIndicatorFullWidth="false"
app:tabMode="scrollable"
app:tabIndicatorHeight="3dp"
app:tabUnboundedRipple="true"
app:tabRippleColor="@color/colorPrimary"
app:tabTextColor="@color/colorSecondaryText"
app:tabSelectedTextColor="@color/colorAccent"
app:tabIndicator="@drawable/custom_tab_indicator"
app:tabPadding="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:clipToPadding="false"
app:tabMinWidth="110dp"
android:background="@color/colorPrimary"
app:tabTextAppearance="@style/AnotherWidget.Settings.Header" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@+id/toolbar"
app:layout_constraintBottom_toBottomOf="parent"
android:background="@color/colorPrimaryDark"
android:orientation="vertical">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/pager"
android:layout_width="match_parent"
android:elevation="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -251,6 +251,14 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/show_next_alarm_label" android:id="@+id/show_next_alarm_label"
style="@style/AnotherWidget.Settings.Subtitle"/> style="@style/AnotherWidget.Settings.Subtitle"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:textSize="14sp"
android:visibility="gone"
android:id="@+id/show_next_alarm_warning"
android:textColor="@color/warningColorText" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout

View File

@ -198,6 +198,7 @@
android:paddingBottom="0dp" android:paddingBottom="0dp"
android:paddingTop="0dp" android:paddingTop="0dp"
android:focusable="true" android:focusable="true"
android:visibility="gone"
android:id="@+id/location_permission_alert" android:id="@+id/location_permission_alert"
android:textColor="@color/errorColorText" android:textColor="@color/errorColorText"
android:text="@string/action_grant_permission"/> android:text="@string/action_grant_permission"/>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/appMainFragment">
<fragment
android:id="@+id/appMainFragment"
android:name="com.tommasoberlose.anotherwidget.ui.fragments.AppMainFragment"
android:label="AppMainFragment" >
<action
android:id="@+id/action_appMainFragment_to_appSettingsFragment"
app:destination="@id/appSettingsFragment" />
</fragment>
<fragment
android:id="@+id/appSettingsFragment"
android:name="com.tommasoberlose.anotherwidget.ui.fragments.SettingsFragment"
android:label="AppSettingsFragment" />
</navigation>

View File

@ -205,4 +205,6 @@
<string name="alpha">Alpha</string> <string name="alpha">Alpha</string>
<string name="settings_background_color_title">Background color</string> <string name="settings_background_color_title">Background color</string>
<string name="transparent">Transparent</string> <string name="transparent">Transparent</string>
<string name="next_alarm_warning">The next alarm clock seems to be wrong.\nIt has been set by %s.</string>
<string name="settings_title">Settings</string>
</resources> </resources>

View File

@ -185,4 +185,6 @@
<string name="alpha">Alpha</string> <string name="alpha">Alpha</string>
<string name="settings_background_color_title">Background color</string> <string name="settings_background_color_title">Background color</string>
<string name="transparent">Transparent</string> <string name="transparent">Transparent</string>
<string name="next_alarm_warning">The next alarm clock seems to be wrong.\nIt has been set by %s.</string>
<string name="settings_title">Settings</string>
</resources> </resources>

View File

@ -184,4 +184,6 @@
<string name="alpha">Trasparenza</string> <string name="alpha">Trasparenza</string>
<string name="settings_background_color_title">Colore background</string> <string name="settings_background_color_title">Colore background</string>
<string name="transparent">Trasparente</string> <string name="transparent">Trasparente</string>
<string name="next_alarm_warning">La sveglia sembra impostata male.\nÈ stata impostata dall\'app %s.</string>
<string name="settings_title">Impostazioni</string>
</resources> </resources>

View File

@ -28,6 +28,7 @@
<color name="colorSecondaryText">#99000000</color> <color name="colorSecondaryText">#99000000</color>
<color name="errorColorBackground">#FBD8D8</color> <color name="errorColorBackground">#FBD8D8</color>
<color name="errorColorText">#E93B3B</color> <color name="errorColorText">#E93B3B</color>
<color name="warningColorText">#FB8C00</color>
<color name="disabledButtonBackground">#efefef</color> <color name="disabledButtonBackground">#efefef</color>
</resources> </resources>

View File

@ -33,7 +33,7 @@
<string name="main_calendar">Account calendar</string> <string name="main_calendar">Account calendar</string>
<string name="settings_calendar_title">Calendar</string> <string name="settings_calendar_title">Calendar</string>
<string name="settings_weather_title">Weather</string> <string name="settings_weather_title">Weather</string>
<string name="settings_general_title">Typography</string> <string name="settings_general_title">General</string>
<string name="calendar_settings_list_error">Error loading the calendar list</string> <string name="calendar_settings_list_error">Error loading the calendar list</string>
<string name="settings_hour_format_title">Hour format</string> <string name="settings_hour_format_title">Hour format</string>
<string name="settings_hour_format_subtitle_12">12 hour</string> <string name="settings_hour_format_subtitle_12">12 hour</string>
@ -196,4 +196,6 @@
<string name="action_grant_permission">Grant permission</string> <string name="action_grant_permission">Grant permission</string>
<string name="alpha">Alpha</string> <string name="alpha">Alpha</string>
<string name="transparent">Transparent</string> <string name="transparent">Transparent</string>
<string name="next_alarm_warning">The next alarm clock seems to be wrong.\nIt has been set by %s.</string>
<string name="settings_title">Settings</string>
</resources> </resources>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
<include domain="sharedpref" path="."/>
</full-backup-content>

View File

@ -4,10 +4,10 @@
android:initialKeyguardLayout="@layout/the_widget" android:initialKeyguardLayout="@layout/the_widget"
android:initialLayout="@layout/the_widget" android:initialLayout="@layout/the_widget"
android:minHeight="50dp" android:minHeight="50dp"
android:minWidth="300dp" android:minWidth="250dp"
android:configure="com.tommasoberlose.anotherwidget.ui.activities.MainActivity" android:configure="com.tommasoberlose.anotherwidget.ui.activities.MainActivity"
android:minResizeHeight="50dp" android:minResizeHeight="50dp"
android:minResizeWidth="300dp" android:minResizeWidth="250dp"
android:previewImage="@drawable/widget_preview" android:previewImage="@drawable/widget_preview"
android:resizeMode="vertical|horizontal" android:resizeMode="vertical|horizontal"
android:updatePeriodMillis="86400000" android:updatePeriodMillis="86400000"

View File

@ -3,7 +3,7 @@
xmlns:dist="http://schemas.android.com/apk/distribution" xmlns:dist="http://schemas.android.com/apk/distribution"
featureSplit="tasksintegration" featureSplit="tasksintegration"
package="com.tommasoberlose.anotherwidget" package="com.tommasoberlose.anotherwidget"
android:versionCode="68" android:versionCode="76"
android:versionName="2.0.5" > android:versionName="2.0.5" >
<uses-sdk <uses-sdk

View File

@ -1,4 +1,4 @@
#Wed May 06 11:30:08 CEST 2020 #Fri May 08 01:05:26 CEST 2020
base.0=/Users/tommaso/Documents/MyCode/another-widget/tasksintegration/build/intermediates/dex/debug/mergeProjectDexDebug/out/classes.dex base.0=/Users/tommaso/Documents/MyCode/another-widget/tasksintegration/build/intermediates/dex/debug/mergeProjectDexDebug/out/classes.dex
path.0=classes.dex path.0=classes.dex
renamed.0=classes.dex renamed.0=classes.dex

View File

@ -4,7 +4,7 @@
featureSplit="tasksintegration" featureSplit="tasksintegration"
package="com.tommasoberlose.anotherwidget" package="com.tommasoberlose.anotherwidget"
android:targetSandboxVersion="2" android:targetSandboxVersion="2"
android:versionCode="68" android:versionCode="76"
android:versionName="2.0.5" > android:versionName="2.0.5" >
<uses-sdk <uses-sdk

View File

@ -3,7 +3,7 @@
3 xmlns:dist="http://schemas.android.com/apk/distribution" 3 xmlns:dist="http://schemas.android.com/apk/distribution"
4 featureSplit="tasksintegration" 4 featureSplit="tasksintegration"
5 package="com.tommasoberlose.anotherwidget" 5 package="com.tommasoberlose.anotherwidget"
6 android:versionCode="68" 6 android:versionCode="76"
7 android:versionName="2.0.5" > 7 android:versionName="2.0.5" >
8 8
9 <uses-sdk 9 <uses-sdk

View File

@ -3,7 +3,7 @@
xmlns:dist="http://schemas.android.com/apk/distribution" xmlns:dist="http://schemas.android.com/apk/distribution"
featureSplit="tasksintegration" featureSplit="tasksintegration"
package="com.tommasoberlose.anotherwidget" package="com.tommasoberlose.anotherwidget"
android:versionCode="68" android:versionCode="76"
android:versionName="2.0.5" > android:versionName="2.0.5" >
<uses-sdk <uses-sdk

View File

@ -3,7 +3,7 @@
xmlns:dist="http://schemas.android.com/apk/distribution" xmlns:dist="http://schemas.android.com/apk/distribution"
featureSplit="tasksintegration" featureSplit="tasksintegration"
package="com.tommasoberlose.anotherwidget" package="com.tommasoberlose.anotherwidget"
android:versionCode="68" android:versionCode="76"
android:versionName="2.0.5" > android:versionName="2.0.5" >
<uses-sdk android:targetSdkVersion="29" /> <uses-sdk android:targetSdkVersion="29" />