Compare commits

...

4 Commits

Author SHA1 Message Date
37cb43dc80 Add media player receiver 2020-05-06 21:40:51 +02:00
ea372dd76d Remove workers. Fix #71 2020-05-06 21:25:23 +02:00
7076311e94 Add workers 2020-05-06 20:58:32 +02:00
2e684e0902 Fix #74, fix #69 2020-05-06 16:16:31 +02:00
35 changed files with 262 additions and 126 deletions

Binary file not shown.

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 71
versionName "2.0.5" versionName "2.0.5"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

Binary file not shown.

View File

@ -90,6 +90,33 @@
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver
android:name=".receivers.PlayerReceiver"
android:enabled="true"
android:exported="true">
<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"

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

@ -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

@ -20,15 +20,12 @@ object BitmapHelper {
view.measure(measuredWidth, measuredHeight) view.measure(measuredWidth, 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

@ -4,7 +4,6 @@ import android.Manifest
import android.content.ContentUris import android.content.ContentUris
import android.content.Context import android.content.Context
import android.provider.CalendarContract import android.provider.CalendarContract
import android.util.Log
import com.tommasoberlose.anotherwidget.services.EventListenerJob import com.tommasoberlose.anotherwidget.services.EventListenerJob
import com.tommasoberlose.anotherwidget.db.EventRepository import com.tommasoberlose.anotherwidget.db.EventRepository
import com.tommasoberlose.anotherwidget.models.Event import com.tommasoberlose.anotherwidget.models.Event
@ -125,7 +124,6 @@ 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(MainActivity.UpdateUiMessageEvent())

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
@ -9,14 +10,25 @@ import android.net.Uri
import android.provider.AlarmClock import android.provider.AlarmClock
import android.provider.CalendarContract import android.provider.CalendarContract
import android.provider.CalendarContract.Events import android.provider.CalendarContract.Events
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,9 +75,15 @@ object IntentHelper {
} }
fun getCalendarIntent(context: Context): Intent { fun getCalendarIntent(context: Context): Intent {
val calendarUri = CalendarContract.CONTENT_URI
.buildUpon()
.appendPath("time")
.appendPath(Date(Calendar.getInstance().timeInMillis).toString())
.build()
return when (Preferences.calendarAppPackage) { return when (Preferences.calendarAppPackage) {
"" -> { "" -> {
Intent(Intent.ACTION_MAIN).apply { Intent(Intent.ACTION_MAIN).apply {
// data = calendarUri
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
addCategory(Intent.CATEGORY_APP_CALENDAR) addCategory(Intent.CATEGORY_APP_CALENDAR)
} }
@ -77,12 +95,14 @@ object IntentHelper {
val pm: PackageManager = context.packageManager val pm: PackageManager = context.packageManager
try { try {
pm.getLaunchIntentForPackage(Preferences.calendarAppPackage)!!.apply { pm.getLaunchIntentForPackage(Preferences.calendarAppPackage)!!.apply {
// data = calendarUri
addCategory(Intent.CATEGORY_LAUNCHER) addCategory(Intent.CATEGORY_LAUNCHER)
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
} }
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
Intent(Intent.ACTION_MAIN).apply { Intent(Intent.ACTION_MAIN).apply {
// data = calendarUri
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
addCategory(Intent.CATEGORY_APP_CALENDAR) addCategory(Intent.CATEGORY_APP_CALENDAR)
} }

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

@ -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,63 @@ 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 != "") {
WeatherHelper.updateWeather(context)
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,
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

@ -11,7 +11,6 @@ import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.provider.Settings import android.provider.Settings
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
@ -263,6 +262,7 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
backgroundColor = ContextCompat.getColor(this@MainActivity, R.color.errorColorText) backgroundColor = ContextCompat.getColor(this@MainActivity, R.color.errorColorText)
badgeGravity = BadgeDrawable.TOP_END 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))) }?.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) { private fun subscribeUi(viewModel: MainViewModel) {

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(
@ -156,6 +167,38 @@ class ClockSettingsFragment : Fragment() {
} }
} }
private fun updateNextAlarmWarningUi() {
show_next_alarm_warning.isVisible = AlarmHelper.isAlarmProbablyWrong(requireContext())
with(requireContext().getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
val alarm = nextAlarmClock
if (alarm != null) {
val pm = requireContext().packageManager as PackageManager
val appNameOrPackage = try {
pm.getApplicationLabel(pm.getApplicationInfo(nextAlarmClock.showIntent.creatorPackage ?: "", 0))
} catch (e: Exception) {
nextAlarmClock.showIntent.creatorPackage
}
show_next_alarm_warning.text = getString(R.string.next_alarm_warning).format(appNameOrPackage)
}
}
}
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

@ -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
@ -137,13 +136,13 @@ 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 {
@ -218,7 +217,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 +228,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
@ -27,16 +26,14 @@ import com.tommasoberlose.anotherwidget.global.Actions
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.helpers.* import com.tommasoberlose.anotherwidget.helpers.*
import com.tommasoberlose.anotherwidget.helpers.WidgetHelper.reduceDimensionWithMaxWidth
import com.tommasoberlose.anotherwidget.receivers.NewCalendarEventReceiver import com.tommasoberlose.anotherwidget.receivers.NewCalendarEventReceiver
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
import com.tommasoberlose.anotherwidget.receivers.WeatherReceiver
import com.tommasoberlose.anotherwidget.receivers.WidgetClickListenerReceiver 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 +55,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 +67,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 {
@ -110,6 +101,13 @@ class MainWidget : AppWidgetProvider() {
// Background // Background
views.setInt(R.id.widget_shape_background, "setColorFilter", ColorHelper.getBackgroundColorRgb()) views.setInt(R.id.widget_shape_background, "setColorFilter", ColorHelper.getBackgroundColorRgb())
views.setInt(R.id.widget_shape_background, "setImageAlpha", ColorHelper.getBackgroundAlpha()) 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)
// Clock // Clock
views = updateClockView(context, views, appWidgetId) views = updateClockView(context, views, appWidgetId)

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()
} }

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

@ -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

@ -205,4 +205,5 @@
<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>
</resources> </resources>

View File

@ -185,4 +185,5 @@
<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>
</resources> </resources>

View File

@ -184,4 +184,5 @@
<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>
</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

@ -196,4 +196,5 @@
<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>
</resources> </resources>

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="71"
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 #Wed May 06 21:31:44 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="71"
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="71"
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="71"
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="71"
android:versionName="2.0.5" > android:versionName="2.0.5" >
<uses-sdk android:targetSdkVersion="29" /> <uses-sdk android:targetSdkVersion="29" />