Merge branch 'master' into translation
* master: Update the build version Update event repository Update the events selector. Fix #95 Fix #113, #111, #79, #107, #109 Add weather icon pack, updates frequency and fix google fit Update ui Update icons Fix dark theme toggle issue Bugfixes Update google fit integration Update beta release update gitignore Clean project files Add google fit connection Add google fit integration
1
.gitignore
vendored
@ -9,3 +9,4 @@
|
|||||||
.externalNativeBuild
|
.externalNativeBuild
|
||||||
/tasksintegration/build
|
/tasksintegration/build
|
||||||
apikey.properties
|
apikey.properties
|
||||||
|
/app/google-services.json
|
||||||
|
BIN
.idea/caches/build_file_checksums.ser
generated
2
.idea/gradle.xml
generated
@ -11,8 +11,6 @@
|
|||||||
<set>
|
<set>
|
||||||
<option value="$PROJECT_DIR$" />
|
<option value="$PROJECT_DIR$" />
|
||||||
<option value="$PROJECT_DIR$/app" />
|
<option value="$PROJECT_DIR$/app" />
|
||||||
<option value="$PROJECT_DIR$/googlefit" />
|
|
||||||
<option value="$PROJECT_DIR$/tasksintegration" />
|
|
||||||
</set>
|
</set>
|
||||||
</option>
|
</option>
|
||||||
<option name="resolveModulePerSourceSet" value="false" />
|
<option name="resolveModulePerSourceSet" value="false" />
|
||||||
|
2
.idea/modules.xml
generated
@ -4,8 +4,6 @@
|
|||||||
<modules>
|
<modules>
|
||||||
<module fileurl="file://$PROJECT_DIR$/Another Widget.iml" filepath="$PROJECT_DIR$/Another Widget.iml" group="Another Widget" />
|
<module fileurl="file://$PROJECT_DIR$/Another Widget.iml" filepath="$PROJECT_DIR$/Another Widget.iml" group="Another Widget" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" group="Another Widget/app" />
|
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" group="Another Widget/app" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/googlefit/googlefit.iml" filepath="$PROJECT_DIR$/googlefit/googlefit.iml" group="Another Widget/googlefit" />
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/tasksintegration/tasksintegration.iml" filepath="$PROJECT_DIR$/tasksintegration/tasksintegration.iml" group="Another Widget/tasksintegration" />
|
|
||||||
</modules>
|
</modules>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
@ -10,6 +10,10 @@ apply plugin: 'kotlin-android-extensions'
|
|||||||
|
|
||||||
apply plugin: 'realm-android'
|
apply plugin: 'realm-android'
|
||||||
|
|
||||||
|
def apiKeyPropertiesFile = rootProject.file("apikey.properties")
|
||||||
|
def apiKeyProperties = new Properties()
|
||||||
|
apiKeyProperties.load(new FileInputStream(apiKeyPropertiesFile))
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 29
|
compileSdkVersion 29
|
||||||
buildToolsVersion "29.0.3"
|
buildToolsVersion "29.0.3"
|
||||||
@ -18,10 +22,12 @@ android {
|
|||||||
applicationId "com.tommasoberlose.anotherwidget"
|
applicationId "com.tommasoberlose.anotherwidget"
|
||||||
minSdkVersion 23
|
minSdkVersion 23
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
versionCode 83
|
versionCode 90
|
||||||
versionName "2.0.6"
|
versionName "2.0.9"
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
|
manifestPlaceholders = [ "AWARENESS_API_KEY": apiKeyProperties['AWARENESS_API_KEY']]
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
@ -52,10 +58,6 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
viewBinding.enabled = true
|
viewBinding.enabled = true
|
||||||
|
|
||||||
dynamicFeatures = [":tasksintegration", ":googlefit"]
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -98,6 +100,10 @@ dependencies {
|
|||||||
implementation 'com.github.bumptech.glide:glide:4.11.0'
|
implementation 'com.github.bumptech.glide:glide:4.11.0'
|
||||||
kapt 'com.github.bumptech.glide:compiler:4.11.0'
|
kapt 'com.github.bumptech.glide:compiler:4.11.0'
|
||||||
|
|
||||||
|
// Fitness
|
||||||
|
implementation 'com.google.android.gms:play-services-fitness:18.0.0'
|
||||||
|
implementation 'com.google.android.gms:play-services-auth:18.0.0'
|
||||||
|
|
||||||
//Weather
|
//Weather
|
||||||
implementation 'com.github.KwabenBerko:OpenWeatherMap-Android-Library:2.0.2'
|
implementation 'com.github.KwabenBerko:OpenWeatherMap-Android-Library:2.0.2'
|
||||||
implementation 'com.google.android.gms:play-services-location:17.0.0'
|
implementation 'com.google.android.gms:play-services-location:17.0.0'
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
{
|
|
||||||
"project_info": {
|
|
||||||
"project_number": "791844924473",
|
|
||||||
"firebase_url": "https://anotherwidget-182008.firebaseio.com",
|
|
||||||
"project_id": "anotherwidget-182008",
|
|
||||||
"storage_bucket": "anotherwidget-182008.appspot.com"
|
|
||||||
},
|
|
||||||
"client": [
|
|
||||||
{
|
|
||||||
"client_info": {
|
|
||||||
"mobilesdk_app_id": "1:791844924473:android:0ad4f6e3890f1ad320b1e8",
|
|
||||||
"android_client_info": {
|
|
||||||
"package_name": "com.tommasoberlose.anotherwidget"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"oauth_client": [
|
|
||||||
{
|
|
||||||
"client_id": "791844924473-73dh46rorjq8vm97dgbn6can2dcpqlf0.apps.googleusercontent.com",
|
|
||||||
"client_type": 3
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"api_key": [
|
|
||||||
{
|
|
||||||
"current_key": "AIzaSyAeJRXstqnzebibxmm3FRM98nbwE_kC8tA"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"services": {
|
|
||||||
"appinvite_service": {
|
|
||||||
"other_platform_oauth_client": [
|
|
||||||
{
|
|
||||||
"client_id": "791844924473-73dh46rorjq8vm97dgbn6can2dcpqlf0.apps.googleusercontent.com",
|
|
||||||
"client_type": 3
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"configuration_version": "1"
|
|
||||||
}
|
|
@ -10,6 +10,10 @@
|
|||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||||
<uses-permission android:name="com.android.vending.BILLING" />
|
<uses-permission android:name="com.android.vending.BILLING" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
|
||||||
|
<uses-permission android:name="android.gms.permission.ACTIVITY_RECOGNITION"/>
|
||||||
|
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
|
||||||
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
@ -21,7 +25,7 @@
|
|||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme"
|
android:theme="@style/AppTheme"
|
||||||
tools:ignore="LockedOrientationActivity">
|
tools:ignore="LockedOrientationActivity">
|
||||||
<activity android:name=".ui.activities.MainActivity" android:launchMode="singleInstance" android:theme="@style/AppTheme.Main" android:screenOrientation="portrait">
|
<activity android:name=".ui.activities.MainActivity" android:launchMode="singleInstance" android:theme="@style/AppTheme.Main">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
@ -82,44 +86,16 @@
|
|||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
|
||||||
<action android:name="com.tommasoberlose.anotherwidget.action.ACTION_WEATHER_UPDATE" />
|
<action android:name="com.tommasoberlose.anotherwidget.action.ACTION_WEATHER_UPDATE" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
|
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
|
||||||
|
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||||
<action android:name="android.intent.action.TIME_SET" />
|
<action android:name="android.intent.action.TIME_SET" />
|
||||||
<action android:name="android.intent.action.TIMEZONE_CHANGED" />
|
<action android:name="android.intent.action.TIMEZONE_CHANGED" />
|
||||||
<action android:name="android.intent.action.LOCALE_CHANGED" />
|
<action android:name="android.intent.action.LOCALE_CHANGED" />
|
||||||
</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"
|
||||||
@ -157,6 +133,16 @@
|
|||||||
<action android:name="android.intent.action.BATTERY_OKAY"/>
|
<action android:name="android.intent.action.BATTERY_OKAY"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
|
<receiver android:name=".receivers.ActivityDetectionReceiver"
|
||||||
|
android:exported="false"
|
||||||
|
android:permission="com.google.android.gms.permission.ACTIVITY_RECOGNITION">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="com.mypackage.ACTION_PROCESS_ACTIVITY_TRANSITIONS" />
|
||||||
|
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
|
||||||
|
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
@ -1,6 +1,7 @@
|
|||||||
package com.tommasoberlose.anotherwidget
|
package com.tommasoberlose.anotherwidget
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import android.util.Log
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import com.chibatching.kotpref.Kotpref
|
import com.chibatching.kotpref.Kotpref
|
||||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||||
|
@ -16,6 +16,7 @@ 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.google.android.material.card.MaterialCardView
|
||||||
import com.tommasoberlose.anotherwidget.R
|
import com.tommasoberlose.anotherwidget.R
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Constants
|
||||||
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark
|
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark
|
||||||
import com.tommasoberlose.anotherwidget.helpers.GlanceProviderHelper
|
import com.tommasoberlose.anotherwidget.helpers.GlanceProviderHelper
|
||||||
import com.tommasoberlose.anotherwidget.models.GlanceProvider
|
import com.tommasoberlose.anotherwidget.models.GlanceProvider
|
||||||
@ -69,7 +70,7 @@ class GlanceProviderSortMenu(
|
|||||||
// move item in `fromPos` to `toPos` in adapter.
|
// move item in `fromPos` to `toPos` in adapter.
|
||||||
adapter.notifyItemMoved(fromPos, toPos)
|
adapter.notifyItemMoved(fromPos, toPos)
|
||||||
|
|
||||||
val list = GlanceProviderHelper.getGlanceProviders()
|
val list = GlanceProviderHelper.getGlanceProviders(context)
|
||||||
Collections.swap(list, fromPos, toPos)
|
Collections.swap(list, fromPos, toPos)
|
||||||
GlanceProviderHelper.saveGlanceProviderOrder(list)
|
GlanceProviderHelper.saveGlanceProviderOrder(list)
|
||||||
return true
|
return true
|
||||||
@ -86,7 +87,7 @@ class GlanceProviderSortMenu(
|
|||||||
mIth.attachToRecyclerView(view.menu)
|
mIth.attachToRecyclerView(view.menu)
|
||||||
|
|
||||||
adapter.updateData(
|
adapter.updateData(
|
||||||
GlanceProviderHelper.getGlanceProviders()
|
GlanceProviderHelper.getGlanceProviders(context)
|
||||||
.mapNotNull { GlanceProviderHelper.getGlanceProviderById(context, it) }
|
.mapNotNull { GlanceProviderHelper.getGlanceProviderById(context, it) }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,17 +16,13 @@ class EventRepository(val context: Context) {
|
|||||||
private val realm by lazy { Realm.getDefaultInstance() }
|
private val realm by lazy { Realm.getDefaultInstance() }
|
||||||
|
|
||||||
fun saveEvents(eventList: ArrayList<Event>) {
|
fun saveEvents(eventList: ArrayList<Event>) {
|
||||||
realm.executeTransactionAsync { realm ->
|
realm.executeTransaction { realm ->
|
||||||
realm.where(Event::class.java).findAll().deleteAllFromRealm()
|
realm.where(Event::class.java).findAll().deleteAllFromRealm()
|
||||||
realm.copyToRealm(eventList)
|
realm.copyToRealm(eventList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun resetNextEventData() {
|
fun resetNextEventData() {
|
||||||
realm.executeTransactionAsync {
|
|
||||||
it.where(Event::class.java).findAll().deleteAllFromRealm()
|
|
||||||
}
|
|
||||||
|
|
||||||
Preferences.bulk {
|
Preferences.bulk {
|
||||||
remove(Preferences::nextEventId)
|
remove(Preferences::nextEventId)
|
||||||
remove(Preferences::nextEventName)
|
remove(Preferences::nextEventName)
|
||||||
@ -44,7 +40,7 @@ class EventRepository(val context: Context) {
|
|||||||
|
|
||||||
fun getNextEvent(): Event? {
|
fun getNextEvent(): Event? {
|
||||||
val nextEvent = getEventByEventId(Preferences.nextEventId)
|
val nextEvent = getEventByEventId(Preferences.nextEventId)
|
||||||
return if (nextEvent != null && nextEvent.endDate > Calendar.getInstance().timeInMillis) {
|
val event = if (nextEvent != null && nextEvent.endDate > Calendar.getInstance().timeInMillis) {
|
||||||
nextEvent
|
nextEvent
|
||||||
} else {
|
} else {
|
||||||
val events = getEvents()
|
val events = getEvents()
|
||||||
@ -57,9 +53,21 @@ class EventRepository(val context: Context) {
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return try {
|
||||||
|
realm.copyFromRealm(event!!)
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
event
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getEventByEventId(id: Long): Event? = realm.where(Event::class.java).equalTo("eventID", id).findFirst()
|
fun getEventByEventId(id: Long): Event? {
|
||||||
|
val event = realm.where(Event::class.java).equalTo("eventID", id).findFirst()
|
||||||
|
return try {
|
||||||
|
realm.copyFromRealm(event!!)
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
event
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun goToNextEvent() {
|
fun goToNextEvent() {
|
||||||
val eventList = getEvents()
|
val eventList = getEvents()
|
||||||
@ -95,8 +103,13 @@ class EventRepository(val context: Context) {
|
|||||||
|
|
||||||
fun getEvents(): RealmResults<Event> {
|
fun getEvents(): RealmResults<Event> {
|
||||||
val now = Calendar.getInstance().timeInMillis
|
val now = Calendar.getInstance().timeInMillis
|
||||||
|
realm.refresh()
|
||||||
return realm.where(Event::class.java).greaterThan("endDate", now).findAll()
|
return realm.where(Event::class.java).greaterThan("endDate", now).findAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getEventsCount(): Int = getEvents().size
|
fun getEventsCount(): Int = getEvents().size
|
||||||
|
|
||||||
|
fun close() {
|
||||||
|
realm.close()
|
||||||
|
}
|
||||||
}
|
}
|
@ -18,8 +18,19 @@ object Constants {
|
|||||||
enum class GlanceProviderId(val id: String) {
|
enum class GlanceProviderId(val id: String) {
|
||||||
PLAYING_SONG("PLAYING_SONG"),
|
PLAYING_SONG("PLAYING_SONG"),
|
||||||
NEXT_CLOCK_ALARM("NEXT_CLOCK_ALARM"),
|
NEXT_CLOCK_ALARM("NEXT_CLOCK_ALARM"),
|
||||||
// BATTERY_LEVEL_LOW("BATTERY_LEVEL_LOW"),
|
BATTERY_LEVEL_LOW("BATTERY_LEVEL_LOW"),
|
||||||
CUSTOM_INFO("CUSTOM_INFO"),
|
CUSTOM_INFO("CUSTOM_INFO"),
|
||||||
// GOOGLE_FIT_STEPS("GOOGLE_FIT_STEPS")
|
GOOGLE_FIT_STEPS("GOOGLE_FIT_STEPS")
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class WidgetUpdateFrequency(val value: Int) {
|
||||||
|
LOW(0),
|
||||||
|
DEFAULT(1),
|
||||||
|
HIGH(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class WeatherIconPack(val value: Int) {
|
||||||
|
DEFAULT(0),
|
||||||
|
MINIMAL(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -30,6 +30,7 @@ object Preferences : KotprefModel() {
|
|||||||
var customLocationLon by stringPref(key = "PREF_CUSTOM_LOCATION_LON", default = "")
|
var customLocationLon by stringPref(key = "PREF_CUSTOM_LOCATION_LON", default = "")
|
||||||
var customLocationAdd by stringPref(key = "PREF_CUSTOM_LOCATION_ADD", default = "")
|
var customLocationAdd by stringPref(key = "PREF_CUSTOM_LOCATION_ADD", default = "")
|
||||||
var dateFormat by stringPref(default = "")
|
var dateFormat by stringPref(default = "")
|
||||||
|
var isDateCapitalize by booleanPref(default = true)
|
||||||
var weatherRefreshPeriod by intPref(key = "PREF_WEATHER_REFRESH_PERIOD", default = 1)
|
var weatherRefreshPeriod by intPref(key = "PREF_WEATHER_REFRESH_PERIOD", default = 1)
|
||||||
var showUntil by intPref(key = "PREF_SHOW_UNTIL", default = 1)
|
var showUntil by intPref(key = "PREF_SHOW_UNTIL", default = 1)
|
||||||
var calendarAppName by stringPref(key = "PREF_CALENDAR_APP_NAME", default = "")
|
var calendarAppName by stringPref(key = "PREF_CALENDAR_APP_NAME", default = "")
|
||||||
@ -40,9 +41,15 @@ object Preferences : KotprefModel() {
|
|||||||
var eventAppName by stringPref(key = "PREF_EVENT_APP_NAME", default = "")
|
var eventAppName by stringPref(key = "PREF_EVENT_APP_NAME", default = "")
|
||||||
var eventAppPackage by stringPref(key = "PREF_EVENT_APP_PACKAGE", default = "")
|
var eventAppPackage by stringPref(key = "PREF_EVENT_APP_PACKAGE", default = "")
|
||||||
var openEventDetails by booleanPref(default = true)
|
var openEventDetails by booleanPref(default = true)
|
||||||
|
|
||||||
|
var widgetUpdateFrequency by intPref(default = Constants.WidgetUpdateFrequency.DEFAULT.value)
|
||||||
|
|
||||||
var textGlobalColor by stringPref(key = "PREF_TEXT_COLOR", default = "#FFFFFF")
|
var textGlobalColor by stringPref(key = "PREF_TEXT_COLOR", default = "#FFFFFF")
|
||||||
var textGlobalAlpha by stringPref(default = "FF")
|
var textGlobalAlpha by stringPref(default = "FF")
|
||||||
|
|
||||||
|
var textSecondaryColor by stringPref(default = "#FFFFFF")
|
||||||
|
var textSecondaryAlpha by stringPref(default = "FF")
|
||||||
|
|
||||||
var backgroundCardColor by stringPref(default = "#000000")
|
var backgroundCardColor by stringPref(default = "#000000")
|
||||||
var backgroundCardAlpha by stringPref(default = "00")
|
var backgroundCardAlpha by stringPref(default = "00")
|
||||||
|
|
||||||
@ -50,6 +57,8 @@ object Preferences : KotprefModel() {
|
|||||||
var clockTextAlpha by stringPref(default = "FF")
|
var clockTextAlpha by stringPref(default = "FF")
|
||||||
var showAMPMIndicator by booleanPref(default = true)
|
var showAMPMIndicator by booleanPref(default = true)
|
||||||
|
|
||||||
|
var weatherIconPack by intPref(default = Constants.WeatherIconPack.DEFAULT.value)
|
||||||
|
|
||||||
// Global
|
// Global
|
||||||
var textMainSize by floatPref(key = "PREF_TEXT_MAIN_SIZE", default = 26f)
|
var textMainSize by floatPref(key = "PREF_TEXT_MAIN_SIZE", default = 26f)
|
||||||
var textSecondSize by floatPref(key = "PREF_TEXT_SECOND_SIZE", default = 18f)
|
var textSecondSize by floatPref(key = "PREF_TEXT_SECOND_SIZE", default = 18f)
|
||||||
@ -83,6 +92,7 @@ object Preferences : KotprefModel() {
|
|||||||
var showBatteryCharging by booleanPref(default = false)
|
var showBatteryCharging by booleanPref(default = false)
|
||||||
var isBatteryLevelLow by booleanPref(default = false)
|
var isBatteryLevelLow by booleanPref(default = false)
|
||||||
var googleFitSteps by longPref(default = -1)
|
var googleFitSteps by longPref(default = -1)
|
||||||
|
var showDailySteps by booleanPref(default = false)
|
||||||
|
|
||||||
var showMusic by booleanPref(default = false)
|
var showMusic by booleanPref(default = false)
|
||||||
var mediaInfoFormat by stringPref(default = "")
|
var mediaInfoFormat by stringPref(default = "")
|
||||||
|
@ -4,6 +4,7 @@ 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
|
||||||
@ -30,6 +31,12 @@ object CalendarHelper {
|
|||||||
val eventList = ArrayList<Event>()
|
val eventList = ArrayList<Event>()
|
||||||
|
|
||||||
val now = Calendar.getInstance()
|
val now = Calendar.getInstance()
|
||||||
|
val begin = Calendar.getInstance().apply {
|
||||||
|
set(Calendar.MILLISECOND, 0)
|
||||||
|
set(Calendar.SECOND, 0)
|
||||||
|
set(Calendar.MINUTE, 0)
|
||||||
|
set(Calendar.HOUR_OF_DAY, 0)
|
||||||
|
}
|
||||||
val limit = Calendar.getInstance()
|
val limit = Calendar.getInstance()
|
||||||
when (Preferences.showUntil) {
|
when (Preferences.showUntil) {
|
||||||
0 -> limit.add(Calendar.HOUR, 3)
|
0 -> limit.add(Calendar.HOUR, 3)
|
||||||
@ -44,7 +51,7 @@ object CalendarHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val builder = CalendarContract.Instances.CONTENT_URI.buildUpon()
|
val builder = CalendarContract.Instances.CONTENT_URI.buildUpon()
|
||||||
ContentUris.appendId(builder, now.timeInMillis)
|
ContentUris.appendId(builder, begin.timeInMillis)
|
||||||
ContentUris.appendId(builder, limit.timeInMillis)
|
ContentUris.appendId(builder, limit.timeInMillis)
|
||||||
|
|
||||||
if (!context.checkGrantedPermission(
|
if (!context.checkGrantedPermission(
|
||||||
@ -55,13 +62,13 @@ object CalendarHelper {
|
|||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
val provider = CalendarProvider(context)
|
val provider = CalendarProvider(context)
|
||||||
val data = provider.getInstances(now.timeInMillis, limit.timeInMillis)
|
val data = provider.getInstances(begin.timeInMillis, limit.timeInMillis)
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
val instances = data.list
|
val instances = data.list
|
||||||
for (instance in instances) {
|
for (instance in instances) {
|
||||||
try {
|
try {
|
||||||
val e = provider.getEvent(instance.eventId)
|
val e = provider.getEvent(instance.eventId)
|
||||||
if (e != null && !e.deleted && instance.begin <= limit.timeInMillis && (Preferences.calendarAllDay || !e.allDay) && !getFilteredCalendarIdList().contains(
|
if (e != null && !e.deleted && instance.begin <= limit.timeInMillis && now.timeInMillis < instance.end && (Preferences.calendarAllDay || !e.allDay) && !getFilteredCalendarIdList().contains(
|
||||||
e.calendarId
|
e.calendarId
|
||||||
) && (Preferences.showDeclinedEvents || e.selfAttendeeStatus.toInt() != CalendarContract.Attendees.ATTENDEE_STATUS_DECLINED)
|
) && (Preferences.showDeclinedEvents || e.selfAttendeeStatus.toInt() != CalendarContract.Attendees.ATTENDEE_STATUS_DECLINED)
|
||||||
) {
|
) {
|
||||||
|
@ -30,6 +30,31 @@ object ColorHelper {
|
|||||||
Color.parseColor("#000000")
|
Color.parseColor("#000000")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getSecondaryFontColor(): Int {
|
||||||
|
return try {
|
||||||
|
Color.parseColor("#%s%s".format(Preferences.textSecondaryAlpha, Preferences.textSecondaryColor.replace("#", "")))
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Color.parseColor("#FFFFFFFF")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getSecondaryFontColorAlpha(): Int {
|
||||||
|
return try {
|
||||||
|
Preferences.textSecondaryAlpha.toIntValue().toDouble() * 255 / 100
|
||||||
|
} catch (e: Exception) {
|
||||||
|
"FF".toIntValue().toDouble() * 255 / 100
|
||||||
|
}.roundToInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getSecondaryFontColorRgb(): Int {
|
||||||
|
return try {
|
||||||
|
Color.parseColor(Preferences.textSecondaryColor)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Color.parseColor("#000000")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getClockFontColor(): Int {
|
fun getClockFontColor(): Int {
|
||||||
return try {
|
return try {
|
||||||
Color.parseColor("#%s%s".format(Preferences.clockTextAlpha, Preferences.clockTextColor.replace("#", "")))
|
Color.parseColor("#%s%s".format(Preferences.clockTextAlpha, Preferences.clockTextColor.replace("#", "")))
|
||||||
|
@ -12,27 +12,30 @@ import java.util.*
|
|||||||
object DateHelper {
|
object DateHelper {
|
||||||
fun getDateText(context: Context, date: Calendar): String {
|
fun getDateText(context: Context, date: Calendar): String {
|
||||||
return if (Preferences.dateFormat != "") {
|
return if (Preferences.dateFormat != "") {
|
||||||
try {
|
val text = try {
|
||||||
SimpleDateFormat(Preferences.dateFormat, Locale.getDefault()).format(date.time)
|
SimpleDateFormat(Preferences.dateFormat, Locale.getDefault()).format(date.time)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
getDefaultDateText(context, date)
|
getDefaultDateText(context, date)
|
||||||
}
|
}
|
||||||
|
if (Preferences.isDateCapitalize) text.getCapWordString() else text
|
||||||
} else {
|
} else {
|
||||||
val flags: Int =
|
val flags: Int =
|
||||||
DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_NO_YEAR or DateUtils.FORMAT_ABBREV_MONTH
|
DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_NO_YEAR or DateUtils.FORMAT_ABBREV_MONTH
|
||||||
"%s, %s".format(
|
val text = "%s, %s".format(
|
||||||
SimpleDateFormat("EEEE", Locale.getDefault()).format(date.time),
|
SimpleDateFormat("EEEE", Locale.getDefault()).format(date.time),
|
||||||
DateUtils.formatDateTime(context, date.timeInMillis, flags)
|
DateUtils.formatDateTime(context, date.timeInMillis, flags)
|
||||||
).getCapWordString()
|
)
|
||||||
|
if (Preferences.isDateCapitalize) text.getCapWordString() else text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDefaultDateText(context: Context, date: Calendar): String {
|
fun getDefaultDateText(context: Context, date: Calendar): String {
|
||||||
val flags: Int =
|
val flags: Int =
|
||||||
DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_NO_YEAR or DateUtils.FORMAT_ABBREV_MONTH
|
DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_NO_YEAR or DateUtils.FORMAT_ABBREV_MONTH
|
||||||
return "%s, %s".format(
|
val text = "%s, %s".format(
|
||||||
SimpleDateFormat("EEEE", Locale.getDefault()).format(date.time),
|
SimpleDateFormat("EEEE", Locale.getDefault()).format(date.time),
|
||||||
DateUtils.formatDateTime(context, date.timeInMillis, flags)
|
DateUtils.formatDateTime(context, date.timeInMillis, flags)
|
||||||
).getCapWordString()
|
)
|
||||||
|
return if (Preferences.isDateCapitalize) text.getCapWordString() else text
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,12 +6,18 @@ import com.tommasoberlose.anotherwidget.db.EventRepository
|
|||||||
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.models.GlanceProvider
|
import com.tommasoberlose.anotherwidget.models.GlanceProvider
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.checkIfFitInstalled
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
|
|
||||||
object GlanceProviderHelper {
|
object GlanceProviderHelper {
|
||||||
fun getGlanceProviders(): ArrayList<Constants.GlanceProviderId> {
|
fun getGlanceProviders(context: Context): ArrayList<Constants.GlanceProviderId> {
|
||||||
val enabledProviders = Preferences.enabledGlanceProviderOrder.split(",").filter { it != "" }
|
val enabledProviders = Preferences.enabledGlanceProviderOrder.split(",").filter { it != "" }
|
||||||
|
|
||||||
val providers = Constants.GlanceProviderId.values()
|
val providers = Constants.GlanceProviderId.values()
|
||||||
|
.filter { it != Constants.GlanceProviderId.BATTERY_LEVEL_LOW }
|
||||||
|
.filter {
|
||||||
|
context.checkIfFitInstalled() || it != Constants.GlanceProviderId.GOOGLE_FIT_STEPS
|
||||||
|
}.toTypedArray()
|
||||||
|
|
||||||
providers.sortWith(Comparator { p1, p2 ->
|
providers.sortWith(Comparator { p1, p2 ->
|
||||||
when {
|
when {
|
||||||
@ -53,18 +59,18 @@ object GlanceProviderHelper {
|
|||||||
R.drawable.round_notes
|
R.drawable.round_notes
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
// Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> {
|
Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> {
|
||||||
// GlanceProvider(providerId.id,
|
GlanceProvider(providerId.id,
|
||||||
// context.getString(R.string.settings_low_battery_level_title),
|
context.getString(R.string.settings_low_battery_level_title),
|
||||||
// R.drawable.round_battery_charging_full
|
R.drawable.round_battery_charging_full
|
||||||
// )
|
)
|
||||||
// }
|
}
|
||||||
// Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> {
|
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> {
|
||||||
// GlanceProvider(providerId.id,
|
GlanceProvider(providerId.id,
|
||||||
// context.getString(R.string.settings_daily_steps_title),
|
context.getString(R.string.settings_daily_steps_title),
|
||||||
// R.drawable.round_directions_walk
|
R.drawable.round_steps
|
||||||
// )
|
)
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,13 +78,13 @@ object GlanceProviderHelper {
|
|||||||
Preferences.enabledGlanceProviderOrder = list.joinToString(separator = ",")
|
Preferences.enabledGlanceProviderOrder = list.joinToString(separator = ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showSpecialWeather(context: Context): Boolean {
|
fun showGlanceProviders(context: Context): Boolean {
|
||||||
return EventRepository(context).getEventsCount() == 0 && (
|
return Preferences.showGlance && EventRepository(context).getEventsCount() == 0 && (
|
||||||
(Preferences.showNextAlarm && AlarmHelper.getNextAlarm(context) != "") ||
|
(Preferences.showNextAlarm && AlarmHelper.getNextAlarm(context) != "") ||
|
||||||
(MediaPlayerHelper.isSomeonePlaying(context)) ||
|
(MediaPlayerHelper.isSomeonePlaying(context)) ||
|
||||||
(Preferences.isBatteryLevelLow) ||
|
(Preferences.isBatteryLevelLow) ||
|
||||||
(Preferences.customNotes.isNotEmpty()) ||
|
(Preferences.customNotes.isNotEmpty()) ||
|
||||||
(Preferences.googleFitSteps > 0)
|
(Preferences.showDailySteps && Preferences.googleFitSteps > 0)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -114,19 +114,40 @@ object IntentHelper {
|
|||||||
if (Preferences.calendarAppPackage == "") {
|
if (Preferences.calendarAppPackage == "") {
|
||||||
Intent(Intent.ACTION_VIEW).apply {
|
Intent(Intent.ACTION_VIEW).apply {
|
||||||
data = uri
|
data = uri
|
||||||
|
if (!e.allDay) {
|
||||||
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)
|
} else {
|
||||||
// type = "vnd.android.cursor.item/event"
|
val start = Calendar.getInstance().apply {
|
||||||
|
timeInMillis = e.startDate
|
||||||
|
}
|
||||||
|
val end = Calendar.getInstance().apply {
|
||||||
|
timeInMillis = e.endDate
|
||||||
|
}
|
||||||
|
|
||||||
|
putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, e.startDate + start.timeZone.getOffset(start.timeInMillis))
|
||||||
|
putExtra(CalendarContract.EXTRA_EVENT_END_TIME, e.endDate + end.timeZone.getOffset(end.timeInMillis))
|
||||||
|
putExtra(CalendarContract.EXTRA_EVENT_ALL_DAY, 1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
getCalendarIntent(context).apply {
|
getCalendarIntent(context).apply {
|
||||||
action = Intent.ACTION_VIEW
|
action = Intent.ACTION_VIEW
|
||||||
data = uri
|
data = uri
|
||||||
|
if (!e.allDay) {
|
||||||
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)
|
} else {
|
||||||
// type = "vnd.android.cursor.item/event"
|
val start = Calendar.getInstance().apply {
|
||||||
|
timeInMillis = e.startDate
|
||||||
|
}
|
||||||
|
val end = Calendar.getInstance().apply {
|
||||||
|
timeInMillis = e.endDate
|
||||||
|
}
|
||||||
|
putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, start.timeInMillis + start.timeZone.getOffset(start.timeInMillis))
|
||||||
|
putExtra(CalendarContract.EXTRA_EVENT_END_TIME, end.timeInMillis + end.timeZone.getOffset(end.timeInMillis))
|
||||||
|
putExtra(CalendarContract.EXTRA_EVENT_ALL_DAY, 1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -178,4 +199,15 @@ object IntentHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getFitIntent(context: Context): Intent {
|
||||||
|
val pm: PackageManager = context.packageManager
|
||||||
|
return try {
|
||||||
|
pm.getLaunchIntentForPackage("com.google.android.apps.fitness")!!.apply {
|
||||||
|
addCategory(Intent.CATEGORY_LAUNCHER)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Intent()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -3,6 +3,8 @@ package com.tommasoberlose.anotherwidget.helpers
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.text.format.DateUtils
|
import android.text.format.DateUtils
|
||||||
import com.tommasoberlose.anotherwidget.R
|
import com.tommasoberlose.anotherwidget.R
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Constants
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import org.joda.time.DateTime
|
import org.joda.time.DateTime
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
@ -68,9 +70,21 @@ object SettingsStringHelper {
|
|||||||
difference += 60 * 1000 - (difference % (60 * 1000))
|
difference += 60 * 1000 - (difference % (60 * 1000))
|
||||||
|
|
||||||
when {
|
when {
|
||||||
difference <= 0 || TimeUnit.MILLISECONDS.toHours(difference) < 1 -> {
|
difference <= 0 -> {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
TimeUnit.MILLISECONDS.toHours(difference) < 1 && Preferences.widgetUpdateFrequency == Constants.WidgetUpdateFrequency.HIGH.value && TimeUnit.MILLISECONDS.toMinutes(difference) > 5 -> {
|
||||||
|
return DateUtils.getRelativeTimeSpanString(start, start - 1000 * 60 * (TimeUnit.MILLISECONDS.toMinutes(difference) - 1 - (TimeUnit.MILLISECONDS.toMinutes(difference) - 1) % 5), DateUtils.MINUTE_IN_MILLIS, DateUtils.FORMAT_ABBREV_RELATIVE).toString()
|
||||||
|
}
|
||||||
|
TimeUnit.MILLISECONDS.toHours(difference) < 1 && Preferences.widgetUpdateFrequency == Constants.WidgetUpdateFrequency.DEFAULT.value && TimeUnit.MILLISECONDS.toMinutes(difference) > 5 -> {
|
||||||
|
return DateUtils.getRelativeTimeSpanString(start, start - 1000 * 60 * (TimeUnit.MILLISECONDS.toMinutes(difference) - 1 - (TimeUnit.MILLISECONDS.toMinutes(difference) - 1) % 15), DateUtils.MINUTE_IN_MILLIS, DateUtils.FORMAT_ABBREV_RELATIVE).toString()
|
||||||
|
}
|
||||||
|
TimeUnit.MILLISECONDS.toHours(difference) < 1 && Preferences.widgetUpdateFrequency == Constants.WidgetUpdateFrequency.LOW.value -> {
|
||||||
|
return context.getString(R.string.soon)
|
||||||
|
}
|
||||||
|
TimeUnit.MILLISECONDS.toHours(difference) < 1 -> {
|
||||||
|
return context.getString(R.string.now)
|
||||||
|
}
|
||||||
TimeUnit.MILLISECONDS.toHours(difference) < 12 -> {
|
TimeUnit.MILLISECONDS.toHours(difference) < 12 -> {
|
||||||
return DateUtils.getRelativeTimeSpanString(start, now, DateUtils.HOUR_IN_MILLIS, DateUtils.FORMAT_ABBREV_RELATIVE).toString()
|
return DateUtils.getRelativeTimeSpanString(start, now, DateUtils.HOUR_IN_MILLIS, DateUtils.FORMAT_ABBREV_RELATIVE).toString()
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import android.os.Build
|
|||||||
import com.google.android.gms.location.LocationServices
|
import com.google.android.gms.location.LocationServices
|
||||||
import com.tommasoberlose.anotherwidget.R
|
import com.tommasoberlose.anotherwidget.R
|
||||||
import com.tommasoberlose.anotherwidget.db.EventRepository
|
import com.tommasoberlose.anotherwidget.db.EventRepository
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Constants
|
||||||
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.fragments.MainFragment
|
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
|
||||||
@ -49,79 +50,79 @@ object WeatherHelper {
|
|||||||
fun getWeatherIconResource(icon: String): Int {
|
fun getWeatherIconResource(icon: String): Int {
|
||||||
when (icon) {
|
when (icon) {
|
||||||
"01d" -> {
|
"01d" -> {
|
||||||
return R.drawable.clear_day
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.clear_day else R.drawable.clear_day_2
|
||||||
}
|
}
|
||||||
"02d" -> {
|
"02d" -> {
|
||||||
return R.drawable.partly_cloudy
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.partly_cloudy else R.drawable.partly_cloudy_2
|
||||||
}
|
}
|
||||||
"03d" -> {
|
"03d" -> {
|
||||||
return R.drawable.mostly_cloudy
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.mostly_cloudy else R.drawable.mostly_cloudy_2
|
||||||
}
|
}
|
||||||
"04d" -> {
|
"04d" -> {
|
||||||
return R.drawable.cloudy_weather
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.cloudy_weather else R.drawable.cloudy_weather_2
|
||||||
}
|
}
|
||||||
"09d" -> {
|
"09d" -> {
|
||||||
return R.drawable.storm_weather_day
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.storm_weather_day else R.drawable.storm_weather_day_2
|
||||||
}
|
}
|
||||||
"10d" -> {
|
"10d" -> {
|
||||||
return R.drawable.rainy_day
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.rainy_day else R.drawable.rainy_day_2
|
||||||
}
|
}
|
||||||
"11d" -> {
|
"11d" -> {
|
||||||
return R.drawable.thunder_day
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.thunder_day else R.drawable.thunder_day_2
|
||||||
}
|
}
|
||||||
"13d" -> {
|
"13d" -> {
|
||||||
return R.drawable.snow_day
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.snow_day else R.drawable.snow_day_2
|
||||||
}
|
}
|
||||||
"50d" -> {
|
"50d" -> {
|
||||||
return R.drawable.haze_day
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.haze_day else R.drawable.haze_day_2
|
||||||
}
|
}
|
||||||
"80d" -> {
|
"80d" -> {
|
||||||
return R.drawable.windy_day
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.windy_day else R.drawable.windy_day_2
|
||||||
}
|
}
|
||||||
"81d" -> {
|
"81d" -> {
|
||||||
return R.drawable.rain_snow_day
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.rain_snow_day else R.drawable.rain_snow_day_2
|
||||||
}
|
}
|
||||||
"82d" -> {
|
"82d" -> {
|
||||||
return R.drawable.haze_weather
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.haze_weather else R.drawable.haze_weather_2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"01n" -> {
|
"01n" -> {
|
||||||
return R.drawable.clear_night
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.clear_night else R.drawable.clear_night_2
|
||||||
}
|
}
|
||||||
"02n" -> {
|
"02n" -> {
|
||||||
return R.drawable.partly_cloudy_night
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.partly_cloudy_night else R.drawable.partly_cloudy_night_2
|
||||||
}
|
}
|
||||||
"03n" -> {
|
"03n" -> {
|
||||||
return R.drawable.mostly_cloudy_night
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.mostly_cloudy_night else R.drawable.mostly_cloudy_night_2
|
||||||
}
|
}
|
||||||
"04n" -> {
|
"04n" -> {
|
||||||
return R.drawable.cloudy_weather
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.cloudy_weather else R.drawable.cloudy_weather_2
|
||||||
}
|
}
|
||||||
"09n" -> {
|
"09n" -> {
|
||||||
return R.drawable.storm_weather_night
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.storm_weather_night else R.drawable.storm_weather_night_2
|
||||||
}
|
}
|
||||||
"10n" -> {
|
"10n" -> {
|
||||||
return R.drawable.rainy_night
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.rainy_night else R.drawable.rainy_night_2
|
||||||
}
|
}
|
||||||
"11n" -> {
|
"11n" -> {
|
||||||
return R.drawable.thunder_night
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.thunder_night else R.drawable.thunder_night_2
|
||||||
}
|
}
|
||||||
"13n" -> {
|
"13n" -> {
|
||||||
return R.drawable.snow_night
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.snow_night else R.drawable.snow_night_2
|
||||||
}
|
}
|
||||||
"50n" -> {
|
"50n" -> {
|
||||||
return R.drawable.haze_night
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.haze_night else R.drawable.haze_night_2
|
||||||
}
|
}
|
||||||
"80n" -> {
|
"80n" -> {
|
||||||
return R.drawable.windy_night
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.windy_night else R.drawable.windy_night_2
|
||||||
}
|
}
|
||||||
"81n" -> {
|
"81n" -> {
|
||||||
return R.drawable.rain_snow_night
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.rain_snow_night else R.drawable.rain_snow_night_2
|
||||||
}
|
}
|
||||||
"82n" -> {
|
"82n" -> {
|
||||||
return R.drawable.haze_weather
|
return if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) R.drawable.haze_weather else R.drawable.haze_weather_2
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
return R.drawable.unknown
|
return R.drawable.unknown
|
||||||
|
@ -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 android.util.Log
|
||||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||||
import com.tommasoberlose.anotherwidget.db.EventRepository
|
import com.tommasoberlose.anotherwidget.db.EventRepository
|
||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
@ -24,19 +25,9 @@ object WidgetHelper {
|
|||||||
return widthInPx to heightInPx
|
return widthInPx to heightInPx
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getWidgetWidth(isPortrait: Boolean, widgetId: Int): Int =
|
private fun getWidgetWidth(isPortrait: Boolean, widgetId: Int): Int = getWidgetSizeInDp(widgetId, AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH)
|
||||||
if (isPortrait) {
|
|
||||||
getWidgetSizeInDp(widgetId, AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH)
|
|
||||||
} else {
|
|
||||||
getWidgetSizeInDp(widgetId, AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getWidgetHeight(isPortrait: Boolean, widgetId: Int): Int =
|
private fun getWidgetHeight(isPortrait: Boolean, widgetId: Int): Int = getWidgetSizeInDp(widgetId, AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT)
|
||||||
if (isPortrait) {
|
|
||||||
getWidgetSizeInDp(widgetId, AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT)
|
|
||||||
} else {
|
|
||||||
getWidgetSizeInDp(widgetId, AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getWidgetSizeInDp(widgetId: Int, key: String): Int =
|
private fun getWidgetSizeInDp(widgetId: Int, key: String): Int =
|
||||||
appWidgetManager.getAppWidgetOptions(widgetId).getInt(key, 0)
|
appWidgetManager.getAppWidgetOptions(widgetId).getInt(key, 0)
|
||||||
|
@ -0,0 +1,176 @@
|
|||||||
|
package com.tommasoberlose.anotherwidget.receivers
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.app.AlarmManager
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Build
|
||||||
|
import android.util.Log
|
||||||
|
import com.google.android.gms.auth.api.signin.GoogleSignIn
|
||||||
|
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
|
||||||
|
import com.google.android.gms.fitness.Fitness
|
||||||
|
import com.google.android.gms.fitness.FitnessOptions
|
||||||
|
import com.google.android.gms.fitness.data.DataType
|
||||||
|
import com.google.android.gms.fitness.data.Field.FIELD_STEPS
|
||||||
|
import com.google.android.gms.fitness.request.DataReadRequest
|
||||||
|
import com.google.android.gms.location.*
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
||||||
|
import java.util.*
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
|
||||||
|
class ActivityDetectionReceiver : BroadcastReceiver() {
|
||||||
|
|
||||||
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
if (ActivityTransitionResult.hasResult(intent)) {
|
||||||
|
val result = ActivityTransitionResult.extractResult(intent)!!
|
||||||
|
val lastEvent = result.transitionEvents.last()
|
||||||
|
|
||||||
|
if (lastEvent.activityType == DetectedActivity.WALKING || lastEvent.activityType == DetectedActivity.RUNNING && lastEvent.transitionType == ActivityTransition.ACTIVITY_TRANSITION_EXIT) {
|
||||||
|
requestDailySteps(context)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (intent.action == Intent.ACTION_BOOT_COMPLETED || intent.action == Intent.ACTION_MY_PACKAGE_REPLACED && Preferences.showDailySteps && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || context.checkGrantedPermission(Manifest.permission.ACTIVITY_RECOGNITION)) {
|
||||||
|
resetDailySteps()
|
||||||
|
registerFence(context)
|
||||||
|
} else {
|
||||||
|
resetDailySteps()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resetDailySteps() {
|
||||||
|
Preferences.googleFitSteps = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val FITNESS_OPTIONS: FitnessOptions = FitnessOptions.builder()
|
||||||
|
.addDataType(DataType.TYPE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)
|
||||||
|
.addDataType(DataType.AGGREGATE_STEP_COUNT_DELTA, FitnessOptions.ACCESS_READ)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
fun registerFence(context: Context) {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || context.checkGrantedPermission(
|
||||||
|
Manifest.permission.ACTIVITY_RECOGNITION)) {
|
||||||
|
val transitions = mutableListOf<ActivityTransition>()
|
||||||
|
|
||||||
|
transitions +=
|
||||||
|
ActivityTransition.Builder()
|
||||||
|
.setActivityType(DetectedActivity.WALKING)
|
||||||
|
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
transitions +=
|
||||||
|
ActivityTransition.Builder()
|
||||||
|
.setActivityType(DetectedActivity.RUNNING)
|
||||||
|
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val request = ActivityTransitionRequest(transitions)
|
||||||
|
|
||||||
|
// myPendingIntent is the instance of PendingIntent where the app receives callbacks.
|
||||||
|
val task = ActivityRecognition.getClient(context)
|
||||||
|
.requestActivityTransitionUpdates(
|
||||||
|
request,
|
||||||
|
PendingIntent.getBroadcast(
|
||||||
|
context,
|
||||||
|
2,
|
||||||
|
Intent(context, ActivityDetectionReceiver::class.java),
|
||||||
|
0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
task.addOnFailureListener { e: Exception ->
|
||||||
|
e.printStackTrace()
|
||||||
|
Preferences.showDailySteps = false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unregisterFence(context: Context) {
|
||||||
|
val task = ActivityRecognition.getClient(context)
|
||||||
|
.removeActivityTransitionUpdates(
|
||||||
|
PendingIntent.getBroadcast(
|
||||||
|
context,
|
||||||
|
2,
|
||||||
|
Intent(context, ActivityDetectionReceiver::class.java),
|
||||||
|
0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
task.addOnCompleteListener {
|
||||||
|
if (it.isSuccessful) {
|
||||||
|
PendingIntent.getBroadcast(
|
||||||
|
context,
|
||||||
|
2,
|
||||||
|
Intent(context, ActivityDetectionReceiver::class.java),
|
||||||
|
0
|
||||||
|
).cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun requestDailySteps(context: Context) {
|
||||||
|
|
||||||
|
val account: GoogleSignInAccount? = GoogleSignIn.getLastSignedInAccount(context)
|
||||||
|
if (account != null && GoogleSignIn.hasPermissions(account, FITNESS_OPTIONS)) {
|
||||||
|
|
||||||
|
val cal: Calendar = Calendar.getInstance()
|
||||||
|
cal.set(Calendar.HOUR_OF_DAY, 0)
|
||||||
|
cal.set(Calendar.MINUTE, 0)
|
||||||
|
cal.set(Calendar.SECOND, 0)
|
||||||
|
cal.set(Calendar.MILLISECOND, 0)
|
||||||
|
val startTime: Long = cal.timeInMillis
|
||||||
|
|
||||||
|
cal.add(Calendar.DAY_OF_YEAR, 1)
|
||||||
|
val endTime: Long = cal.timeInMillis
|
||||||
|
|
||||||
|
val readRequest = DataReadRequest.Builder()
|
||||||
|
.aggregate(
|
||||||
|
DataType.TYPE_STEP_COUNT_DELTA,
|
||||||
|
DataType.AGGREGATE_STEP_COUNT_DELTA
|
||||||
|
)
|
||||||
|
.setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS)
|
||||||
|
.bucketByTime(1, TimeUnit.DAYS)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
Fitness.getHistoryClient(context, account)
|
||||||
|
.readData(readRequest)
|
||||||
|
.addOnSuccessListener { response ->
|
||||||
|
Preferences.googleFitSteps = response.buckets.sumBy {
|
||||||
|
try {
|
||||||
|
it.getDataSet(DataType.AGGREGATE_STEP_COUNT_DELTA)?.dataPoints?.get(
|
||||||
|
0
|
||||||
|
)?.getValue(FIELD_STEPS)?.asInt() ?: 0
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}.toLong()
|
||||||
|
MainWidget.updateWidget(context)
|
||||||
|
setTimeout(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setTimeout(context: Context) {
|
||||||
|
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
|
||||||
|
cancel(PendingIntent.getBroadcast(context, 5, Intent(context, ActivityDetectionReceiver::class.java), 0))
|
||||||
|
setExactAndAllowWhileIdle(
|
||||||
|
AlarmManager.RTC,
|
||||||
|
Calendar.getInstance().timeInMillis + 5 * 60 * 1000,
|
||||||
|
PendingIntent.getBroadcast(
|
||||||
|
context,
|
||||||
|
5,
|
||||||
|
Intent(context, ActivityDetectionReceiver::class.java),
|
||||||
|
0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ import android.content.BroadcastReceiver
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.BatteryManager
|
import android.os.BatteryManager
|
||||||
|
import android.util.Log
|
||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||||
|
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
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")
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,6 +10,8 @@ import androidx.core.app.AlarmManagerCompat
|
|||||||
import androidx.core.content.ContextCompat.getSystemService
|
import androidx.core.content.ContextCompat.getSystemService
|
||||||
import com.tommasoberlose.anotherwidget.db.EventRepository
|
import com.tommasoberlose.anotherwidget.db.EventRepository
|
||||||
import com.tommasoberlose.anotherwidget.global.Actions
|
import com.tommasoberlose.anotherwidget.global.Actions
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Constants
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper
|
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper
|
||||||
import com.tommasoberlose.anotherwidget.models.Event
|
import com.tommasoberlose.anotherwidget.models.Event
|
||||||
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||||
@ -68,9 +70,24 @@ class UpdatesReceiver : BroadcastReceiver() {
|
|||||||
val diff = Period(now.timeInMillis, event.startDate)
|
val diff = Period(now.timeInMillis, event.startDate)
|
||||||
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
|
||||||
setExactAndAllowWhileIdle(
|
if (diff.hours == 0) {
|
||||||
|
var minutes = 0
|
||||||
|
when (Preferences.widgetUpdateFrequency) {
|
||||||
|
Constants.WidgetUpdateFrequency.DEFAULT.value -> {
|
||||||
|
minutes = when {
|
||||||
|
diff.minutes > 50 -> 50
|
||||||
|
diff.minutes > 30 -> 30
|
||||||
|
diff.minutes > 15 -> 15
|
||||||
|
else -> 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.WidgetUpdateFrequency.HIGH.value -> {
|
||||||
|
minutes = diff.minutes - (diff.minutes % 5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setExact(
|
||||||
AlarmManager.RTC,
|
AlarmManager.RTC,
|
||||||
if (event.startDate - diff.hours * 1000 * 60 * 60 > (now.timeInMillis + 120 * 1000)) event.startDate - diff.hours * 1000 * 60 * 60 else now.timeInMillis + 120000,
|
if (event.startDate - minutes * 1000 * 60 > (now.timeInMillis + 120 * 1000)) event.startDate - 60 * 1000 * minutes else now.timeInMillis + 120000,
|
||||||
PendingIntent.getBroadcast(
|
PendingIntent.getBroadcast(
|
||||||
context,
|
context,
|
||||||
event.eventID.toInt(),
|
event.eventID.toInt(),
|
||||||
@ -81,11 +98,26 @@ class UpdatesReceiver : BroadcastReceiver() {
|
|||||||
0
|
0
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
setExact(
|
||||||
|
AlarmManager.RTC,
|
||||||
|
event.startDate - diff.hours * 1000 * 60 * 60,
|
||||||
|
PendingIntent.getBroadcast(
|
||||||
|
context,
|
||||||
|
event.eventID.toInt(),
|
||||||
|
Intent(context, UpdatesReceiver::class.java).apply {
|
||||||
|
action = Actions.ACTION_TIME_UPDATE
|
||||||
|
putExtra(EVENT_ID, event.eventID)
|
||||||
|
},
|
||||||
|
0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Update the widget one second after the event is finished
|
// Update the widget one second after the event is finished
|
||||||
val fireTime =
|
val fireTime =
|
||||||
if (event.endDate > now.timeInMillis + 120 * 1000) event.endDate else now.timeInMillis + 120000
|
if (event.endDate > now.timeInMillis + 120 * 1000) event.endDate else now.timeInMillis + 120000
|
||||||
setExactAndAllowWhileIdle(
|
setExact(
|
||||||
AlarmManager.RTC,
|
AlarmManager.RTC,
|
||||||
fireTime,
|
fireTime,
|
||||||
PendingIntent.getBroadcast(
|
PendingIntent.getBroadcast(
|
||||||
|
@ -18,7 +18,9 @@ import com.tommasoberlose.anotherwidget.databinding.ActivityCustomDateBinding
|
|||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.helpers.DateHelper
|
import com.tommasoberlose.anotherwidget.helpers.DateHelper
|
||||||
import com.tommasoberlose.anotherwidget.ui.viewmodels.CustomDateViewModel
|
import com.tommasoberlose.anotherwidget.ui.viewmodels.CustomDateViewModel
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.getCapWordString
|
||||||
import com.tommasoberlose.anotherwidget.utils.openURI
|
import com.tommasoberlose.anotherwidget.utils.openURI
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.toast
|
||||||
import kotlinx.android.synthetic.main.activity_custom_date.*
|
import kotlinx.android.synthetic.main.activity_custom_date.*
|
||||||
import kotlinx.android.synthetic.main.activity_custom_location.action_back
|
import kotlinx.android.synthetic.main.activity_custom_location.action_back
|
||||||
import kotlinx.android.synthetic.main.activity_custom_location.list_view
|
import kotlinx.android.synthetic.main.activity_custom_location.list_view
|
||||||
@ -78,7 +80,7 @@ class CustomDateActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
delay(200)
|
delay(200)
|
||||||
val text = if (dateFormat != "") {
|
var text = if (dateFormat != "") {
|
||||||
try {
|
try {
|
||||||
SimpleDateFormat(dateFormat, Locale.getDefault()).format(DATE.time)
|
SimpleDateFormat(dateFormat, Locale.getDefault()).format(DATE.time)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@ -88,6 +90,10 @@ class CustomDateActivity : AppCompatActivity() {
|
|||||||
"__"
|
"__"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Preferences.isDateCapitalize) {
|
||||||
|
text = text.getCapWordString()
|
||||||
|
}
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
action_save.isVisible = text != ERROR_STRING
|
action_save.isVisible = text != ERROR_STRING
|
||||||
loader.visibility = View.INVISIBLE
|
loader.visibility = View.INVISIBLE
|
||||||
@ -96,6 +102,11 @@ class CustomDateActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
viewModel.isDateCapitalize.observe(this, Observer {
|
||||||
|
viewModel.dateInput.value = viewModel.dateInput.value
|
||||||
|
binding.isdCapitalizeEnabled = it
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupListener() {
|
private fun setupListener() {
|
||||||
@ -108,6 +119,15 @@ class CustomDateActivity : AppCompatActivity() {
|
|||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
action_capitalize.setOnClickListener {
|
||||||
|
Preferences.isDateCapitalize = !Preferences.isDateCapitalize
|
||||||
|
}
|
||||||
|
|
||||||
|
action_capitalize.setOnLongClickListener {
|
||||||
|
toast(getString(R.string.action_capitalize_the_date))
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
action_date_format_info.setOnClickListener {
|
action_date_format_info.setOnClickListener {
|
||||||
openURI("https://developer.android.com/reference/java/text/SimpleDateFormat")
|
openURI("https://developer.android.com/reference/java/text/SimpleDateFormat")
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import androidx.lifecycle.ViewModelProvider
|
|||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.NavController
|
import androidx.navigation.NavController
|
||||||
import androidx.navigation.Navigation
|
import androidx.navigation.Navigation
|
||||||
|
import com.chibatching.kotpref.Kotpref
|
||||||
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.Dexter
|
||||||
|
@ -81,6 +81,8 @@ class CalendarTabFragment : Fragment() {
|
|||||||
binding: FragmentCalendarSettingsBinding,
|
binding: FragmentCalendarSettingsBinding,
|
||||||
viewModel: MainViewModel
|
viewModel: MainViewModel
|
||||||
) {
|
) {
|
||||||
|
binding.isCalendarEnabled = Preferences.showEvents
|
||||||
|
|
||||||
viewModel.showEvents.observe(viewLifecycleOwner, Observer {
|
viewModel.showEvents.observe(viewLifecycleOwner, Observer {
|
||||||
maintainScrollPosition {
|
maintainScrollPosition {
|
||||||
binding.isCalendarEnabled = it
|
binding.isCalendarEnabled = it
|
||||||
@ -121,6 +123,17 @@ class CalendarTabFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
viewModel.widgetUpdateFrequency.observe(viewLifecycleOwner, Observer {
|
||||||
|
maintainScrollPosition {
|
||||||
|
widget_update_frequency_label?.text = when (it) {
|
||||||
|
Constants.WidgetUpdateFrequency.HIGH.value -> getString(R.string.settings_widget_update_frequency_high)
|
||||||
|
Constants.WidgetUpdateFrequency.DEFAULT.value -> getString(R.string.settings_widget_update_frequency_default)
|
||||||
|
Constants.WidgetUpdateFrequency.LOW.value -> getString(R.string.settings_widget_update_frequency_low)
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
viewModel.showUntil.observe(viewLifecycleOwner, Observer {
|
viewModel.showUntil.observe(viewLifecycleOwner, Observer {
|
||||||
maintainScrollPosition {
|
maintainScrollPosition {
|
||||||
show_until_label?.text = getString(SettingsStringHelper.getShowUntilString(it))
|
show_until_label?.text = getString(SettingsStringHelper.getShowUntilString(it))
|
||||||
@ -135,12 +148,6 @@ class CalendarTabFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
viewModel.dateFormat.observe(viewLifecycleOwner, Observer {
|
|
||||||
maintainScrollPosition {
|
|
||||||
date_format_label?.text = DateHelper.getDateText(requireContext(), Calendar.getInstance())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
viewModel.calendarAppName.observe(viewLifecycleOwner, Observer {
|
viewModel.calendarAppName.observe(viewLifecycleOwner, Observer {
|
||||||
maintainScrollPosition {
|
maintainScrollPosition {
|
||||||
calendar_app_label?.text = if (it != "") it else getString(R.string.default_calendar_app)
|
calendar_app_label?.text = if (it != "") it else getString(R.string.default_calendar_app)
|
||||||
@ -266,6 +273,18 @@ class CalendarTabFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
action_widget_update_frequency.setOnClickListener {
|
||||||
|
if (Preferences.showEvents) {
|
||||||
|
BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_widget_update_frequency_title), message = getString(R.string.settings_widget_update_frequency_subtitle)).setSelectedValue(Preferences.widgetUpdateFrequency)
|
||||||
|
.addItem(getString(R.string.settings_widget_update_frequency_high), Constants.WidgetUpdateFrequency.HIGH.value)
|
||||||
|
.addItem(getString(R.string.settings_widget_update_frequency_default), Constants.WidgetUpdateFrequency.DEFAULT.value)
|
||||||
|
.addItem(getString(R.string.settings_widget_update_frequency_low), Constants.WidgetUpdateFrequency.LOW.value)
|
||||||
|
.addOnSelectItemListener { value ->
|
||||||
|
Preferences.widgetUpdateFrequency = value
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
action_second_row_info.setOnClickListener {
|
action_second_row_info.setOnClickListener {
|
||||||
if (Preferences.showEvents) {
|
if (Preferences.showEvents) {
|
||||||
val dialog = BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_second_row_info_title)).setSelectedValue(Preferences.secondRowInformation)
|
val dialog = BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_second_row_info_title)).setSelectedValue(Preferences.secondRowInformation)
|
||||||
@ -290,27 +309,6 @@ class CalendarTabFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
action_date_format.setOnClickListener {
|
|
||||||
if (Preferences.showEvents) {
|
|
||||||
val now = Calendar.getInstance()
|
|
||||||
val dialog = BottomSheetMenu<String>(requireContext(), header = getString(R.string.settings_date_format_title)).setSelectedValue(Preferences.dateFormat)
|
|
||||||
|
|
||||||
dialog.addItem(DateHelper.getDefaultDateText(requireContext(), now), "")
|
|
||||||
if (Preferences.dateFormat != "") {
|
|
||||||
dialog.addItem(DateHelper.getDateText(requireContext(), now), Preferences.dateFormat)
|
|
||||||
}
|
|
||||||
dialog.addItem(getString(R.string.custom_date_format), "-")
|
|
||||||
|
|
||||||
dialog.addOnSelectItemListener { value ->
|
|
||||||
if (value == "-") {
|
|
||||||
startActivity(Intent(requireContext(), CustomDateActivity::class.java))
|
|
||||||
} else {
|
|
||||||
Preferences.dateFormat = value
|
|
||||||
}
|
|
||||||
}.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
action_open_event_details.setOnClickListener {
|
action_open_event_details.setOnClickListener {
|
||||||
if (Preferences.showEvents) {
|
if (Preferences.showEvents) {
|
||||||
BottomSheetMenu<Boolean>(requireContext(), header = getString(R.string.settings_event_app_title)).setSelectedValue(Preferences.openEventDetails)
|
BottomSheetMenu<Boolean>(requireContext(), header = getString(R.string.settings_event_app_title)).setSelectedValue(Preferences.openEventDetails)
|
||||||
|
@ -85,6 +85,8 @@ class ClockTabFragment : Fragment() {
|
|||||||
binding: FragmentClockSettingsBinding,
|
binding: FragmentClockSettingsBinding,
|
||||||
viewModel: MainViewModel
|
viewModel: MainViewModel
|
||||||
) {
|
) {
|
||||||
|
binding.isClockVisible = Preferences.showClock
|
||||||
|
|
||||||
viewModel.showBigClockWarning.observe(viewLifecycleOwner, Observer {
|
viewModel.showBigClockWarning.observe(viewLifecycleOwner, Observer {
|
||||||
large_clock_warning?.isVisible = it
|
large_clock_warning?.isVisible = it
|
||||||
small_clock_warning?.isVisible = !it
|
small_clock_warning?.isVisible = !it
|
||||||
|
@ -21,7 +21,9 @@ import com.tommasoberlose.anotherwidget.global.RequestCode
|
|||||||
import com.tommasoberlose.anotherwidget.helpers.ColorHelper
|
import com.tommasoberlose.anotherwidget.helpers.ColorHelper
|
||||||
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toHexValue
|
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toHexValue
|
||||||
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toIntValue
|
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toIntValue
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.DateHelper
|
||||||
import com.tommasoberlose.anotherwidget.helpers.SettingsStringHelper
|
import com.tommasoberlose.anotherwidget.helpers.SettingsStringHelper
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.activities.CustomDateActivity
|
||||||
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 kotlinx.android.synthetic.main.fragment_general_settings.*
|
import kotlinx.android.synthetic.main.fragment_general_settings.*
|
||||||
@ -29,6 +31,7 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
class GeneralTabFragment : Fragment() {
|
class GeneralTabFragment : Fragment() {
|
||||||
@ -113,6 +116,28 @@ class GeneralTabFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
viewModel.textSecondaryColor.observe(viewLifecycleOwner, Observer {
|
||||||
|
maintainScrollPosition {
|
||||||
|
if (Preferences.textSecondaryAlpha == "00") {
|
||||||
|
secondary_font_color_label?.text = getString(R.string.transparent)
|
||||||
|
} else {
|
||||||
|
secondary_font_color_label?.text =
|
||||||
|
"#%s".format(Integer.toHexString(ColorHelper.getSecondaryFontColor())).toUpperCase()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
viewModel.textSecondaryAlpha.observe(viewLifecycleOwner, Observer {
|
||||||
|
maintainScrollPosition {
|
||||||
|
if (Preferences.textSecondaryAlpha == "00") {
|
||||||
|
secondary_font_color_label?.text = getString(R.string.transparent)
|
||||||
|
} else {
|
||||||
|
secondary_font_color_label?.text =
|
||||||
|
"#%s".format(Integer.toHexString(ColorHelper.getSecondaryFontColor())).toUpperCase()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
viewModel.backgroundCardColor.observe(viewLifecycleOwner, Observer {
|
viewModel.backgroundCardColor.observe(viewLifecycleOwner, Observer {
|
||||||
maintainScrollPosition {
|
maintainScrollPosition {
|
||||||
if (Preferences.backgroundCardAlpha == "00") {
|
if (Preferences.backgroundCardAlpha == "00") {
|
||||||
@ -141,6 +166,12 @@ class GeneralTabFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
viewModel.dateFormat.observe(viewLifecycleOwner, Observer {
|
||||||
|
maintainScrollPosition {
|
||||||
|
date_format_label?.text = DateHelper.getDateText(requireContext(), Calendar.getInstance())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
viewModel.customFont.observe(viewLifecycleOwner, Observer {
|
viewModel.customFont.observe(viewLifecycleOwner, Observer {
|
||||||
maintainScrollPosition {
|
maintainScrollPosition {
|
||||||
custom_font_label?.text = getString(SettingsStringHelper.getCustomFontLabel(it))
|
custom_font_label?.text = getString(SettingsStringHelper.getCustomFontLabel(it))
|
||||||
@ -167,7 +198,7 @@ class GeneralTabFragment : Fragment() {
|
|||||||
private fun setupListener() {
|
private fun setupListener() {
|
||||||
action_main_text_size.setOnClickListener {
|
action_main_text_size.setOnClickListener {
|
||||||
val dialog = BottomSheetMenu<Float>(requireContext(), header = getString(R.string.title_main_text_size)).setSelectedValue(Preferences.textMainSize)
|
val dialog = BottomSheetMenu<Float>(requireContext(), header = getString(R.string.title_main_text_size)).setSelectedValue(Preferences.textMainSize)
|
||||||
(32 downTo 10).filter { it % 2 == 0 }.forEach {
|
(40 downTo 10).filter { it % 2 == 0 }.forEach {
|
||||||
dialog.addItem("${it}sp", it.toFloat())
|
dialog.addItem("${it}sp", it.toFloat())
|
||||||
}
|
}
|
||||||
dialog.addOnSelectItemListener { value ->
|
dialog.addOnSelectItemListener { value ->
|
||||||
@ -177,7 +208,7 @@ class GeneralTabFragment : Fragment() {
|
|||||||
|
|
||||||
action_second_text_size.setOnClickListener {
|
action_second_text_size.setOnClickListener {
|
||||||
val dialog = BottomSheetMenu<Float>(requireContext(), header = getString(R.string.title_second_text_size)).setSelectedValue(Preferences.textSecondSize)
|
val dialog = BottomSheetMenu<Float>(requireContext(), header = getString(R.string.title_second_text_size)).setSelectedValue(Preferences.textSecondSize)
|
||||||
(28 downTo 10).filter { it % 2 == 0 }.forEach {
|
(40 downTo 10).filter { it % 2 == 0 }.forEach {
|
||||||
dialog.addItem("${it}sp", it.toFloat())
|
dialog.addItem("${it}sp", it.toFloat())
|
||||||
}
|
}
|
||||||
dialog.addOnSelectItemListener { value ->
|
dialog.addOnSelectItemListener { value ->
|
||||||
@ -202,6 +233,44 @@ class GeneralTabFragment : Fragment() {
|
|||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
action_secondary_font_color.setOnClickListener {
|
||||||
|
BottomSheetColorPicker(requireContext(),
|
||||||
|
colors = colors,
|
||||||
|
header = getString(R.string.settings_secondary_font_color_title),
|
||||||
|
getSelected = ColorHelper::getSecondaryFontColorRgb,
|
||||||
|
onColorSelected = { color: Int ->
|
||||||
|
val colorString = Integer.toHexString(color)
|
||||||
|
Preferences.textSecondaryColor = "#" + if (colorString.length > 6) colorString.substring(2) else colorString
|
||||||
|
},
|
||||||
|
showAlphaSelector = true,
|
||||||
|
alpha = Preferences.textSecondaryAlpha.toIntValue(),
|
||||||
|
onAlphaChangeListener = { alpha ->
|
||||||
|
Preferences.textSecondaryAlpha = alpha.toHexValue()
|
||||||
|
}
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
action_date_format.setOnClickListener {
|
||||||
|
if (Preferences.showEvents) {
|
||||||
|
val now = Calendar.getInstance()
|
||||||
|
val dialog = BottomSheetMenu<String>(requireContext(), header = getString(R.string.settings_date_format_title)).setSelectedValue(Preferences.dateFormat)
|
||||||
|
|
||||||
|
dialog.addItem(DateHelper.getDefaultDateText(requireContext(), now), "")
|
||||||
|
if (Preferences.dateFormat != "") {
|
||||||
|
dialog.addItem(DateHelper.getDateText(requireContext(), now), Preferences.dateFormat)
|
||||||
|
}
|
||||||
|
dialog.addItem(getString(R.string.custom_date_format), "-")
|
||||||
|
|
||||||
|
dialog.addOnSelectItemListener { value ->
|
||||||
|
if (value == "-") {
|
||||||
|
startActivity(Intent(requireContext(), CustomDateActivity::class.java))
|
||||||
|
} else {
|
||||||
|
Preferences.dateFormat = value
|
||||||
|
}
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
action_background_color.setOnClickListener {
|
action_background_color.setOnClickListener {
|
||||||
BottomSheetColorPicker(requireContext(),
|
BottomSheetColorPicker(requireContext(),
|
||||||
colors = colors,
|
colors = colors,
|
||||||
|
@ -1,31 +1,35 @@
|
|||||||
package com.tommasoberlose.anotherwidget.ui.fragments
|
package com.tommasoberlose.anotherwidget.ui.fragments
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.app.Activity
|
||||||
import android.app.AlarmManager
|
import android.app.AlarmManager
|
||||||
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.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
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
|
||||||
import android.widget.ImageView
|
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.databinding.DataBindingUtil
|
import androidx.databinding.DataBindingUtil
|
||||||
import androidx.fragment.app.Fragment
|
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.recyclerview.widget.ItemTouchHelper
|
import com.google.android.gms.auth.api.signin.GoogleSignIn
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
|
||||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
import com.google.android.gms.common.api.ApiException
|
||||||
|
import com.karumi.dexter.Dexter
|
||||||
|
import com.karumi.dexter.MultiplePermissionsReport
|
||||||
|
import com.karumi.dexter.PermissionToken
|
||||||
|
import com.karumi.dexter.listener.PermissionRequest
|
||||||
|
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
|
||||||
import com.tommasoberlose.anotherwidget.R
|
import com.tommasoberlose.anotherwidget.R
|
||||||
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
|
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
|
||||||
import com.tommasoberlose.anotherwidget.components.CustomNotesDialog
|
import com.tommasoberlose.anotherwidget.components.CustomNotesDialog
|
||||||
@ -33,16 +37,18 @@ import com.tommasoberlose.anotherwidget.components.GlanceProviderSortMenu
|
|||||||
import com.tommasoberlose.anotherwidget.databinding.FragmentGlanceSettingsBinding
|
import com.tommasoberlose.anotherwidget.databinding.FragmentGlanceSettingsBinding
|
||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.helpers.AlarmHelper
|
import com.tommasoberlose.anotherwidget.helpers.AlarmHelper
|
||||||
import com.tommasoberlose.anotherwidget.helpers.GlanceProviderHelper
|
|
||||||
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
|
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
|
||||||
import com.tommasoberlose.anotherwidget.models.GlanceProvider
|
import com.tommasoberlose.anotherwidget.receivers.ActivityDetectionReceiver
|
||||||
|
import com.tommasoberlose.anotherwidget.receivers.ActivityDetectionReceiver.Companion.FITNESS_OPTIONS
|
||||||
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
|
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.checkGrantedPermission
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.checkIfFitInstalled
|
||||||
|
import kotlinx.android.synthetic.main.fragment_calendar_settings.*
|
||||||
import kotlinx.android.synthetic.main.fragment_glance_settings.*
|
import kotlinx.android.synthetic.main.fragment_glance_settings.*
|
||||||
|
import kotlinx.android.synthetic.main.fragment_glance_settings.scrollView
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import net.idik.lib.slimadapter.SlimAdapter
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
|
|
||||||
class GlanceTabFragment : Fragment() {
|
class GlanceTabFragment : Fragment() {
|
||||||
@ -76,6 +82,8 @@ class GlanceTabFragment : Fragment() {
|
|||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
|
||||||
|
action_show_steps.isVisible = requireContext().checkIfFitInstalled()
|
||||||
|
|
||||||
setupListener()
|
setupListener()
|
||||||
updateNextAlarmWarningUi()
|
updateNextAlarmWarningUi()
|
||||||
}
|
}
|
||||||
@ -84,6 +92,7 @@ class GlanceTabFragment : Fragment() {
|
|||||||
binding: FragmentGlanceSettingsBinding,
|
binding: FragmentGlanceSettingsBinding,
|
||||||
viewModel: MainViewModel
|
viewModel: MainViewModel
|
||||||
) {
|
) {
|
||||||
|
binding.isGlanceVisible = Preferences.showGlance
|
||||||
|
|
||||||
viewModel.showGlance.observe(viewLifecycleOwner, Observer {
|
viewModel.showGlance.observe(viewLifecycleOwner, Observer {
|
||||||
maintainScrollPosition {
|
maintainScrollPosition {
|
||||||
@ -109,6 +118,13 @@ class GlanceTabFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
viewModel.showDailySteps.observe(viewLifecycleOwner, Observer {
|
||||||
|
maintainScrollPosition {
|
||||||
|
show_steps_label?.text = if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
|
||||||
|
}
|
||||||
|
checkFitnessPermission()
|
||||||
|
})
|
||||||
|
|
||||||
viewModel.customInfo.observe(viewLifecycleOwner, Observer {
|
viewModel.customInfo.observe(viewLifecycleOwner, Observer {
|
||||||
maintainScrollPosition {
|
maintainScrollPosition {
|
||||||
show_custom_notes_label?.text = if (it == "") getString(R.string.settings_not_visible) else it
|
show_custom_notes_label?.text = if (it == "") getString(R.string.settings_not_visible) else it
|
||||||
@ -174,6 +190,30 @@ class GlanceTabFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
action_show_steps.setOnClickListener {
|
||||||
|
if (Preferences.showGlance) {
|
||||||
|
BottomSheetMenu<Boolean>(
|
||||||
|
requireContext(),
|
||||||
|
header = getString(R.string.settings_daily_steps_title)
|
||||||
|
).setSelectedValue(Preferences.showDailySteps)
|
||||||
|
.addItem(getString(R.string.settings_visible), true)
|
||||||
|
.addItem(getString(R.string.settings_not_visible), false)
|
||||||
|
.addOnSelectItemListener { value ->
|
||||||
|
if (value) {
|
||||||
|
val account: GoogleSignInAccount? = GoogleSignIn.getLastSignedInAccount(requireContext())
|
||||||
|
if (!GoogleSignIn.hasPermissions(account, FITNESS_OPTIONS)) {
|
||||||
|
val mGoogleSignInClient = GoogleSignIn.getClient(requireActivity(), GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).addExtension(FITNESS_OPTIONS).build())
|
||||||
|
startActivityForResult(mGoogleSignInClient.signInIntent, 2)
|
||||||
|
} else {
|
||||||
|
Preferences.showDailySteps = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Preferences.showDailySteps = false
|
||||||
|
}
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
action_show_custom_notes.setOnClickListener {
|
action_show_custom_notes.setOnClickListener {
|
||||||
if (Preferences.showGlance) {
|
if (Preferences.showGlance) {
|
||||||
CustomNotesDialog(requireContext()).show()
|
CustomNotesDialog(requireContext()).show()
|
||||||
@ -228,11 +268,93 @@ class GlanceTabFragment : Fragment() {
|
|||||||
activity?.startActivity(Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"))
|
activity?.startActivity(Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
show_music_label?.text = getString(R.string.settings_show_music_disabled_subtitle)
|
show_music_label?.text = getString(R.string.settings_not_visible)
|
||||||
notification_permission_alert?.isVisible = false
|
notification_permission_alert?.isVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun checkFitnessPermission() {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || activity?.checkGrantedPermission(Manifest.permission.ACTIVITY_RECOGNITION) == true) {
|
||||||
|
fitness_permission_alert?.isVisible = false
|
||||||
|
if (Preferences.showDailySteps) {
|
||||||
|
ActivityDetectionReceiver.registerFence(requireContext())
|
||||||
|
} else {
|
||||||
|
ActivityDetectionReceiver.unregisterFence(requireContext())
|
||||||
|
}
|
||||||
|
show_steps_label?.text = if (Preferences.showDailySteps) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
|
||||||
|
} else if (Preferences.showDailySteps) {
|
||||||
|
ActivityDetectionReceiver.unregisterFence(requireContext())
|
||||||
|
fitness_permission_alert?.isVisible = true
|
||||||
|
show_steps_label?.text = getString(R.string.settings_request_fitness_access)
|
||||||
|
fitness_permission_alert?.setOnClickListener {
|
||||||
|
requireFitnessPermission()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ActivityDetectionReceiver.unregisterFence(requireContext())
|
||||||
|
show_steps_label?.text = getString(R.string.settings_not_visible)
|
||||||
|
fitness_permission_alert?.isVisible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityResult(
|
||||||
|
requestCode: Int,
|
||||||
|
resultCode: Int,
|
||||||
|
data: Intent?
|
||||||
|
) {
|
||||||
|
when (requestCode) {
|
||||||
|
1 -> {
|
||||||
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
|
checkFitnessPermission()
|
||||||
|
} else {
|
||||||
|
Preferences.showDailySteps = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2-> {
|
||||||
|
try {
|
||||||
|
val account: GoogleSignInAccount? = GoogleSignIn.getSignedInAccountFromIntent(data).getResult(ApiException::class.java)
|
||||||
|
if (!GoogleSignIn.hasPermissions(account, FITNESS_OPTIONS)) {
|
||||||
|
GoogleSignIn.requestPermissions(
|
||||||
|
requireActivity(),
|
||||||
|
1,
|
||||||
|
account,
|
||||||
|
FITNESS_OPTIONS)
|
||||||
|
} else {
|
||||||
|
checkFitnessPermission()
|
||||||
|
}
|
||||||
|
} catch (e: ApiException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
Preferences.showDailySteps = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun requireFitnessPermission() {
|
||||||
|
Dexter.withContext(requireContext())
|
||||||
|
.withPermissions(
|
||||||
|
"com.google.android.gms.permission.ACTIVITY_RECOGNITION",
|
||||||
|
"android.gms.permission.ACTIVITY_RECOGNITION",
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACTIVITY_RECOGNITION else "com.google.android.gms.permission.ACTIVITY_RECOGNITION"
|
||||||
|
).withListener(object: MultiplePermissionsListener {
|
||||||
|
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
|
||||||
|
report?.let {
|
||||||
|
if (report.areAllPermissionsGranted()){
|
||||||
|
checkFitnessPermission()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override fun onPermissionRationaleShouldBeShown(
|
||||||
|
permissions: MutableList<PermissionRequest>?,
|
||||||
|
token: PermissionToken?
|
||||||
|
) {
|
||||||
|
// Remember to invoke this method when the custom rationale is closed
|
||||||
|
// or just by default if you don't want to use any custom rationale.
|
||||||
|
token?.continuePermissionRequest()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.check()
|
||||||
|
}
|
||||||
|
|
||||||
private fun maintainScrollPosition(callback: () -> Unit) {
|
private fun maintainScrollPosition(callback: () -> Unit) {
|
||||||
val scrollPosition = scrollView.scrollY
|
val scrollPosition = scrollView.scrollY
|
||||||
callback.invoke()
|
callback.invoke()
|
||||||
|
@ -14,6 +14,7 @@ import android.util.TypedValue
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.ImageView
|
||||||
import android.widget.RelativeLayout
|
import android.widget.RelativeLayout
|
||||||
import androidx.core.animation.addListener
|
import androidx.core.animation.addListener
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
@ -125,8 +126,11 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
private fun updateUI() {
|
private fun updateUI() {
|
||||||
uiJob?.cancel()
|
uiJob?.cancel()
|
||||||
|
|
||||||
|
preview?.clearAnimation()
|
||||||
|
time_container?.clearAnimation()
|
||||||
|
|
||||||
if (Preferences.showPreview) {
|
if (Preferences.showPreview) {
|
||||||
preview.setCardBackgroundColor(
|
preview?.setCardBackgroundColor(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
if (ColorHelper.getFontColor()
|
if (ColorHelper.getFontColor()
|
||||||
@ -134,52 +138,62 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
) android.R.color.white else R.color.colorAccent
|
) android.R.color.white else R.color.colorAccent
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
widget_shape_background.setImageDrawable(BitmapHelper.getTintedDrawable(requireContext(), R.drawable.card_background, ColorHelper.getBackgroundColor()))
|
widget_shape_background?.setImageDrawable(
|
||||||
|
BitmapHelper.getTintedDrawable(
|
||||||
|
requireContext(),
|
||||||
|
R.drawable.card_background,
|
||||||
|
ColorHelper.getBackgroundColor()
|
||||||
|
)
|
||||||
|
)
|
||||||
uiJob = viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
|
uiJob = viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
|
||||||
val generatedView = MainWidget.generateWidgetView(requireContext())
|
val generatedView = MainWidget.generateWidgetView(requireContext())
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
generatedView.measure(0, 0)
|
generatedView.measure(0, 0)
|
||||||
preview.measure(0, 0)
|
preview?.measure(0, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
val bitmap = BitmapHelper.getBitmapFromView(
|
val bitmap = if (preview != null) {
|
||||||
|
BitmapHelper.getBitmapFromView(
|
||||||
generatedView,
|
generatedView,
|
||||||
if (preview.width > 0) preview.width else generatedView.measuredWidth,
|
if (preview.width > 0) preview.width else generatedView.measuredWidth,
|
||||||
generatedView.measuredHeight
|
generatedView.measuredHeight
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
// Clock
|
// Clock
|
||||||
time.setTextColor(ColorHelper.getClockFontColor())
|
time?.setTextColor(ColorHelper.getClockFontColor())
|
||||||
time_am_pm.setTextColor(ColorHelper.getClockFontColor())
|
time_am_pm?.setTextColor(ColorHelper.getClockFontColor())
|
||||||
time.setTextSize(
|
time?.setTextSize(
|
||||||
TypedValue.COMPLEX_UNIT_SP,
|
TypedValue.COMPLEX_UNIT_SP,
|
||||||
Preferences.clockTextSize.toPixel(requireContext())
|
Preferences.clockTextSize.toPixel(requireContext())
|
||||||
)
|
)
|
||||||
time_am_pm.setTextSize(
|
time_am_pm?.setTextSize(
|
||||||
TypedValue.COMPLEX_UNIT_SP,
|
TypedValue.COMPLEX_UNIT_SP,
|
||||||
Preferences.clockTextSize.toPixel(requireContext()) / 5 * 2
|
Preferences.clockTextSize.toPixel(requireContext()) / 5 * 2
|
||||||
)
|
)
|
||||||
time_am_pm.isVisible = Preferences.showAMPMIndicator
|
time_am_pm?.isVisible = Preferences.showAMPMIndicator
|
||||||
|
|
||||||
// Clock bottom margin
|
// Clock bottom margin
|
||||||
clock_bottom_margin_none.isVisible =
|
clock_bottom_margin_none?.isVisible =
|
||||||
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.NONE.value
|
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.NONE.value
|
||||||
clock_bottom_margin_small.isVisible =
|
clock_bottom_margin_small?.isVisible =
|
||||||
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.SMALL.value
|
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.SMALL.value
|
||||||
clock_bottom_margin_medium.isVisible =
|
clock_bottom_margin_medium?.isVisible =
|
||||||
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.MEDIUM.value
|
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.MEDIUM.value
|
||||||
clock_bottom_margin_large.isVisible =
|
clock_bottom_margin_large?.isVisible =
|
||||||
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.LARGE.value
|
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.LARGE.value
|
||||||
|
|
||||||
if ((Preferences.showClock && !time_container.isVisible) || (!Preferences.showClock && time_container.isVisible)) {
|
if ((Preferences.showClock && time_container?.isVisible == false) || (!Preferences.showClock && time_container?.isVisible == true)) {
|
||||||
if (Preferences.showClock) {
|
if (Preferences.showClock) {
|
||||||
time_container.layoutParams = time_container.layoutParams.apply {
|
time_container?.layoutParams = time_container.layoutParams.apply {
|
||||||
height = RelativeLayout.LayoutParams.WRAP_CONTENT
|
height = RelativeLayout.LayoutParams.WRAP_CONTENT
|
||||||
}
|
}
|
||||||
time_container.measure(0, 0)
|
time_container?.measure(0, 0)
|
||||||
}
|
}
|
||||||
val initialHeight = time_container.measuredHeight
|
val initialHeight = time_container?.measuredHeight ?: 0
|
||||||
ValueAnimator.ofFloat(
|
ValueAnimator.ofFloat(
|
||||||
if (Preferences.showClock) 0f else 1f,
|
if (Preferences.showClock) 0f else 1f,
|
||||||
if (Preferences.showClock) 1f else 0f
|
if (Preferences.showClock) 1f else 0f
|
||||||
@ -187,24 +201,27 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
duration = 500L
|
duration = 500L
|
||||||
addUpdateListener {
|
addUpdateListener {
|
||||||
val animatedValue = animatedValue as Float
|
val animatedValue = animatedValue as Float
|
||||||
time_container.layoutParams = time_container.layoutParams.apply {
|
time_container?.layoutParams =
|
||||||
|
time_container.layoutParams.apply {
|
||||||
height = (initialHeight * animatedValue).toInt()
|
height = (initialHeight * animatedValue).toInt()
|
||||||
}
|
}
|
||||||
|
time?.alpha = animatedValue
|
||||||
}
|
}
|
||||||
addListener(
|
addListener(
|
||||||
onStart = {
|
onStart = {
|
||||||
if (Preferences.showClock) {
|
if (Preferences.showClock) {
|
||||||
time_container.isVisible = true
|
time_container?.isVisible = true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onEnd = {
|
onEnd = {
|
||||||
if (!Preferences.showClock) {
|
if (!Preferences.showClock) {
|
||||||
time_container.isVisible = false
|
time_container?.isVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}.start()
|
}.start()
|
||||||
|
|
||||||
|
if (preview != null) {
|
||||||
ValueAnimator.ofInt(
|
ValueAnimator.ofInt(
|
||||||
preview.height,
|
preview.height,
|
||||||
PREVIEW_BASE_HEIGHT.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(
|
PREVIEW_BASE_HEIGHT.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(
|
||||||
@ -219,14 +236,15 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
preview.layoutParams = layoutParams
|
preview.layoutParams = layoutParams
|
||||||
}
|
}
|
||||||
}.start()
|
}.start()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
time_container.layoutParams = time_container.layoutParams.apply {
|
time_container?.layoutParams = time_container.layoutParams.apply {
|
||||||
height = RelativeLayout.LayoutParams.WRAP_CONTENT
|
height = RelativeLayout.LayoutParams.WRAP_CONTENT
|
||||||
}
|
}
|
||||||
time_container.measure(0, 0)
|
time_container?.measure(0, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preview.height == 0) {
|
if (preview != null && preview.height == 0) {
|
||||||
ValueAnimator.ofInt(
|
ValueAnimator.ofInt(
|
||||||
preview.height,
|
preview.height,
|
||||||
PREVIEW_BASE_HEIGHT.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(
|
PREVIEW_BASE_HEIGHT.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(
|
||||||
@ -238,17 +256,22 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
val animatedValue = animatedValue as Int
|
val animatedValue = animatedValue as Int
|
||||||
val layoutParams = preview.layoutParams
|
val layoutParams = preview.layoutParams
|
||||||
layoutParams.height = animatedValue
|
layoutParams.height = animatedValue
|
||||||
preview.layoutParams = layoutParams
|
preview?.layoutParams = layoutParams
|
||||||
}
|
}
|
||||||
}.start()
|
}.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
widget_loader.animate().scaleX(0f).scaleY(0f).alpha(0f).setDuration(200L).start()
|
widget_loader?.animate()?.scaleX(0f)?.scaleY(0f)?.alpha(0f)?.setDuration(200L)?.start()
|
||||||
bitmap_container.setImageBitmap(bitmap)
|
bitmap_container?.apply {
|
||||||
widget.animate().alpha(1f).start()
|
setImageBitmap(bitmap)
|
||||||
|
scaleX = 0.9f
|
||||||
|
scaleY = 0.9f
|
||||||
|
}
|
||||||
|
widget?.animate()?.alpha(1f)?.start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (preview != null) {
|
||||||
ValueAnimator.ofInt(
|
ValueAnimator.ofInt(
|
||||||
preview.height,
|
preview.height,
|
||||||
0
|
0
|
||||||
@ -262,6 +285,7 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
}
|
}
|
||||||
}.start()
|
}.start()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
showErrorBadge()
|
showErrorBadge()
|
||||||
|
|
||||||
@ -272,13 +296,27 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
activity?.let { act ->
|
activity?.let { act ->
|
||||||
val wallpaper = act.getCurrentWallpaper()
|
val wallpaper = act.getCurrentWallpaper()
|
||||||
widget_bg.setImageDrawable(if (it) wallpaper else null)
|
widget_bg.setImageDrawable(if (it) wallpaper else null)
|
||||||
widget_bg.layoutParams = widget_bg.layoutParams.apply {
|
if (wallpaper != null) {
|
||||||
|
widget_bg.layoutParams =
|
||||||
|
(widget_bg.layoutParams as ViewGroup.MarginLayoutParams).apply {
|
||||||
|
|
||||||
val metrics = DisplayMetrics()
|
val metrics = DisplayMetrics()
|
||||||
act.windowManager.defaultDisplay.getMetrics(metrics)
|
act.windowManager.defaultDisplay.getMetrics(metrics)
|
||||||
|
|
||||||
height = metrics.heightPixels
|
val dimensions: Pair<Int, Int> = if (wallpaper.intrinsicWidth >= wallpaper.intrinsicHeight) {
|
||||||
width = (wallpaper?.intrinsicWidth ?: 1) * metrics.heightPixels / (wallpaper?.intrinsicWidth ?: 1)
|
metrics.heightPixels to (wallpaper.intrinsicWidth) * metrics.heightPixels / (wallpaper.intrinsicHeight)
|
||||||
|
} else {
|
||||||
|
metrics.widthPixels to (wallpaper.intrinsicHeight) * metrics.widthPixels / (wallpaper.intrinsicWidth)
|
||||||
|
}
|
||||||
|
|
||||||
|
setMargins(
|
||||||
|
if (dimensions.first >= dimensions.second) (-80).toPixel(requireContext()) else 0,
|
||||||
|
(-80).toPixel(requireContext()), 0, 0
|
||||||
|
)
|
||||||
|
|
||||||
|
width = dimensions.first
|
||||||
|
height = dimensions.second
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -313,11 +351,6 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
}?.isVisible = Preferences.showMusic && !NotificationManagerCompat.getEnabledListenerPackages(requireContext()).contains(requireContext().packageName)
|
}?.isVisible = Preferences.showMusic && !NotificationManagerCompat.getEnabledListenerPackages(requireContext()).contains(requireContext().packageName)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSharedPreferenceChanged(preferences: SharedPreferences, p1: String) {
|
|
||||||
updateUI()
|
|
||||||
MainWidget.updateWidget(requireContext())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
Preferences.preferences.registerOnSharedPreferenceChangeListener(this)
|
Preferences.preferences.registerOnSharedPreferenceChangeListener(this)
|
||||||
@ -332,10 +365,29 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
super.onPause()
|
super.onPause()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var delayJob: Job? = null
|
||||||
|
|
||||||
|
override fun onSharedPreferenceChanged(preferences: SharedPreferences, p1: String) {
|
||||||
|
delayJob?.cancel()
|
||||||
|
delayJob = lifecycleScope.launch(Dispatchers.IO) {
|
||||||
|
delay(200)
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
updateUI()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MainWidget.updateWidget(requireContext())
|
||||||
|
}
|
||||||
|
|
||||||
class UpdateUiMessageEvent
|
class UpdateUiMessageEvent
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
fun onMessageEvent(ignore: UpdateUiMessageEvent?) {
|
fun onMessageEvent(ignore: UpdateUiMessageEvent?) {
|
||||||
|
delayJob?.cancel()
|
||||||
|
delayJob = lifecycleScope.launch(Dispatchers.IO) {
|
||||||
|
delay(200)
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
updateUI()
|
updateUI()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -4,6 +4,7 @@ import android.Manifest
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
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
|
||||||
|
@ -5,6 +5,7 @@ import android.app.Activity
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
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
|
||||||
@ -79,6 +80,8 @@ class WeatherTabFragment : Fragment() {
|
|||||||
binding: FragmentWeatherSettingsBinding,
|
binding: FragmentWeatherSettingsBinding,
|
||||||
viewModel: MainViewModel
|
viewModel: MainViewModel
|
||||||
) {
|
) {
|
||||||
|
binding.isWeatherVisible = Preferences.showWeather
|
||||||
|
|
||||||
viewModel.showWeatherWarning.observe(viewLifecycleOwner, Observer {
|
viewModel.showWeatherWarning.observe(viewLifecycleOwner, Observer {
|
||||||
weather_warning?.isVisible = it
|
weather_warning?.isVisible = it
|
||||||
checkLocationPermission()
|
checkLocationPermission()
|
||||||
@ -124,6 +127,16 @@ class WeatherTabFragment : Fragment() {
|
|||||||
checkLocationPermission()
|
checkLocationPermission()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
viewModel.weatherIconPack.observe(viewLifecycleOwner, Observer {
|
||||||
|
maintainScrollPosition {
|
||||||
|
label_weather_icon_pack?.text = when (it) {
|
||||||
|
Constants.WeatherIconPack.MINIMAL.value -> getString(R.string.settings_weather_icon_pack_minimal)
|
||||||
|
else -> getString(R.string.settings_weather_icon_pack_default)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkLocationPermission()
|
||||||
|
})
|
||||||
|
|
||||||
viewModel.weatherAppName.observe(viewLifecycleOwner, Observer {
|
viewModel.weatherAppName.observe(viewLifecycleOwner, Observer {
|
||||||
maintainScrollPosition {
|
maintainScrollPosition {
|
||||||
weather_app_label?.text =
|
weather_app_label?.text =
|
||||||
@ -215,6 +228,17 @@ class WeatherTabFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
action_weather_icon_pack.setOnClickListener {
|
||||||
|
if (Preferences.showWeather) {
|
||||||
|
BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_weather_icon_pack_title)).setSelectedValue(Preferences.weatherIconPack)
|
||||||
|
.addItem(getString(R.string.settings_weather_icon_pack_default), Constants.WeatherIconPack.DEFAULT.value)
|
||||||
|
.addItem(getString(R.string.settings_weather_icon_pack_minimal), Constants.WeatherIconPack.MINIMAL.value)
|
||||||
|
.addOnSelectItemListener { value ->
|
||||||
|
Preferences.weatherIconPack = value
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
action_weather_app.setOnClickListener {
|
action_weather_app.setOnClickListener {
|
||||||
if (Preferences.showWeather) {
|
if (Preferences.showWeather) {
|
||||||
startActivityForResult(
|
startActivityForResult(
|
||||||
|
@ -3,8 +3,10 @@ package com.tommasoberlose.anotherwidget.ui.viewmodels
|
|||||||
import android.app.Application
|
import android.app.Application
|
||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import com.chibatching.kotpref.livedata.asLiveData
|
||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
|
|
||||||
class CustomDateViewModel(application: Application) : AndroidViewModel(application) {
|
class CustomDateViewModel(application: Application) : AndroidViewModel(application) {
|
||||||
val dateInput: MutableLiveData<String> = MutableLiveData(if (Preferences.dateFormat == "") "EEEE, MMM dd" else Preferences.dateFormat)
|
val dateInput: MutableLiveData<String> = MutableLiveData(if (Preferences.dateFormat == "") "EEEE, MMM dd" else Preferences.dateFormat)
|
||||||
|
val isDateCapitalize = Preferences.asLiveData(Preferences::isDateCapitalize)
|
||||||
}
|
}
|
@ -9,6 +9,8 @@ class MainViewModel : ViewModel() {
|
|||||||
// General Settings
|
// General Settings
|
||||||
val textGlobalColor = Preferences.asLiveData(Preferences::textGlobalColor)
|
val textGlobalColor = Preferences.asLiveData(Preferences::textGlobalColor)
|
||||||
val textGlobalAlpha = Preferences.asLiveData(Preferences::textGlobalAlpha)
|
val textGlobalAlpha = Preferences.asLiveData(Preferences::textGlobalAlpha)
|
||||||
|
val textSecondaryColor = Preferences.asLiveData(Preferences::textSecondaryColor)
|
||||||
|
val textSecondaryAlpha = Preferences.asLiveData(Preferences::textSecondaryAlpha)
|
||||||
val backgroundCardColor = Preferences.asLiveData(Preferences::backgroundCardColor)
|
val backgroundCardColor = Preferences.asLiveData(Preferences::backgroundCardColor)
|
||||||
val backgroundCardAlpha = Preferences.asLiveData(Preferences::backgroundCardAlpha)
|
val backgroundCardAlpha = Preferences.asLiveData(Preferences::backgroundCardAlpha)
|
||||||
val textMainSize = Preferences.asLiveData(Preferences::textMainSize)
|
val textMainSize = Preferences.asLiveData(Preferences::textMainSize)
|
||||||
@ -27,6 +29,7 @@ class MainViewModel : ViewModel() {
|
|||||||
val showNextEvent = Preferences.asLiveData(Preferences::showNextEvent)
|
val showNextEvent = Preferences.asLiveData(Preferences::showNextEvent)
|
||||||
val openEventDetails = Preferences.asLiveData(Preferences::openEventDetails)
|
val openEventDetails = Preferences.asLiveData(Preferences::openEventDetails)
|
||||||
val calendarAppName = Preferences.asLiveData(Preferences::calendarAppName)
|
val calendarAppName = Preferences.asLiveData(Preferences::calendarAppName)
|
||||||
|
val widgetUpdateFrequency = Preferences.asLiveData(Preferences::widgetUpdateFrequency)
|
||||||
|
|
||||||
// Clock Settings
|
// Clock Settings
|
||||||
val showClock = Preferences.asLiveData(Preferences::showClock)
|
val showClock = Preferences.asLiveData(Preferences::showClock)
|
||||||
@ -52,12 +55,14 @@ class MainViewModel : ViewModel() {
|
|||||||
val customLocationAdd = Preferences.asLiveData(Preferences::customLocationAdd)
|
val customLocationAdd = Preferences.asLiveData(Preferences::customLocationAdd)
|
||||||
|
|
||||||
val showWeatherWarning = Preferences.asLiveData(Preferences::showWeatherWarning)
|
val showWeatherWarning = Preferences.asLiveData(Preferences::showWeatherWarning)
|
||||||
|
val weatherIconPack = Preferences.asLiveData(Preferences::weatherIconPack)
|
||||||
|
|
||||||
// Glance
|
// Glance
|
||||||
val showGlance = Preferences.asLiveData(Preferences::showGlance)
|
val showGlance = Preferences.asLiveData(Preferences::showGlance)
|
||||||
val showMusic = Preferences.asLiveData(Preferences::showMusic)
|
val showMusic = Preferences.asLiveData(Preferences::showMusic)
|
||||||
val showNextAlarm = Preferences.asLiveData(Preferences::showNextAlarm)
|
val showNextAlarm = Preferences.asLiveData(Preferences::showNextAlarm)
|
||||||
val showBatteryCharging = Preferences.asLiveData(Preferences::showBatteryCharging)
|
val showBatteryCharging = Preferences.asLiveData(Preferences::showBatteryCharging)
|
||||||
|
val showDailySteps = Preferences.asLiveData(Preferences::showDailySteps)
|
||||||
val customInfo = Preferences.asLiveData(Preferences::customNotes)
|
val customInfo = Preferences.asLiveData(Preferences::customNotes)
|
||||||
|
|
||||||
// Advanced Settings
|
// Advanced Settings
|
||||||
|
@ -35,6 +35,7 @@ import java.lang.Exception
|
|||||||
import java.text.DateFormat
|
import java.text.DateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
|
|
||||||
class MainWidget : AppWidgetProvider() {
|
class MainWidget : AppWidgetProvider() {
|
||||||
@ -85,9 +86,10 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
appWidgetId: Int) {
|
appWidgetId: Int) {
|
||||||
val displayMetrics = Resources.getSystem().displayMetrics
|
val displayMetrics = Resources.getSystem().displayMetrics
|
||||||
val width = displayMetrics.widthPixels
|
val width = displayMetrics.widthPixels
|
||||||
|
val height = displayMetrics.heightPixels
|
||||||
|
|
||||||
val dimensions = WidgetHelper.WidgetSizeProvider(context, appWidgetManager).getWidgetsSize(appWidgetId)
|
val dimensions = WidgetHelper.WidgetSizeProvider(context, appWidgetManager).getWidgetsSize(appWidgetId)
|
||||||
generateWidgetView(context, appWidgetId, appWidgetManager, dimensions.first - 8.toPixel(context) /*width - 16.toPixel(context)*/)
|
generateWidgetView(context, appWidgetId, appWidgetManager, min(dimensions.first - 8.toPixel(context), min(width, height) - 16.toPixel(context)))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateWidgetView(context: Context, appWidgetId: Int, appWidgetManager: AppWidgetManager, w: Int) {
|
private fun generateWidgetView(context: Context, appWidgetId: Int, appWidgetManager: AppWidgetManager, w: Int) {
|
||||||
@ -261,13 +263,8 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
|
|
||||||
views.setViewVisibility(R.id.empty_layout_rect, View.GONE)
|
views.setViewVisibility(R.id.empty_layout_rect, View.GONE)
|
||||||
views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE)
|
views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE)
|
||||||
} else if (Preferences.showGlance) {
|
} else if (GlanceProviderHelper.showGlanceProviders(context)) {
|
||||||
|
loop@ for (provider:Constants.GlanceProviderId in GlanceProviderHelper.getGlanceProviders(context)) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
loop@ for (provider:Constants.GlanceProviderId in GlanceProviderHelper.getGlanceProviders()) {
|
|
||||||
when (provider) {
|
when (provider) {
|
||||||
Constants.GlanceProviderId.PLAYING_SONG -> {
|
Constants.GlanceProviderId.PLAYING_SONG -> {
|
||||||
if (MediaPlayerHelper.isSomeonePlaying(context)) {
|
if (MediaPlayerHelper.isSomeonePlaying(context)) {
|
||||||
@ -293,28 +290,35 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
break@loop
|
break@loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> {
|
Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> {
|
||||||
// if (Preferences.isBatteryLevelLow) {
|
if (Preferences.isBatteryLevelLow) {
|
||||||
// val alarmIntent = PendingIntent.getActivity(
|
val alarmIntent = PendingIntent.getActivity(
|
||||||
// context,
|
context,
|
||||||
// widgetID,
|
widgetID,
|
||||||
// IntentHelper.getClockIntent(context),
|
IntentHelper.getClockIntent(context),
|
||||||
// 0
|
0
|
||||||
// )
|
)
|
||||||
// views.setOnClickPendingIntent(R.id.second_row_rect, alarmIntent)
|
views.setOnClickPendingIntent(R.id.second_row_rect, alarmIntent)
|
||||||
// break@loop
|
break@loop
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
Constants.GlanceProviderId.CUSTOM_INFO -> {
|
Constants.GlanceProviderId.CUSTOM_INFO -> {
|
||||||
if (Preferences.customNotes.isNotEmpty()) {
|
if (Preferences.customNotes.isNotEmpty()) {
|
||||||
break@loop
|
break@loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> {
|
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> {
|
||||||
// if (Preferences.googleFitSteps > 0) {
|
if (Preferences.showDailySteps && Preferences.googleFitSteps > 0) {
|
||||||
// break@loop
|
val fitIntent = PendingIntent.getActivity(
|
||||||
// }
|
context,
|
||||||
// }
|
widgetID,
|
||||||
|
IntentHelper.getFitIntent(context),
|
||||||
|
0
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.second_row_rect, fitIntent)
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,7 +375,7 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
BitmapHelper.getBitmapFromView(v.calendar_weather, draw = false)
|
BitmapHelper.getBitmapFromView(v.calendar_weather, draw = false)
|
||||||
)
|
)
|
||||||
|
|
||||||
if (GlanceProviderHelper.showSpecialWeather(context)) {
|
if (GlanceProviderHelper.showGlanceProviders(context)) {
|
||||||
views.setViewVisibility(R.id.calendar_weather_rect, View.GONE)
|
views.setViewVisibility(R.id.calendar_weather_rect, View.GONE)
|
||||||
} else {
|
} else {
|
||||||
views.setViewVisibility(R.id.special_weather_rect, View.GONE)
|
views.setViewVisibility(R.id.special_weather_rect, View.GONE)
|
||||||
@ -452,7 +456,10 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
val eventRepository = EventRepository(context)
|
val eventRepository = EventRepository(context)
|
||||||
val v = View.inflate(context, R.layout.the_widget, null)
|
val v = View.inflate(context, R.layout.the_widget, null)
|
||||||
|
|
||||||
val now = Calendar.getInstance()
|
val now = Calendar.getInstance().apply {
|
||||||
|
set(Calendar.SECOND, 0)
|
||||||
|
set(Calendar.MILLISECOND, 0)
|
||||||
|
}
|
||||||
|
|
||||||
v.empty_layout.visibility = View.VISIBLE
|
v.empty_layout.visibility = View.VISIBLE
|
||||||
v.calendar_layout.visibility = View.GONE
|
v.calendar_layout.visibility = View.GONE
|
||||||
@ -472,7 +479,7 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
|
|
||||||
v.next_event.text = nextEvent.title
|
v.next_event.text = nextEvent.title
|
||||||
|
|
||||||
if (Preferences.showDiffTime && now.timeInMillis < (nextEvent.startDate - 1000 * 60 * 60)) {
|
if (Preferences.showDiffTime && now.timeInMillis < nextEvent.startDate) {
|
||||||
v.next_event_difference_time.text = if (!nextEvent.allDay) {
|
v.next_event_difference_time.text = if (!nextEvent.allDay) {
|
||||||
SettingsStringHelper.getDifferenceText(
|
SettingsStringHelper.getDifferenceText(
|
||||||
context,
|
context,
|
||||||
@ -494,8 +501,8 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
} else {
|
} else {
|
||||||
v.second_row_icon.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.round_today))
|
v.second_row_icon.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.round_today))
|
||||||
if (!nextEvent.allDay) {
|
if (!nextEvent.allDay) {
|
||||||
val startHour = DateFormat.getTimeInstance(DateFormat.SHORT).format(nextEvent.startDate)
|
val startHour = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.getDefault()).format(nextEvent.startDate)
|
||||||
val endHour = DateFormat.getTimeInstance(DateFormat.SHORT).format(nextEvent.endDate)
|
val endHour = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.getDefault()).format(nextEvent.endDate)
|
||||||
|
|
||||||
var dayDiff = TimeUnit.MILLISECONDS.toDays(nextEvent.endDate - nextEvent.startDate)
|
var dayDiff = TimeUnit.MILLISECONDS.toDays(nextEvent.endDate - nextEvent.startDate)
|
||||||
|
|
||||||
@ -518,15 +525,15 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
val flags: Int = DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_NO_YEAR or DateUtils.FORMAT_ABBREV_MONTH
|
val flags: Int = DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_NO_YEAR or DateUtils.FORMAT_ABBREV_MONTH
|
||||||
v.next_event_date.text = DateUtils.formatDateTime(context, now.timeInMillis, flags).getCapWordString()
|
v.next_event_date.text = DateUtils.formatDateTime(context, now.timeInMillis, flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
v.empty_layout.visibility = View.GONE
|
v.empty_layout.visibility = View.GONE
|
||||||
v.calendar_layout.visibility = View.VISIBLE
|
v.calendar_layout.visibility = View.VISIBLE
|
||||||
} else if (Preferences.showGlance) {
|
} else if (GlanceProviderHelper.showGlanceProviders(context)) {
|
||||||
v.second_row_icon.isVisible = true
|
v.second_row_icon.isVisible = true
|
||||||
loop@ for (provider:Constants.GlanceProviderId in GlanceProviderHelper.getGlanceProviders()) {
|
loop@ for (provider:Constants.GlanceProviderId in GlanceProviderHelper.getGlanceProviders(context)) {
|
||||||
when (provider) {
|
when (provider) {
|
||||||
Constants.GlanceProviderId.PLAYING_SONG -> {
|
Constants.GlanceProviderId.PLAYING_SONG -> {
|
||||||
if (MediaPlayerHelper.isSomeonePlaying(context)) {
|
if (MediaPlayerHelper.isSomeonePlaying(context)) {
|
||||||
@ -552,37 +559,38 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
break@loop
|
break@loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> {
|
Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> {
|
||||||
// if (Preferences.isBatteryLevelLow) {
|
if (Preferences.isBatteryLevelLow) {
|
||||||
// v.second_row_icon.setImageDrawable(
|
v.second_row_icon.setImageDrawable(
|
||||||
// ContextCompat.getDrawable(
|
ContextCompat.getDrawable(
|
||||||
// context,
|
context,
|
||||||
// R.drawable.round_battery_charging_full
|
R.drawable.round_battery_charging_full
|
||||||
// )
|
)
|
||||||
// )
|
)
|
||||||
// v.next_event_date.text = context.getString(R.string.battery_low_warning)
|
v.next_event_date.text = context.getString(R.string.battery_low_warning)
|
||||||
// break@loop
|
break@loop
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
Constants.GlanceProviderId.CUSTOM_INFO -> {
|
Constants.GlanceProviderId.CUSTOM_INFO -> {
|
||||||
if (Preferences.customNotes.isNotEmpty()) {
|
if (Preferences.customNotes.isNotEmpty()) {
|
||||||
v.second_row_icon.isVisible = false
|
v.second_row_icon.isVisible = false
|
||||||
v.next_event_date.text = Preferences.customNotes
|
v.next_event_date.text = Preferences.customNotes
|
||||||
|
v.next_event_date.maxLines = 2
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> {
|
||||||
|
if (Preferences.showDailySteps && Preferences.googleFitSteps > 0) {
|
||||||
|
v.second_row_icon.setImageDrawable(
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
context,
|
||||||
|
R.drawable.round_steps
|
||||||
|
)
|
||||||
|
)
|
||||||
|
v.next_event_date.text = context.getString(R.string.daily_steps_counter).format(Preferences.googleFitSteps)
|
||||||
break@loop
|
break@loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> {
|
|
||||||
// if (Preferences.googleFitSteps > 0) {
|
|
||||||
// v.second_row_icon.setImageDrawable(
|
|
||||||
// ContextCompat.getDrawable(
|
|
||||||
// context,
|
|
||||||
// R.drawable.round_directions_walk
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
// v.next_event_date.text = ""
|
|
||||||
// break@loop
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -593,14 +601,30 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
|
|
||||||
|
|
||||||
// Color
|
// Color
|
||||||
listOf<TextView>(v.empty_date, v.divider1, v.temp, v.next_event, v.next_event_difference_time, v.next_event_date, v.divider2, v.calendar_temp, v.divider3, v.special_temp).forEach {
|
listOf<TextView>(v.empty_date, v.divider1, v.temp, v.next_event, v.next_event_difference_time, v.divider3, v.special_temp).forEach {
|
||||||
it.setTextColor(ColorHelper.getFontColor())
|
it.setTextColor(ColorHelper.getFontColor())
|
||||||
}
|
}
|
||||||
|
|
||||||
listOf<ImageView>(v.second_row_icon, v.action_next, v.action_previous).forEach {
|
if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) {
|
||||||
|
listOf<ImageView>(v.action_next, v.action_previous)
|
||||||
|
} else {
|
||||||
|
listOf<ImageView>(v.action_next, v.action_previous, v.empty_weather_icon, v.special_weather_icon)
|
||||||
|
}.forEach {
|
||||||
it.setColorFilter(ColorHelper.getFontColor())
|
it.setColorFilter(ColorHelper.getFontColor())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
listOf<TextView>(v.next_event_date, v.divider2, v.calendar_temp).forEach {
|
||||||
|
it.setTextColor(ColorHelper.getSecondaryFontColor())
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Preferences.weatherIconPack == Constants.WeatherIconPack.DEFAULT.value) {
|
||||||
|
listOf<ImageView>(v.second_row_icon)
|
||||||
|
} else {
|
||||||
|
listOf<ImageView>(v.second_row_icon, v.weather_icon)
|
||||||
|
}.forEach {
|
||||||
|
it.setColorFilter(ColorHelper.getSecondaryFontColor())
|
||||||
|
}
|
||||||
|
|
||||||
// Text Size
|
// Text Size
|
||||||
listOf<Pair<TextView, Float>>(
|
listOf<Pair<TextView, Float>>(
|
||||||
v.empty_date to Preferences.textMainSize,
|
v.empty_date to Preferences.textMainSize,
|
||||||
@ -621,11 +645,11 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
v.second_row_icon.scaleX = Preferences.textSecondSize / 18f
|
v.second_row_icon.scaleX = Preferences.textSecondSize / 18f
|
||||||
v.second_row_icon.scaleY = Preferences.textSecondSize / 18f
|
v.second_row_icon.scaleY = Preferences.textSecondSize / 18f
|
||||||
|
|
||||||
v.weather_icon.scaleX = Preferences.textSecondSize / 16f
|
v.weather_icon.scaleX = Preferences.textSecondSize / 14f
|
||||||
v.weather_icon.scaleY = Preferences.textSecondSize / 16f
|
v.weather_icon.scaleY = Preferences.textSecondSize / 14f
|
||||||
|
|
||||||
v.empty_weather_icon.scaleX = Preferences.textMainSize / 20f
|
v.empty_weather_icon.scaleX = Preferences.textMainSize / 18f
|
||||||
v.empty_weather_icon.scaleY = Preferences.textMainSize / 20f
|
v.empty_weather_icon.scaleY = Preferences.textMainSize / 18f
|
||||||
|
|
||||||
v.action_next.scaleX = Preferences.textMainSize / 28f
|
v.action_next.scaleX = Preferences.textMainSize / 28f
|
||||||
v.action_next.scaleY = Preferences.textMainSize / 28f
|
v.action_next.scaleY = Preferences.textMainSize / 28f
|
||||||
@ -694,7 +718,7 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
v.calendar_temp.text = currentTemp
|
v.calendar_temp.text = currentTemp
|
||||||
v.special_temp.text = currentTemp
|
v.special_temp.text = currentTemp
|
||||||
|
|
||||||
if (GlanceProviderHelper.showSpecialWeather(context)) {
|
if (GlanceProviderHelper.showGlanceProviders(context)) {
|
||||||
v.calendar_weather.visibility = View.GONE
|
v.calendar_weather.visibility = View.GONE
|
||||||
} else {
|
} else {
|
||||||
v.special_weather.visibility = View.GONE
|
v.special_weather.visibility = View.GONE
|
||||||
|
@ -213,3 +213,12 @@ fun String.getCapWordString(): String {
|
|||||||
this
|
this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Context.checkIfFitInstalled(): Boolean {
|
||||||
|
return try {
|
||||||
|
packageManager.getPackageInfo("com.google.android.apps.fitness", PackageManager.GET_ACTIVITIES)
|
||||||
|
true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
BIN
app/src/main/res/drawable-hdpi/round_access_alarm.png
Normal file
After Width: | Height: | Size: 868 B |
BIN
app/src/main/res/drawable-hdpi/round_access_alarm_black_18.png
Normal file
After Width: | Height: | Size: 459 B |
BIN
app/src/main/res/drawable-hdpi/round_access_alarm_black_24.png
Normal file
After Width: | Height: | Size: 601 B |
BIN
app/src/main/res/drawable-hdpi/round_access_alarm_black_48.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
app/src/main/res/drawable-hdpi/round_filter_none_black_18.png
Normal file
After Width: | Height: | Size: 240 B |
BIN
app/src/main/res/drawable-hdpi/round_filter_none_black_24.png
Normal file
After Width: | Height: | Size: 259 B |
BIN
app/src/main/res/drawable-hdpi/round_filter_none_black_36.png
Normal file
After Width: | Height: | Size: 355 B |
BIN
app/src/main/res/drawable-hdpi/round_filter_none_black_48.png
Normal file
After Width: | Height: | Size: 413 B |
BIN
app/src/main/res/drawable-hdpi/round_format_size.png
Normal file
After Width: | Height: | Size: 206 B |
BIN
app/src/main/res/drawable-hdpi/round_format_size_black_24.png
Normal file
After Width: | Height: | Size: 237 B |
BIN
app/src/main/res/drawable-hdpi/round_format_size_black_36.png
Normal file
After Width: | Height: | Size: 311 B |
BIN
app/src/main/res/drawable-hdpi/round_format_size_black_48.png
Normal file
After Width: | Height: | Size: 306 B |
BIN
app/src/main/res/drawable-hdpi/round_keyboard_capslock.png
Normal file
After Width: | Height: | Size: 306 B |
After Width: | Height: | Size: 167 B |
After Width: | Height: | Size: 204 B |
After Width: | Height: | Size: 268 B |
BIN
app/src/main/res/drawable-hdpi/round_library_alarm.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
app/src/main/res/drawable-hdpi/round_library_books_black_18.png
Normal file
After Width: | Height: | Size: 268 B |
BIN
app/src/main/res/drawable-hdpi/round_library_books_black_24.png
Normal file
After Width: | Height: | Size: 275 B |
BIN
app/src/main/res/drawable-hdpi/round_library_books_black_36.png
Normal file
After Width: | Height: | Size: 372 B |
BIN
app/src/main/res/drawable-hdpi/round_library_books_black_48.png
Normal file
After Width: | Height: | Size: 447 B |
BIN
app/src/main/res/drawable-hdpi/round_library_music.png
Normal file
After Width: | Height: | Size: 415 B |
BIN
app/src/main/res/drawable-hdpi/round_library_music_black_18.png
Normal file
After Width: | Height: | Size: 269 B |
BIN
app/src/main/res/drawable-hdpi/round_library_music_black_24.png
Normal file
After Width: | Height: | Size: 299 B |
BIN
app/src/main/res/drawable-hdpi/round_library_music_black_48.png
Normal file
After Width: | Height: | Size: 494 B |
BIN
app/src/main/res/drawable-hdpi/round_library_steps.png
Normal file
After Width: | Height: | Size: 900 B |
BIN
app/src/main/res/drawable-hdpi/round_steps.png
Normal file
After Width: | Height: | Size: 947 B |
BIN
app/src/main/res/drawable-mdpi/round_access_alarm.png
Normal file
After Width: | Height: | Size: 601 B |
BIN
app/src/main/res/drawable-mdpi/round_access_alarm_black_18.png
Normal file
After Width: | Height: | Size: 309 B |
BIN
app/src/main/res/drawable-mdpi/round_access_alarm_black_24.png
Normal file
After Width: | Height: | Size: 396 B |
BIN
app/src/main/res/drawable-mdpi/round_access_alarm_black_48.png
Normal file
After Width: | Height: | Size: 763 B |
BIN
app/src/main/res/drawable-mdpi/round_filter_none_black_18.png
Normal file
After Width: | Height: | Size: 177 B |
BIN
app/src/main/res/drawable-mdpi/round_filter_none_black_24.png
Normal file
After Width: | Height: | Size: 164 B |
BIN
app/src/main/res/drawable-mdpi/round_filter_none_black_36.png
Normal file
After Width: | Height: | Size: 259 B |
BIN
app/src/main/res/drawable-mdpi/round_filter_none_black_48.png
Normal file
After Width: | Height: | Size: 282 B |
BIN
app/src/main/res/drawable-mdpi/round_format_size.png
Normal file
After Width: | Height: | Size: 159 B |
BIN
app/src/main/res/drawable-mdpi/round_format_size_black_24.png
Normal file
After Width: | Height: | Size: 156 B |
BIN
app/src/main/res/drawable-mdpi/round_format_size_black_36.png
Normal file
After Width: | Height: | Size: 237 B |
BIN
app/src/main/res/drawable-mdpi/round_format_size_black_48.png
Normal file
After Width: | Height: | Size: 232 B |
BIN
app/src/main/res/drawable-mdpi/round_keyboard_capslock.png
Normal file
After Width: | Height: | Size: 243 B |
After Width: | Height: | Size: 147 B |
After Width: | Height: | Size: 151 B |
After Width: | Height: | Size: 204 B |
BIN
app/src/main/res/drawable-mdpi/round_library_alarm.png
Normal file
After Width: | Height: | Size: 556 B |
BIN
app/src/main/res/drawable-mdpi/round_library_books_black_18.png
Normal file
After Width: | Height: | Size: 196 B |
BIN
app/src/main/res/drawable-mdpi/round_library_books_black_24.png
Normal file
After Width: | Height: | Size: 176 B |
BIN
app/src/main/res/drawable-mdpi/round_library_books_black_36.png
Normal file
After Width: | Height: | Size: 275 B |
BIN
app/src/main/res/drawable-mdpi/round_library_books_black_48.png
Normal file
After Width: | Height: | Size: 311 B |
BIN
app/src/main/res/drawable-mdpi/round_library_music.png
Normal file
After Width: | Height: | Size: 299 B |
BIN
app/src/main/res/drawable-mdpi/round_library_music_black_18.png
Normal file
After Width: | Height: | Size: 208 B |
BIN
app/src/main/res/drawable-mdpi/round_library_music_black_24.png
Normal file
After Width: | Height: | Size: 201 B |
BIN
app/src/main/res/drawable-mdpi/round_library_music_black_48.png
Normal file
After Width: | Height: | Size: 351 B |
BIN
app/src/main/res/drawable-mdpi/round_library_steps.png
Normal file
After Width: | Height: | Size: 484 B |
BIN
app/src/main/res/drawable-mdpi/round_steps.png
Normal file
After Width: | Height: | Size: 521 B |
BIN
app/src/main/res/drawable-xhdpi/round_access_alarm.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
app/src/main/res/drawable-xhdpi/round_access_alarm_black_18.png
Normal file
After Width: | Height: | Size: 601 B |
BIN
app/src/main/res/drawable-xhdpi/round_access_alarm_black_24.png
Normal file
After Width: | Height: | Size: 763 B |
BIN
app/src/main/res/drawable-xhdpi/round_access_alarm_black_48.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/drawable-xhdpi/round_filter_none_black_18.png
Normal file
After Width: | Height: | Size: 259 B |
BIN
app/src/main/res/drawable-xhdpi/round_filter_none_black_24.png
Normal file
After Width: | Height: | Size: 282 B |
BIN
app/src/main/res/drawable-xhdpi/round_filter_none_black_36.png
Normal file
After Width: | Height: | Size: 413 B |
BIN
app/src/main/res/drawable-xhdpi/round_filter_none_black_48.png
Normal file
After Width: | Height: | Size: 531 B |