Compare commits
72 Commits
v2.0.15-be
...
v2.1.1
Author | SHA1 | Date | |
---|---|---|---|
c595168320 | |||
61e3e43fd7 | |||
1513b96313 | |||
536ed64d41 | |||
5b2d245e80 | |||
0aec34dcd2 | |||
b2a9b9fbb3 | |||
768f04825e | |||
80ee877bf2 | |||
ac7839ecdc | |||
66d0214cd9 | |||
e069b8f6ab | |||
8a681f0cd7 | |||
92158ec5f2 | |||
ebb37f21ed | |||
2a389cb422 | |||
4504a0617e | |||
9ed34ee17e | |||
a7294edfd4 | |||
49ca17803e | |||
97ab72081d | |||
e6fee0dfe1 | |||
e0c4f24c43 | |||
2a7d0f171b | |||
00dcfc3149 | |||
eb11b603aa | |||
4d2f624448 | |||
7581af4dd2 | |||
0325af6582 | |||
4de0413a35 | |||
c54a24c889 | |||
98eccd2833 | |||
0119a20765 | |||
a1e54892fd | |||
17801fd164 | |||
e6087b2969 | |||
59b8ba26a2 | |||
f190ee5d15 | |||
2f266ffcf8 | |||
0e376aba80 | |||
313e4fa92d | |||
a8ec754bc4 | |||
f8d1188634 | |||
8216fc96b9 | |||
56d95c5559 | |||
c0e747a714 | |||
16076dc145 | |||
c95f9fb943 | |||
331d5772af | |||
e2719b6445 | |||
bd35022f7d | |||
6d9cb750a7 | |||
f85b4c9a6a | |||
df54a4a79e | |||
6ea97e7724 | |||
d27071739d | |||
738781225f | |||
12d32f852b | |||
f0baa60363 | |||
785eb39334 | |||
d289699d08 | |||
c68d0a8327 | |||
de2e223713 | |||
6150dd7e22 | |||
d9ecebe770 | |||
52327715b1 | |||
e301e6e6ec | |||
c884fae362 | |||
eb78257e52 | |||
109aa24af1 | |||
2403f066a3 | |||
9bc7d7b62e |
5
.gitignore
vendored
@ -8,4 +8,7 @@
|
|||||||
.externalNativeBuild
|
.externalNativeBuild
|
||||||
/tasksintegration/build
|
/tasksintegration/build
|
||||||
/app/google-services.json
|
/app/google-services.json
|
||||||
apikey.properties
|
apikey.properties
|
||||||
|
./.idea/*
|
||||||
|
app/release/*
|
||||||
|
/app/release/*
|
23
.idea/assetWizardSettings.xml
generated
@ -123,6 +123,29 @@
|
|||||||
</PersistentState>
|
</PersistentState>
|
||||||
</value>
|
</value>
|
||||||
</entry>
|
</entry>
|
||||||
|
<entry key="vectorWizard">
|
||||||
|
<value>
|
||||||
|
<PersistentState>
|
||||||
|
<option name="children">
|
||||||
|
<map>
|
||||||
|
<entry key="vectorAssetStep">
|
||||||
|
<value>
|
||||||
|
<PersistentState>
|
||||||
|
<option name="values">
|
||||||
|
<map>
|
||||||
|
<entry key="assetSourceType" value="FILE" />
|
||||||
|
<entry key="outputName" value="round_aspect_ratio_24" />
|
||||||
|
<entry key="sourceFile" value="$USER_HOME$/Desktop/round_aspect_ratio_24.svg" />
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</PersistentState>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</PersistentState>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
</map>
|
</map>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
|
BIN
.idea/caches/build_file_checksums.ser
generated
@ -16,18 +16,20 @@ apikeyProperties.load(new FileInputStream(apikeyPropertiesFile))
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
|
|
||||||
compileSdkVersion 29
|
compileSdkVersion 30
|
||||||
buildToolsVersion "29.0.3"
|
buildToolsVersion "29.0.3"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.tommasoberlose.anotherwidget"
|
applicationId "com.tommasoberlose.anotherwidget"
|
||||||
minSdkVersion 23
|
minSdkVersion 23
|
||||||
targetSdkVersion 29
|
targetSdkVersion 30
|
||||||
versionCode 108
|
versionCode 115
|
||||||
versionName "2.0.15"
|
versionName "2.1.1"
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
buildConfigField("String", "GOOGLE_API_KEY", apikeyProperties['GOOGLE_API_KEY'])
|
buildConfigField("String", "GOOGLE_API_KEY", apikeyProperties['GOOGLE_API_KEY'])
|
||||||
|
|
||||||
|
renderscriptSupportModeEnabled true
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
@ -70,9 +72,9 @@ dependencies {
|
|||||||
|
|
||||||
// UI
|
// UI
|
||||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||||
implementation 'com.google.android.material:material:1.3.0-alpha03'
|
implementation 'com.google.android.material:material:1.3.0-beta01'
|
||||||
implementation 'androidx.browser:browser:1.2.0'
|
implementation 'androidx.browser:browser:1.3.0'
|
||||||
implementation 'net.idik:slimadapter:2.1.2'
|
implementation 'net.idik:slimadapter:2.1.2'
|
||||||
implementation 'com.google.android:flexbox:2.0.1'
|
implementation 'com.google.android:flexbox:2.0.1'
|
||||||
|
|
||||||
@ -87,8 +89,8 @@ dependencies {
|
|||||||
implementation 'org.greenrobot:eventbus:3.2.0'
|
implementation 'org.greenrobot:eventbus:3.2.0'
|
||||||
|
|
||||||
// Navigation
|
// Navigation
|
||||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.0'
|
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.2'
|
||||||
implementation 'androidx.navigation:navigation-ui-ktx:2.3.0'
|
implementation 'androidx.navigation:navigation-ui-ktx:2.3.2'
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
implementation 'androidx.multidex:multidex:2.0.1'
|
implementation 'androidx.multidex:multidex:2.0.1'
|
||||||
@ -101,7 +103,7 @@ dependencies {
|
|||||||
kapt 'com.github.bumptech.glide:compiler:4.11.0'
|
kapt 'com.github.bumptech.glide:compiler:4.11.0'
|
||||||
|
|
||||||
// Fitness
|
// Fitness
|
||||||
implementation 'com.google.android.gms:play-services-fitness:18.0.0'
|
implementation 'com.google.android.gms:play-services-fitness:20.0.0'
|
||||||
implementation 'com.google.android.gms:play-services-auth:18.1.0'
|
implementation 'com.google.android.gms:play-services-auth:18.1.0'
|
||||||
|
|
||||||
//Weather
|
//Weather
|
||||||
@ -109,8 +111,8 @@ dependencies {
|
|||||||
implementation 'com.google.android.gms:play-services-location:17.1.0'
|
implementation 'com.google.android.gms:play-services-location:17.1.0'
|
||||||
|
|
||||||
// Billing
|
// Billing
|
||||||
implementation 'com.android.billingclient:billing:3.0.1'
|
implementation 'com.android.billingclient:billing:3.0.2'
|
||||||
implementation 'com.android.billingclient:billing-ktx:3.0.1'
|
implementation 'com.android.billingclient:billing-ktx:3.0.2'
|
||||||
|
|
||||||
// KTX
|
// KTX
|
||||||
implementation "androidx.core:core-ktx:1.3.2"
|
implementation "androidx.core:core-ktx:1.3.2"
|
||||||
@ -126,10 +128,10 @@ dependencies {
|
|||||||
implementation "com.github.haroldadmin:NetworkResponseAdapter:4.0.1"
|
implementation "com.github.haroldadmin:NetworkResponseAdapter:4.0.1"
|
||||||
|
|
||||||
//Coroutines
|
//Coroutines
|
||||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.5'
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
|
||||||
|
|
||||||
// Add the Firebase SDK for Crashlytics.
|
// Add the Firebase SDK for Crashlytics.
|
||||||
implementation 'com.google.firebase:firebase-crashlytics:17.2.2'
|
implementation 'com.google.firebase:firebase-crashlytics:17.3.0'
|
||||||
|
|
||||||
// Preferences
|
// Preferences
|
||||||
implementation 'com.chibatching.kotpref:kotpref:2.11.0'
|
implementation 'com.chibatching.kotpref:kotpref:2.11.0'
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
<uses-permission android:name="android.permission.READ_CALENDAR" />
|
<uses-permission android:name="android.permission.READ_CALENDAR" />
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
<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" />
|
||||||
@ -13,7 +12,7 @@
|
|||||||
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
|
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
|
||||||
<uses-permission android:name="android.gms.permission.ACTIVITY_RECOGNITION"/>
|
<uses-permission android:name="android.gms.permission.ACTIVITY_RECOGNITION"/>
|
||||||
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
|
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
@ -154,6 +153,17 @@
|
|||||||
android:name=".services.UpdateCalendarJob"
|
android:name=".services.UpdateCalendarJob"
|
||||||
android:permission="android.permission.BIND_JOB_SERVICE"
|
android:permission="android.permission.BIND_JOB_SERVICE"
|
||||||
android:exported="true"/>
|
android:exported="true"/>
|
||||||
|
<service
|
||||||
|
android:name=".services.LocationService"
|
||||||
|
android:enabled="true"
|
||||||
|
android:exported="false"
|
||||||
|
android:foregroundServiceType="location" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
|
<queries>
|
||||||
|
<package android:name="com.google.android.apps.fitness"/>
|
||||||
|
<intent>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
</intent>
|
||||||
|
</queries>
|
||||||
</manifest>
|
</manifest>
|
@ -24,6 +24,7 @@ import com.tommasoberlose.anotherwidget.R
|
|||||||
import com.tommasoberlose.anotherwidget.helpers.ColorHelper
|
import com.tommasoberlose.anotherwidget.helpers.ColorHelper
|
||||||
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark
|
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark
|
||||||
import com.tommasoberlose.anotherwidget.utils.expand
|
import com.tommasoberlose.anotherwidget.utils.expand
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
|
||||||
import com.tommasoberlose.anotherwidget.utils.reveal
|
import com.tommasoberlose.anotherwidget.utils.reveal
|
||||||
import com.tommasoberlose.anotherwidget.utils.toPixel
|
import com.tommasoberlose.anotherwidget.utils.toPixel
|
||||||
import com.warkiz.widget.IndicatorSeekBar
|
import com.warkiz.widget.IndicatorSeekBar
|
||||||
@ -93,6 +94,7 @@ class BottomSheetColorPicker(
|
|||||||
injector
|
injector
|
||||||
.with<MaterialCardView>(R.id.color) {
|
.with<MaterialCardView>(R.id.color) {
|
||||||
it.setCardBackgroundColor(ColorStateList.valueOf(item))
|
it.setCardBackgroundColor(ColorStateList.valueOf(item))
|
||||||
|
it.strokeWidth = if ((colors.indexOf(item) == 0 && !context.isDarkTheme()) || (colors.indexOf(item) == 10 && context.isDarkTheme())) 2 else 0
|
||||||
}
|
}
|
||||||
.with<AppCompatImageView>(R.id.check) {
|
.with<AppCompatImageView>(R.id.check) {
|
||||||
if (getSelected?.invoke() == item) {
|
if (getSelected?.invoke() == item) {
|
||||||
|
@ -9,7 +9,7 @@ import com.tommasoberlose.anotherwidget.R
|
|||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import kotlinx.android.synthetic.main.custom_notes_dialog_layout.view.*
|
import kotlinx.android.synthetic.main.custom_notes_dialog_layout.view.*
|
||||||
|
|
||||||
class CustomNotesDialog(context: Context) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) {
|
class CustomNotesDialog(context: Context, callback: (() -> Unit)?) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val view = View.inflate(context, R.layout.custom_notes_dialog_layout, null)
|
val view = View.inflate(context, R.layout.custom_notes_dialog_layout, null)
|
||||||
@ -18,6 +18,7 @@ class CustomNotesDialog(context: Context) : BottomSheetDialog(context, R.style.B
|
|||||||
view.action_positive.setOnClickListener {
|
view.action_positive.setOnClickListener {
|
||||||
Preferences.customNotes = view.notes.text.toString()
|
Preferences.customNotes = view.notes.text.toString()
|
||||||
this.dismiss()
|
this.dismiss()
|
||||||
|
callback?.invoke()
|
||||||
}
|
}
|
||||||
|
|
||||||
view.notes.requestFocus()
|
view.notes.requestFocus()
|
||||||
|
@ -7,6 +7,7 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import android.util.EventLog
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
@ -25,13 +26,16 @@ import com.tommasoberlose.anotherwidget.global.Constants
|
|||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.helpers.ActiveNotificationsHelper
|
import com.tommasoberlose.anotherwidget.helpers.ActiveNotificationsHelper
|
||||||
import com.tommasoberlose.anotherwidget.helpers.AlarmHelper
|
import com.tommasoberlose.anotherwidget.helpers.AlarmHelper
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.GreetingsHelper
|
||||||
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
|
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
|
||||||
import com.tommasoberlose.anotherwidget.receivers.ActivityDetectionReceiver
|
import com.tommasoberlose.anotherwidget.receivers.ActivityDetectionReceiver
|
||||||
import com.tommasoberlose.anotherwidget.ui.activities.AppNotificationsFilterActivity
|
import com.tommasoberlose.anotherwidget.ui.activities.AppNotificationsFilterActivity
|
||||||
import com.tommasoberlose.anotherwidget.ui.activities.MusicPlayersFilterActivity
|
import com.tommasoberlose.anotherwidget.ui.activities.MusicPlayersFilterActivity
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
|
||||||
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
||||||
import kotlinx.android.synthetic.main.glance_provider_settings_layout.view.*
|
import kotlinx.android.synthetic.main.glance_provider_settings_layout.view.*
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
|
||||||
class GlanceSettingsDialog(val context: Activity, val provider: Constants.GlanceProviderId, private val statusCallback: (() -> Unit)?) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) {
|
class GlanceSettingsDialog(val context: Activity, val provider: Constants.GlanceProviderId, private val statusCallback: (() -> Unit)?) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) {
|
||||||
|
|
||||||
@ -47,6 +51,7 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
|
|||||||
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> context.getString(R.string.settings_daily_steps_title)
|
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> context.getString(R.string.settings_daily_steps_title)
|
||||||
Constants.GlanceProviderId.NOTIFICATIONS -> context.getString(R.string.settings_show_notifications_title)
|
Constants.GlanceProviderId.NOTIFICATIONS -> context.getString(R.string.settings_show_notifications_title)
|
||||||
Constants.GlanceProviderId.GREETINGS -> context.getString(R.string.settings_show_greetings_title)
|
Constants.GlanceProviderId.GREETINGS -> context.getString(R.string.settings_show_greetings_title)
|
||||||
|
Constants.GlanceProviderId.EVENTS -> context.getString(R.string.settings_show_events_as_glance_provider_title)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SUBTITLE*/
|
/* SUBTITLE*/
|
||||||
@ -58,13 +63,15 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
|
|||||||
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> context.getString(R.string.settings_daily_steps_subtitle)
|
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> context.getString(R.string.settings_daily_steps_subtitle)
|
||||||
Constants.GlanceProviderId.NOTIFICATIONS -> context.getString(R.string.settings_show_notifications_subtitle)
|
Constants.GlanceProviderId.NOTIFICATIONS -> context.getString(R.string.settings_show_notifications_subtitle)
|
||||||
Constants.GlanceProviderId.GREETINGS -> context.getString(R.string.settings_show_greetings_subtitle)
|
Constants.GlanceProviderId.GREETINGS -> context.getString(R.string.settings_show_greetings_subtitle)
|
||||||
|
Constants.GlanceProviderId.EVENTS -> context.getString(R.string.settings_show_events_as_glance_provider_subtitle)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SONG */
|
/* SONG */
|
||||||
view.action_filter_music_players.isVisible = provider == Constants.GlanceProviderId.PLAYING_SONG
|
view.action_filter_music_players.isVisible = provider == Constants.GlanceProviderId.PLAYING_SONG
|
||||||
if (provider == Constants.GlanceProviderId.PLAYING_SONG) {
|
if (provider == Constants.GlanceProviderId.PLAYING_SONG) {
|
||||||
view.action_filter_music_players.setOnClickListener {
|
view.action_filter_music_players.setOnClickListener {
|
||||||
context.startActivity(Intent(context, MusicPlayersFilterActivity::class.java))
|
dismiss()
|
||||||
|
context.startActivityForResult(Intent(context, MusicPlayersFilterActivity::class.java), 0)
|
||||||
}
|
}
|
||||||
checkNotificationPermission(view)
|
checkNotificationPermission(view)
|
||||||
}
|
}
|
||||||
@ -94,10 +101,24 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
|
|||||||
|
|
||||||
/* NOTIFICATIONS */
|
/* NOTIFICATIONS */
|
||||||
view.action_filter_notifications_app.isVisible = provider == Constants.GlanceProviderId.NOTIFICATIONS
|
view.action_filter_notifications_app.isVisible = provider == Constants.GlanceProviderId.NOTIFICATIONS
|
||||||
|
view.action_change_notification_timer.isVisible = provider == Constants.GlanceProviderId.NOTIFICATIONS
|
||||||
if (provider == Constants.GlanceProviderId.NOTIFICATIONS) {
|
if (provider == Constants.GlanceProviderId.NOTIFICATIONS) {
|
||||||
checkLastNotificationsPermission(view)
|
checkLastNotificationsPermission(view)
|
||||||
|
val stringArray = context.resources.getStringArray(R.array.glance_notifications_timeout)
|
||||||
view.action_filter_notifications_app.setOnClickListener {
|
view.action_filter_notifications_app.setOnClickListener {
|
||||||
context.startActivity(Intent(context, AppNotificationsFilterActivity::class.java))
|
dismiss()
|
||||||
|
context.startActivityForResult(Intent(context, AppNotificationsFilterActivity::class.java), 0)
|
||||||
|
}
|
||||||
|
view.notification_timer_label.text = stringArray[Preferences.hideNotificationAfter]
|
||||||
|
view.action_change_notification_timer.setOnClickListener {
|
||||||
|
val dialog = BottomSheetMenu<Int>(context, header = context.getString(R.string.glance_notification_hide_timeout_title)).setSelectedValue(Preferences.hideNotificationAfter)
|
||||||
|
Constants.GlanceNotificationTimer.values().forEachIndexed { index, timeout ->
|
||||||
|
dialog.addItem(stringArray[index], timeout.value)
|
||||||
|
}
|
||||||
|
dialog.addOnSelectItemListener { value ->
|
||||||
|
Preferences.hideNotificationAfter = value
|
||||||
|
this.show()
|
||||||
|
}.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,6 +129,13 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
|
|||||||
view.divider.isVisible = false
|
view.divider.isVisible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* EVENTS */
|
||||||
|
if (provider == Constants.GlanceProviderId.EVENTS) {
|
||||||
|
view.header.isVisible = false
|
||||||
|
view.divider.isVisible = false
|
||||||
|
checkCalendarConfig(view)
|
||||||
|
}
|
||||||
|
|
||||||
/* TOGGLE */
|
/* TOGGLE */
|
||||||
view.provider_switch.isChecked = when (provider) {
|
view.provider_switch.isChecked = when (provider) {
|
||||||
Constants.GlanceProviderId.PLAYING_SONG -> Preferences.showMusic
|
Constants.GlanceProviderId.PLAYING_SONG -> Preferences.showMusic
|
||||||
@ -117,6 +145,7 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
|
|||||||
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> Preferences.showDailySteps
|
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> Preferences.showDailySteps
|
||||||
Constants.GlanceProviderId.NOTIFICATIONS -> Preferences.showNotifications
|
Constants.GlanceProviderId.NOTIFICATIONS -> Preferences.showNotifications
|
||||||
Constants.GlanceProviderId.GREETINGS -> Preferences.showGreetings
|
Constants.GlanceProviderId.GREETINGS -> Preferences.showGreetings
|
||||||
|
Constants.GlanceProviderId.EVENTS -> Preferences.showEventsAsGlanceProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
var job: Job? = null
|
var job: Job? = null
|
||||||
@ -144,6 +173,7 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
|
|||||||
}
|
}
|
||||||
Constants.GlanceProviderId.GREETINGS -> {
|
Constants.GlanceProviderId.GREETINGS -> {
|
||||||
Preferences.showGreetings = isChecked
|
Preferences.showGreetings = isChecked
|
||||||
|
GreetingsHelper.toggleGreetings(context)
|
||||||
}
|
}
|
||||||
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> {
|
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> {
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
@ -171,6 +201,9 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
|
|||||||
checkFitnessPermission(view)
|
checkFitnessPermission(view)
|
||||||
checkGoogleFitConnection(view)
|
checkGoogleFitConnection(view)
|
||||||
}
|
}
|
||||||
|
Constants.GlanceProviderId.EVENTS -> {
|
||||||
|
Preferences.showEventsAsGlanceProvider = isChecked
|
||||||
|
}
|
||||||
else -> {
|
else -> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -203,6 +236,19 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
|
|||||||
statusCallback?.invoke()
|
statusCallback?.invoke()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun checkCalendarConfig(view: View) {
|
||||||
|
if (!Preferences.showEvents || !context.checkGrantedPermission(Manifest.permission.READ_CALENDAR)) {
|
||||||
|
view.warning_container.isVisible = true
|
||||||
|
view.warning_title.text = context.getString(R.string.settings_show_events_as_glance_provider_error)
|
||||||
|
view.warning_container.setOnClickListener {
|
||||||
|
dismiss()
|
||||||
|
EventBus.getDefault().post(MainFragment.ChangeTabEvent(1))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
view.warning_container.isVisible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun checkNotificationPermission(view: View) {
|
private fun checkNotificationPermission(view: View) {
|
||||||
when {
|
when {
|
||||||
ActiveNotificationsHelper.checkNotificationAccess(context) -> {
|
ActiveNotificationsHelper.checkNotificationAccess(context) -> {
|
||||||
|
@ -18,7 +18,7 @@ import kotlin.collections.ArrayList
|
|||||||
class EventRepository(val context: Context) {
|
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: List<Event>) {
|
||||||
realm.executeTransaction { realm ->
|
realm.executeTransaction { realm ->
|
||||||
realm.where(Event::class.java).findAll().deleteAllFromRealm()
|
realm.where(Event::class.java).findAll().deleteAllFromRealm()
|
||||||
realm.copyToRealm(eventList)
|
realm.copyToRealm(eventList)
|
||||||
|
@ -13,4 +13,5 @@ object Actions {
|
|||||||
const val ACTION_GO_TO_PREVIOUS_EVENT = "com.tommasoberlose.anotherwidget.action.GO_TO_PREVIOUS_EVENT"
|
const val ACTION_GO_TO_PREVIOUS_EVENT = "com.tommasoberlose.anotherwidget.action.GO_TO_PREVIOUS_EVENT"
|
||||||
const val ACTION_REPORT_CRASH = "com.tommasoberlose.anotherwidget.action.REPORT_CRASH"
|
const val ACTION_REPORT_CRASH = "com.tommasoberlose.anotherwidget.action.REPORT_CRASH"
|
||||||
const val ACTION_CLEAR_NOTIFICATION = "com.tommasoberlose.anotherwidget.action.CLEAR_NOTIFICATION"
|
const val ACTION_CLEAR_NOTIFICATION = "com.tommasoberlose.anotherwidget.action.CLEAR_NOTIFICATION"
|
||||||
|
const val ACTION_UPDATE_GREETINGS = "com.tommasoberlose.anotherwidget.action.UPDATE_GREETINGS"
|
||||||
}
|
}
|
@ -32,7 +32,8 @@ object Constants {
|
|||||||
CUSTOM_INFO("CUSTOM_INFO"),
|
CUSTOM_INFO("CUSTOM_INFO"),
|
||||||
GOOGLE_FIT_STEPS("GOOGLE_FIT_STEPS"),
|
GOOGLE_FIT_STEPS("GOOGLE_FIT_STEPS"),
|
||||||
NOTIFICATIONS("NOTIFICATIONS"),
|
NOTIFICATIONS("NOTIFICATIONS"),
|
||||||
GREETINGS("GREETINGS");
|
GREETINGS("GREETINGS"),
|
||||||
|
EVENTS("EVENTS");
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val map = GlanceProviderId.values().associateBy(GlanceProviderId::id)
|
private val map = GlanceProviderId.values().associateBy(GlanceProviderId::id)
|
||||||
@ -61,6 +62,20 @@ object Constants {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class GlanceNotificationTimer(val value: Int) {
|
||||||
|
HALF_MINUTE(0),
|
||||||
|
ONE_MINUTE(1),
|
||||||
|
FIVE_MINUTES(2),
|
||||||
|
TEN_MINUTES(3),
|
||||||
|
FIFTEEN_MINUTES(4),
|
||||||
|
WHEN_DISMISSED(5);
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val map = values().associateBy(GlanceNotificationTimer::value)
|
||||||
|
fun fromInt(type: Int) = map[type]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum class WeatherIconPack(val value: Int) {
|
enum class WeatherIconPack(val value: Int) {
|
||||||
DEFAULT(0),
|
DEFAULT(0),
|
||||||
MINIMAL(1),
|
MINIMAL(1),
|
||||||
|
@ -2,7 +2,10 @@ package com.tommasoberlose.anotherwidget.global
|
|||||||
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.appcompat.app.AppCompatDelegate.*
|
import androidx.appcompat.app.AppCompatDelegate.*
|
||||||
|
import androidx.core.os.ConfigurationCompat
|
||||||
import com.chibatching.kotpref.KotprefModel
|
import com.chibatching.kotpref.KotprefModel
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.isMetric
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
object Preferences : KotprefModel() {
|
object Preferences : KotprefModel() {
|
||||||
override val commitAllPropertiesByDefault: Boolean = true
|
override val commitAllPropertiesByDefault: Boolean = true
|
||||||
@ -14,8 +17,8 @@ object Preferences : KotprefModel() {
|
|||||||
var showWeather by booleanPref(key = "PREF_SHOW_WEATHER", default = false)
|
var showWeather by booleanPref(key = "PREF_SHOW_WEATHER", default = false)
|
||||||
var weatherIcon by stringPref(key = "PREF_WEATHER_ICON", default = "")
|
var weatherIcon by stringPref(key = "PREF_WEATHER_ICON", default = "")
|
||||||
var weatherTemp by floatPref(key = "PREF_WEATHER_TEMP", default = 0f)
|
var weatherTemp by floatPref(key = "PREF_WEATHER_TEMP", default = 0f)
|
||||||
var weatherTempUnit by stringPref(key = "PREF_WEATHER_TEMP_UNIT", default = "F")
|
var weatherTempUnit by stringPref(key = "PREF_WEATHER_TEMP_UNIT", default = if (ConfigurationCompat.getLocales(context.resources.configuration)[0].isMetric()) "C" else "F")
|
||||||
var weatherRealTempUnit by stringPref(key = "PREF_WEATHER_REAL_TEMP_UNIT", default = "F")
|
var weatherRealTempUnit by stringPref(key = "PREF_WEATHER_REAL_TEMP_UNIT", default = if (ConfigurationCompat.getLocales(context.resources.configuration)[0].isMetric()) "C" else "F")
|
||||||
var calendarAllDay by booleanPref(key = "PREF_CALENDAR_ALL_DAY", default = true)
|
var calendarAllDay by booleanPref(key = "PREF_CALENDAR_ALL_DAY", default = true)
|
||||||
var calendarFilter by stringPref(key = "PREF_CALENDAR_FILTER", default = "")
|
var calendarFilter by stringPref(key = "PREF_CALENDAR_FILTER", default = "")
|
||||||
|
|
||||||
@ -43,7 +46,7 @@ object Preferences : KotprefModel() {
|
|||||||
var weatherProviderApiWeatherApi by stringPref(default = "")
|
var weatherProviderApiWeatherApi by stringPref(default = "")
|
||||||
var weatherProviderApiWeatherBit by stringPref(default = "")
|
var weatherProviderApiWeatherBit by stringPref(default = "")
|
||||||
var weatherProviderApiAccuweather by stringPref(default = "")
|
var weatherProviderApiAccuweather by stringPref(default = "")
|
||||||
var weatherProvider by intPref(default = Constants.WeatherProvider.OPEN_WEATHER.value)
|
var weatherProvider by intPref(default = if (ConfigurationCompat.getLocales(context.resources.configuration)[0].isMetric()) Constants.WeatherProvider.YR.value else Constants.WeatherProvider.WEATHER_GOV.value)
|
||||||
var weatherProviderError by stringPref(default = "")
|
var weatherProviderError by stringPref(default = "")
|
||||||
var weatherProviderLocationError by stringPref(default = "")
|
var weatherProviderLocationError by stringPref(default = "")
|
||||||
var eventAppName by stringPref(key = "PREF_EVENT_APP_NAME", default = "")
|
var eventAppName by stringPref(key = "PREF_EVENT_APP_NAME", default = "")
|
||||||
@ -125,6 +128,7 @@ object Preferences : KotprefModel() {
|
|||||||
var showDailySteps by booleanPref(default = false)
|
var showDailySteps by booleanPref(default = false)
|
||||||
var showGreetings by booleanPref(default = false)
|
var showGreetings by booleanPref(default = false)
|
||||||
var showNotifications by booleanPref(default = false)
|
var showNotifications by booleanPref(default = false)
|
||||||
|
var hideNotificationAfter by intPref(default = Constants.GlanceNotificationTimer.ONE_MINUTE.value)
|
||||||
|
|
||||||
var lastNotificationId by intPref(default = -1)
|
var lastNotificationId by intPref(default = -1)
|
||||||
var lastNotificationTitle by stringPref(default = "")
|
var lastNotificationTitle by stringPref(default = "")
|
||||||
@ -140,6 +144,8 @@ object Preferences : KotprefModel() {
|
|||||||
var musicPlayersFilter by stringPref(default = "")
|
var musicPlayersFilter by stringPref(default = "")
|
||||||
var appNotificationsFilter by stringPref(default = "")
|
var appNotificationsFilter by stringPref(default = "")
|
||||||
|
|
||||||
|
var showEventsAsGlanceProvider by booleanPref(default = false)
|
||||||
|
|
||||||
// Integrations
|
// Integrations
|
||||||
var installedIntegrations by intPref(default = 0)
|
var installedIntegrations by intPref(default = 0)
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import com.chibatching.kotpref.Kotpref
|
|||||||
import com.chibatching.kotpref.blockingBulk
|
import com.chibatching.kotpref.blockingBulk
|
||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.receivers.NotificationListener
|
import com.tommasoberlose.anotherwidget.receivers.NotificationListener
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||||
|
|
||||||
object ActiveNotificationsHelper {
|
object ActiveNotificationsHelper {
|
||||||
fun showLastNotification(): Boolean {
|
fun showLastNotification(): Boolean {
|
||||||
@ -23,6 +24,7 @@ object ActiveNotificationsHelper {
|
|||||||
remove(Preferences::lastNotificationPackage)
|
remove(Preferences::lastNotificationPackage)
|
||||||
remove(Preferences::lastNotificationIcon)
|
remove(Preferences::lastNotificationIcon)
|
||||||
}
|
}
|
||||||
|
MainWidget.updateWidget(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkNotificationAccess(context: Context): Boolean {
|
fun checkNotificationAccess(context: Context): Boolean {
|
||||||
|
@ -80,4 +80,27 @@ object CalendarHelper {
|
|||||||
.filter { (!Preferences.showOnlyBusyEvents || it.availability != CalendarContract.EventsEntity.AVAILABILITY_FREE) }
|
.filter { (!Preferences.showOnlyBusyEvents || it.availability != CalendarContract.EventsEntity.AVAILABILITY_FREE) }
|
||||||
.toList()
|
.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun List<Event>.sortEvents(): List<Event> {
|
||||||
|
return sortedWith { event: Event, event1: Event ->
|
||||||
|
val date = Calendar.getInstance().apply { timeInMillis = event.startDate }
|
||||||
|
val date1 = Calendar.getInstance().apply { timeInMillis = event1.startDate }
|
||||||
|
|
||||||
|
if (date.get(Calendar.DAY_OF_YEAR) == date1.get(Calendar.DAY_OF_YEAR) && date.get(
|
||||||
|
Calendar.YEAR) == date1.get(Calendar.YEAR)
|
||||||
|
) {
|
||||||
|
if (event.allDay && event1.allDay) {
|
||||||
|
event.startDate.compareTo(event1.startDate)
|
||||||
|
} else if (event.allDay) {
|
||||||
|
1
|
||||||
|
} else if (event1.allDay) {
|
||||||
|
-1
|
||||||
|
} else {
|
||||||
|
event.startDate.compareTo(event1.startDate)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
event.startDate.compareTo(event1.startDate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,11 +1,14 @@
|
|||||||
package com.tommasoberlose.anotherwidget.helpers
|
package com.tommasoberlose.anotherwidget.helpers
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.util.Log
|
||||||
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.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.checkGrantedPermission
|
||||||
import com.tommasoberlose.anotherwidget.utils.checkIfFitInstalled
|
import com.tommasoberlose.anotherwidget.utils.checkIfFitInstalled
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
|
|
||||||
@ -16,9 +19,10 @@ object GlanceProviderHelper {
|
|||||||
val providers = Constants.GlanceProviderId.values()
|
val providers = Constants.GlanceProviderId.values()
|
||||||
.filter {
|
.filter {
|
||||||
context.checkIfFitInstalled() || it != Constants.GlanceProviderId.GOOGLE_FIT_STEPS
|
context.checkIfFitInstalled() || it != Constants.GlanceProviderId.GOOGLE_FIT_STEPS
|
||||||
}.toTypedArray()
|
}
|
||||||
|
.toTypedArray()
|
||||||
|
|
||||||
providers.sortWith(Comparator { p1, p2 ->
|
return ArrayList(providers.filter { enabledProviders.contains(it.id) }.sortedWith(Comparator { p1, p2 ->
|
||||||
when {
|
when {
|
||||||
enabledProviders.contains(p1.id) && enabledProviders.contains(p2.id) -> {
|
enabledProviders.contains(p1.id) && enabledProviders.contains(p2.id) -> {
|
||||||
enabledProviders.indexOf(p1.id).compareTo(enabledProviders.indexOf(p2.id))
|
enabledProviders.indexOf(p1.id).compareTo(enabledProviders.indexOf(p2.id))
|
||||||
@ -33,9 +37,7 @@ object GlanceProviderHelper {
|
|||||||
p1.id.compareTo(p2.id)
|
p1.id.compareTo(p2.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}) + providers.filter { !enabledProviders.contains(it.id) })
|
||||||
|
|
||||||
return ArrayList(providers.toList())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getGlanceProviderById(context: Context, providerId: Constants.GlanceProviderId): GlanceProvider? {
|
fun getGlanceProviderById(context: Context, providerId: Constants.GlanceProviderId): GlanceProvider? {
|
||||||
@ -43,49 +45,55 @@ object GlanceProviderHelper {
|
|||||||
Constants.GlanceProviderId.NEXT_CLOCK_ALARM -> {
|
Constants.GlanceProviderId.NEXT_CLOCK_ALARM -> {
|
||||||
GlanceProvider(providerId.id,
|
GlanceProvider(providerId.id,
|
||||||
context.getString(R.string.settings_show_next_alarm_title),
|
context.getString(R.string.settings_show_next_alarm_title),
|
||||||
R.drawable.round_access_alarm
|
R.drawable.round_access_alarm_24
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Constants.GlanceProviderId.PLAYING_SONG -> {
|
Constants.GlanceProviderId.PLAYING_SONG -> {
|
||||||
GlanceProvider(providerId.id,
|
GlanceProvider(providerId.id,
|
||||||
context.getString(R.string.settings_show_music_title),
|
context.getString(R.string.settings_show_music_title),
|
||||||
R.drawable.round_radio
|
R.drawable.round_music_note_24
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Constants.GlanceProviderId.CUSTOM_INFO -> {
|
Constants.GlanceProviderId.CUSTOM_INFO -> {
|
||||||
GlanceProvider(providerId.id,
|
GlanceProvider(providerId.id,
|
||||||
context.getString(R.string.settings_custom_notes_title),
|
context.getString(R.string.settings_custom_notes_title),
|
||||||
R.drawable.round_sticky_note_2
|
R.drawable.round_sticky_note_2_24
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
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_24
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
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_run_circle
|
R.drawable.round_favorite_border_24
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Constants.GlanceProviderId.NOTIFICATIONS -> {
|
Constants.GlanceProviderId.NOTIFICATIONS -> {
|
||||||
GlanceProvider(providerId.id,
|
GlanceProvider(providerId.id,
|
||||||
context.getString(R.string.settings_show_notifications_title),
|
context.getString(R.string.settings_show_notifications_title),
|
||||||
R.drawable.round_notifications
|
R.drawable.round_notifications_24
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Constants.GlanceProviderId.GREETINGS -> {
|
Constants.GlanceProviderId.GREETINGS -> {
|
||||||
GlanceProvider(providerId.id,
|
GlanceProvider(providerId.id,
|
||||||
context.getString(R.string.settings_show_greetings_title),
|
context.getString(R.string.settings_show_greetings_title),
|
||||||
R.drawable.round_history_edu
|
R.drawable.round_history_edu_24
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.EVENTS -> {
|
||||||
|
GlanceProvider(providerId.id,
|
||||||
|
context.getString(R.string.settings_show_events_as_glance_provider_title),
|
||||||
|
R.drawable.round_event_note_24
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun saveGlanceProviderOrder(list: ArrayList<Constants.GlanceProviderId>) {
|
fun saveGlanceProviderOrder(list: List<Constants.GlanceProviderId>) {
|
||||||
Preferences.enabledGlanceProviderOrder = list.joinToString(separator = ",")
|
Preferences.enabledGlanceProviderOrder = list.joinToString(separator = ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,14 +101,17 @@ object GlanceProviderHelper {
|
|||||||
val eventRepository = EventRepository(context)
|
val eventRepository = EventRepository(context)
|
||||||
BatteryHelper.updateBatteryInfo(context)
|
BatteryHelper.updateBatteryInfo(context)
|
||||||
|
|
||||||
val showGlance = Preferences.showGlance && (eventRepository.getEventsCount() == 0 || !Preferences.showEvents)
|
val showGlance = Preferences.showGlance && (eventRepository.getEventsCount() == 0 || !Preferences.showEvents || Preferences.showEventsAsGlanceProvider)
|
||||||
&& (
|
&& (
|
||||||
(Preferences.showNotifications && ActiveNotificationsHelper.showLastNotification()) ||
|
(Preferences.showNotifications && ActiveNotificationsHelper.showLastNotification()) ||
|
||||||
(Preferences.showNextAlarm && AlarmHelper.getNextAlarm(context) != "") ||
|
(Preferences.showNextAlarm && AlarmHelper.getNextAlarm(context) != "") ||
|
||||||
(MediaPlayerHelper.isSomeonePlaying(context)) ||
|
(MediaPlayerHelper.isSomeonePlaying(context)) ||
|
||||||
(Preferences.showBatteryCharging && Preferences.isCharging || Preferences.isBatteryLevelLow) ||
|
(Preferences.showBatteryCharging && Preferences.isCharging || Preferences.isBatteryLevelLow) ||
|
||||||
(Preferences.customNotes.isNotEmpty()) ||
|
(Preferences.customNotes.isNotEmpty()) ||
|
||||||
(Preferences.showDailySteps && Preferences.googleFitSteps > 0)
|
(Preferences.showDailySteps && Preferences.googleFitSteps > 0) ||
|
||||||
|
(Preferences.showGreetings && GreetingsHelper.showGreetings()) ||
|
||||||
|
(Preferences.showEventsAsGlanceProvider && Preferences.showEvents && context.checkGrantedPermission(
|
||||||
|
Manifest.permission.READ_CALENDAR) && eventRepository.getNextEvent() != null)
|
||||||
)
|
)
|
||||||
eventRepository.close()
|
eventRepository.close()
|
||||||
return showGlance
|
return showGlance
|
||||||
|
@ -0,0 +1,110 @@
|
|||||||
|
package com.tommasoberlose.anotherwidget.helpers
|
||||||
|
|
||||||
|
import android.app.AlarmManager
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import com.tommasoberlose.anotherwidget.R
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Actions
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
|
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
|
object GreetingsHelper {
|
||||||
|
private const val MORNING_TIME = 36
|
||||||
|
private const val MORNING_TIME_END = 37
|
||||||
|
private const val EVENING_TIME = 38
|
||||||
|
private const val NIGHT_TIME = 39
|
||||||
|
|
||||||
|
fun toggleGreetings(context: Context) {
|
||||||
|
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
|
||||||
|
val now = Calendar.getInstance().apply {
|
||||||
|
set(Calendar.SECOND, 0)
|
||||||
|
set(Calendar.MILLISECOND, 0)
|
||||||
|
set(Calendar.MINUTE, 0)
|
||||||
|
set(Calendar.HOUR_OF_DAY, 0)
|
||||||
|
}
|
||||||
|
if (Preferences.showGreetings) {
|
||||||
|
setRepeating(
|
||||||
|
AlarmManager.RTC,
|
||||||
|
now.apply {
|
||||||
|
set(Calendar.HOUR_OF_DAY, 5)
|
||||||
|
}.timeInMillis,
|
||||||
|
1000 * 60 * 60 * 24,
|
||||||
|
PendingIntent.getBroadcast(context,
|
||||||
|
MORNING_TIME,
|
||||||
|
Intent(context, UpdatesReceiver::class.java).apply {
|
||||||
|
action = Actions.ACTION_UPDATE_GREETINGS
|
||||||
|
},
|
||||||
|
0)
|
||||||
|
)
|
||||||
|
|
||||||
|
setRepeating(
|
||||||
|
AlarmManager.RTC,
|
||||||
|
now.apply {
|
||||||
|
set(Calendar.HOUR_OF_DAY, 9)
|
||||||
|
}.timeInMillis,
|
||||||
|
1000 * 60 * 60 * 24,
|
||||||
|
PendingIntent.getBroadcast(context,
|
||||||
|
MORNING_TIME_END,
|
||||||
|
Intent(context, UpdatesReceiver::class.java).apply {
|
||||||
|
action = Actions.ACTION_UPDATE_GREETINGS
|
||||||
|
},
|
||||||
|
0)
|
||||||
|
)
|
||||||
|
|
||||||
|
setRepeating(
|
||||||
|
AlarmManager.RTC,
|
||||||
|
now.apply {
|
||||||
|
set(Calendar.HOUR_OF_DAY, 19)
|
||||||
|
}.timeInMillis,
|
||||||
|
1000 * 60 * 60 * 24,
|
||||||
|
PendingIntent.getBroadcast(context,
|
||||||
|
EVENING_TIME,
|
||||||
|
Intent(context, UpdatesReceiver::class.java).apply {
|
||||||
|
action = Actions.ACTION_UPDATE_GREETINGS
|
||||||
|
},
|
||||||
|
0)
|
||||||
|
)
|
||||||
|
|
||||||
|
setRepeating(
|
||||||
|
AlarmManager.RTC,
|
||||||
|
now.apply {
|
||||||
|
set(Calendar.HOUR_OF_DAY, 22)
|
||||||
|
}.timeInMillis,
|
||||||
|
1000 * 60 * 60 * 24,
|
||||||
|
PendingIntent.getBroadcast(context,
|
||||||
|
NIGHT_TIME,
|
||||||
|
Intent(context, UpdatesReceiver::class.java).apply {
|
||||||
|
action = Actions.ACTION_UPDATE_GREETINGS
|
||||||
|
},
|
||||||
|
0)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
listOf(MORNING_TIME, MORNING_TIME_END, EVENING_TIME, NIGHT_TIME).forEach {
|
||||||
|
cancel(PendingIntent.getBroadcast(context, it, Intent(context,
|
||||||
|
UpdatesReceiver::class.java).apply {
|
||||||
|
action = Actions.ACTION_UPDATE_GREETINGS
|
||||||
|
}, 0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showGreetings(): Boolean {
|
||||||
|
val hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY)
|
||||||
|
return hour < 9 || hour >= 19
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getRandomString(context: Context): String {
|
||||||
|
val hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY)
|
||||||
|
val array = when {
|
||||||
|
hour in 5..8 -> context.resources.getStringArray(R.array.morning_greetings)
|
||||||
|
hour in 19..21 -> context.resources.getStringArray(R.array.evening_greetings)
|
||||||
|
hour >= 22 && hour < 5 -> context.resources.getStringArray(R.array.night_greetings)
|
||||||
|
else -> emptyArray()
|
||||||
|
}
|
||||||
|
return if (array.isNotEmpty()) array[Random().nextInt(array.size)] else ""
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
package com.tommasoberlose.anotherwidget.helpers
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.*
|
||||||
|
import android.renderscript.*
|
||||||
|
import android.util.TypedValue
|
||||||
|
import android.widget.ImageView
|
||||||
|
import androidx.core.graphics.drawable.toBitmap
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
|
||||||
|
import java.util.prefs.Preferences
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
|
object ImageHelper {
|
||||||
|
fun ImageView.applyShadow(originalView: ImageView, factor: Float = 1f) {
|
||||||
|
clearColorFilter()
|
||||||
|
val cElevation = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, when (if (context.isDarkTheme()) com.tommasoberlose.anotherwidget.global.Preferences.textShadowDark else com.tommasoberlose.anotherwidget.global.Preferences.textShadow) {
|
||||||
|
0 -> 0f * factor
|
||||||
|
1 -> 8f * factor
|
||||||
|
2 -> 16f * factor
|
||||||
|
else -> 0f * factor
|
||||||
|
}, resources.displayMetrics)
|
||||||
|
|
||||||
|
if (originalView.drawable != null) {
|
||||||
|
val btm = originalView.drawable.toBitmap().copy(Bitmap.Config.ARGB_8888, true)
|
||||||
|
val comb = Bitmap.createBitmap(btm)
|
||||||
|
val shadowBitmap = generateShadowBitmap(context, cElevation, btm, factor)
|
||||||
|
|
||||||
|
shadowBitmap?.let {
|
||||||
|
val canvas = Canvas(comb)
|
||||||
|
canvas.drawColor(Color.TRANSPARENT)
|
||||||
|
canvas.save()
|
||||||
|
val rect = Rect()
|
||||||
|
val bounds = originalView.drawable.copyBounds()
|
||||||
|
canvas.getClipBounds(rect)
|
||||||
|
rect.inset(-2 * getBlurRadius(context, cElevation).toInt(), -2 * getBlurRadius(context, cElevation).toInt())
|
||||||
|
canvas.save()
|
||||||
|
canvas.clipRect(rect)
|
||||||
|
canvas.drawBitmap(shadowBitmap, 0f, 2f, null)
|
||||||
|
canvas.restore()
|
||||||
|
setImageBitmap(comb)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateShadowBitmap(context: Context, cElevation: Float, bitmap: Bitmap?, factor: Float): Bitmap? {
|
||||||
|
val rs: RenderScript = RenderScript.create(context)
|
||||||
|
val element = Element.U8_4(rs)
|
||||||
|
val blurScript: ScriptIntrinsicBlur = ScriptIntrinsicBlur.create(rs, element)
|
||||||
|
val colorMatrixScript: ScriptIntrinsicColorMatrix = ScriptIntrinsicColorMatrix.create(rs)
|
||||||
|
val allocationIn = Allocation.createFromBitmap(rs, bitmap)
|
||||||
|
val allocationOut = Allocation.createTyped(rs, allocationIn.type)
|
||||||
|
|
||||||
|
val matrix = Matrix4f(floatArrayOf(
|
||||||
|
0f, 0f, 0f, 0f,
|
||||||
|
0f, 0f, 0f, 0f,
|
||||||
|
0f, 0f, 0f, 0f,
|
||||||
|
0f, 0f, 0f, when (if (context.isDarkTheme()) com.tommasoberlose.anotherwidget.global.Preferences.textShadowDark else com.tommasoberlose.anotherwidget.global.Preferences.textShadow) {
|
||||||
|
0 -> 0f * factor
|
||||||
|
1 -> 0.8f * factor
|
||||||
|
2 -> 1f * factor
|
||||||
|
else -> 0f
|
||||||
|
}))
|
||||||
|
|
||||||
|
colorMatrixScript.setColorMatrix(matrix)
|
||||||
|
colorMatrixScript.forEach(allocationIn, allocationOut)
|
||||||
|
|
||||||
|
blurScript.setRadius(getBlurRadius(context, cElevation))
|
||||||
|
|
||||||
|
blurScript.setInput(allocationOut)
|
||||||
|
blurScript.forEach(allocationIn)
|
||||||
|
|
||||||
|
allocationIn.copyTo(bitmap)
|
||||||
|
|
||||||
|
allocationIn.destroy()
|
||||||
|
allocationOut.destroy()
|
||||||
|
|
||||||
|
return bitmap
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getBlurRadius(context: Context, customElevation: Float): Float {
|
||||||
|
val maxElevation = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24f, context.resources.displayMetrics)
|
||||||
|
return min(25f * (customElevation / maxElevation), 25f)
|
||||||
|
}
|
||||||
|
}
|
@ -66,7 +66,6 @@ object IntentHelper {
|
|||||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
context.toast(context.getString(R.string.error_opening_app))
|
|
||||||
Intent()
|
Intent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,7 +95,6 @@ object IntentHelper {
|
|||||||
data = calendarUri
|
data = calendarUri
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
context.toast(context.getString(R.string.error_opening_app))
|
|
||||||
Intent()
|
Intent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -181,7 +179,6 @@ object IntentHelper {
|
|||||||
addCategory(Intent.CATEGORY_LAUNCHER)
|
addCategory(Intent.CATEGORY_LAUNCHER)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
context.toast(context.getString(R.string.error_opening_app))
|
|
||||||
Intent()
|
Intent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,7 +201,6 @@ object IntentHelper {
|
|||||||
addCategory(Intent.CATEGORY_LAUNCHER)
|
addCategory(Intent.CATEGORY_LAUNCHER)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
context.toast(context.getString(R.string.error_opening_app))
|
|
||||||
Intent()
|
Intent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -218,7 +214,6 @@ object IntentHelper {
|
|||||||
addCategory(Intent.CATEGORY_LAUNCHER)
|
addCategory(Intent.CATEGORY_LAUNCHER)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
context.toast(context.getString(R.string.error_opening_app))
|
|
||||||
Intent()
|
Intent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -230,7 +225,6 @@ object IntentHelper {
|
|||||||
addCategory(Intent.CATEGORY_LAUNCHER)
|
addCategory(Intent.CATEGORY_LAUNCHER)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
context.toast(context.getString(R.string.error_opening_app))
|
|
||||||
Intent()
|
Intent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import com.tommasoberlose.anotherwidget.R
|
|||||||
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.network.WeatherNetworkApi
|
import com.tommasoberlose.anotherwidget.network.WeatherNetworkApi
|
||||||
|
import com.tommasoberlose.anotherwidget.services.LocationService
|
||||||
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
|
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
|
||||||
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||||
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
||||||
@ -31,26 +32,8 @@ object WeatherHelper {
|
|||||||
val networkApi = WeatherNetworkApi(context)
|
val networkApi = WeatherNetworkApi(context)
|
||||||
if (Preferences.customLocationAdd != "") {
|
if (Preferences.customLocationAdd != "") {
|
||||||
networkApi.updateWeather()
|
networkApi.updateWeather()
|
||||||
} else if (context.checkGrantedPermission(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION)) {
|
} else if (context.checkGrantedPermission(Manifest.permission.ACCESS_FINE_LOCATION)) {
|
||||||
LocationServices.getFusedLocationProviderClient(context).lastLocation.addOnCompleteListener { task ->
|
LocationService.requestNewLocation(context)
|
||||||
if (task.isSuccessful) {
|
|
||||||
val location = task.result
|
|
||||||
if (location != null) {
|
|
||||||
Preferences.customLocationLat = location.latitude.toString()
|
|
||||||
Preferences.customLocationLon = location.longitude.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
|
||||||
networkApi.updateWeather()
|
|
||||||
}
|
|
||||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
|
||||||
} else {
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
|
||||||
networkApi.updateWeather()
|
|
||||||
}
|
|
||||||
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,11 +8,14 @@ import android.os.Build
|
|||||||
import android.service.notification.NotificationListenerService
|
import android.service.notification.NotificationListenerService
|
||||||
import android.service.notification.StatusBarNotification
|
import android.service.notification.StatusBarNotification
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.widget.Toast
|
||||||
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.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.helpers.ActiveNotificationsHelper
|
import com.tommasoberlose.anotherwidget.helpers.ActiveNotificationsHelper
|
||||||
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
|
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
|
||||||
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||||
|
import java.lang.Exception
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
@ -31,16 +34,19 @@ class NotificationListener : NotificationListenerService() {
|
|||||||
val isGroupHeader = sbn.notification.flags and Notification.FLAG_GROUP_SUMMARY != 0
|
val isGroupHeader = sbn.notification.flags and Notification.FLAG_GROUP_SUMMARY != 0
|
||||||
val isOngoing = sbn.notification.flags and Notification.FLAG_ONGOING_EVENT != 0
|
val isOngoing = sbn.notification.flags and Notification.FLAG_ONGOING_EVENT != 0
|
||||||
|
|
||||||
if (bundle.containsKey(Notification.EXTRA_TITLE) && !isGroupHeader && !isOngoing && ActiveNotificationsHelper.isAppAccepted(sbn.packageName)) {
|
if (bundle.containsKey(Notification.EXTRA_TITLE) && !isGroupHeader && !isOngoing && ActiveNotificationsHelper.isAppAccepted(sbn.packageName) && !sbn.packageName.contains("com.android.systemui")) {
|
||||||
Preferences.lastNotificationId = sbn.id
|
Preferences.lastNotificationId = sbn.id
|
||||||
Preferences.lastNotificationTitle = bundle.getString(Notification.EXTRA_TITLE) ?: ""
|
Preferences.lastNotificationTitle = bundle.getString(Notification.EXTRA_TITLE) ?: ""
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
try {
|
||||||
Preferences.lastNotificationIcon = sbn.notification.smallIcon.resId
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
Preferences.lastNotificationPackage = sbn.notification.smallIcon.resPackage
|
Preferences.lastNotificationIcon = sbn.notification.smallIcon.resId
|
||||||
} else {
|
} else {
|
||||||
Preferences.lastNotificationIcon = sbn.notification.icon
|
Preferences.lastNotificationIcon = sbn.notification.icon
|
||||||
Preferences.lastNotificationPackage = sbn.packageName
|
}
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
Preferences.lastNotificationIcon = 0
|
||||||
}
|
}
|
||||||
|
Preferences.lastNotificationPackage = sbn.packageName
|
||||||
MainWidget.updateWidget(this)
|
MainWidget.updateWidget(this)
|
||||||
setTimeout(this)
|
setTimeout(this)
|
||||||
}
|
}
|
||||||
@ -69,16 +75,26 @@ class NotificationListener : NotificationListenerService() {
|
|||||||
action = Actions.ACTION_CLEAR_NOTIFICATION
|
action = Actions.ACTION_CLEAR_NOTIFICATION
|
||||||
}
|
}
|
||||||
cancel(PendingIntent.getBroadcast(context, 28943, intent, 0))
|
cancel(PendingIntent.getBroadcast(context, 28943, intent, 0))
|
||||||
setExact(
|
val timeoutPref = Constants.GlanceNotificationTimer.fromInt(Preferences.hideNotificationAfter)
|
||||||
AlarmManager.RTC,
|
if (timeoutPref != Constants.GlanceNotificationTimer.WHEN_DISMISSED) {
|
||||||
Calendar.getInstance().timeInMillis + 30 * 1000,
|
setExact(
|
||||||
PendingIntent.getBroadcast(
|
AlarmManager.RTC,
|
||||||
context,
|
Calendar.getInstance().timeInMillis + when (timeoutPref) {
|
||||||
5,
|
Constants.GlanceNotificationTimer.HALF_MINUTE -> 30 * 1000
|
||||||
intent,
|
Constants.GlanceNotificationTimer.ONE_MINUTE -> 60 * 1000
|
||||||
0
|
Constants.GlanceNotificationTimer.FIVE_MINUTES -> 5 * 60 * 1000
|
||||||
|
Constants.GlanceNotificationTimer.TEN_MINUTES -> 10 * 60 * 1000
|
||||||
|
Constants.GlanceNotificationTimer.FIFTEEN_MINUTES -> 15 * 60 * 1000
|
||||||
|
else -> 0
|
||||||
|
},
|
||||||
|
PendingIntent.getBroadcast(
|
||||||
|
context,
|
||||||
|
5,
|
||||||
|
intent,
|
||||||
|
0
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -33,9 +33,9 @@ class UpdatesReceiver : BroadcastReceiver() {
|
|||||||
Intent.ACTION_LOCALE_CHANGED,
|
Intent.ACTION_LOCALE_CHANGED,
|
||||||
Intent.ACTION_DATE_CHANGED,
|
Intent.ACTION_DATE_CHANGED,
|
||||||
Actions.ACTION_CALENDAR_UPDATE -> {
|
Actions.ACTION_CALENDAR_UPDATE -> {
|
||||||
CalendarHelper.updateEventList(context)
|
|
||||||
ActiveNotificationsHelper.clearLastNotification(context)
|
ActiveNotificationsHelper.clearLastNotification(context)
|
||||||
MediaPlayerHelper.updatePlayingMediaInfo(context)
|
MediaPlayerHelper.updatePlayingMediaInfo(context)
|
||||||
|
CalendarHelper.updateEventList(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
"com.sec.android.widgetapp.APPWIDGET_RESIZE",
|
"com.sec.android.widgetapp.APPWIDGET_RESIZE",
|
||||||
@ -52,6 +52,9 @@ class UpdatesReceiver : BroadcastReceiver() {
|
|||||||
ActiveNotificationsHelper.clearLastNotification(context)
|
ActiveNotificationsHelper.clearLastNotification(context)
|
||||||
MainWidget.updateWidget(context)
|
MainWidget.updateWidget(context)
|
||||||
}
|
}
|
||||||
|
Actions.ACTION_UPDATE_GREETINGS -> {
|
||||||
|
MainWidget.updateWidget(context)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,129 @@
|
|||||||
|
package com.tommasoberlose.anotherwidget.services
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.app.*
|
||||||
|
import android.app.job.JobScheduler
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.location.Address
|
||||||
|
import android.location.Geocoder
|
||||||
|
import android.os.IBinder
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.core.app.*
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import com.google.android.gms.location.LocationServices
|
||||||
|
import com.tommasoberlose.anotherwidget.R
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
|
import com.tommasoberlose.anotherwidget.network.WeatherNetworkApi
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import java.lang.Exception
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
|
class LocationService : Service() {
|
||||||
|
|
||||||
|
private val jobs: ArrayList<Job> = ArrayList()
|
||||||
|
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
startForeground(LOCATION_ACCESS_NOTIFICATION_ID, getLocationAccessNotification())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
|
if (ActivityCompat.checkSelfPermission(
|
||||||
|
this,
|
||||||
|
Manifest.permission.ACCESS_FINE_LOCATION
|
||||||
|
) == PackageManager.PERMISSION_GRANTED
|
||||||
|
) {
|
||||||
|
|
||||||
|
jobs += GlobalScope.launch(Dispatchers.IO) {
|
||||||
|
LocationServices.getFusedLocationProviderClient(this@LocationService).lastLocation.addOnCompleteListener { task ->
|
||||||
|
val networkApi = WeatherNetworkApi(this@LocationService)
|
||||||
|
if (task.isSuccessful) {
|
||||||
|
val location = task.result
|
||||||
|
if (location != null) {
|
||||||
|
Preferences.customLocationLat = location.latitude.toString()
|
||||||
|
Preferences.customLocationLon = location.longitude.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
networkApi.updateWeather()
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
stopSelf()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||||
|
} else {
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
networkApi.updateWeather()
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
stopSelf()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stopSelf()
|
||||||
|
}
|
||||||
|
return START_STICKY
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
jobs.forEach {
|
||||||
|
it.cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val LOCATION_ACCESS_NOTIFICATION_ID = 28465
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun requestNewLocation(context: Context) {
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||||
|
context.startForegroundService(Intent(context, LocationService::class.java))
|
||||||
|
} else {
|
||||||
|
context.startService(Intent(context, LocationService::class.java))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBind(intent: Intent?): IBinder? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getLocationAccessNotification(): Notification {
|
||||||
|
with(NotificationManagerCompat.from(this)) {
|
||||||
|
// Create channel
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||||
|
createNotificationChannel(
|
||||||
|
NotificationChannel(
|
||||||
|
getString(R.string.location_access_notification_channel_id),
|
||||||
|
getString(R.string.location_access_notification_channel_name),
|
||||||
|
NotificationManager.IMPORTANCE_LOW
|
||||||
|
).apply {
|
||||||
|
description = getString(R.string.location_access_notification_channel_description)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val builder = NotificationCompat.Builder(this@LocationService, getString(R.string.location_access_notification_channel_id))
|
||||||
|
.setSmallIcon(R.drawable.ic_stat_notification)
|
||||||
|
.setContentTitle(getString(R.string.location_access_notification_title))
|
||||||
|
.setStyle(NotificationCompat.BigTextStyle().bigText(getString(R.string.location_access_notification_subtitle)))
|
||||||
|
.setOngoing(true)
|
||||||
|
.setColor(ContextCompat.getColor(this@LocationService, R.color.colorAccent))
|
||||||
|
|
||||||
|
// Main intent that open the activity
|
||||||
|
builder.setContentIntent(PendingIntent.getActivity(this@LocationService, 0, Intent(this@LocationService, MainActivity::class.java), PendingIntent.FLAG_UPDATE_CURRENT))
|
||||||
|
|
||||||
|
return builder.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,7 @@ import com.tommasoberlose.anotherwidget.db.EventRepository
|
|||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper
|
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper
|
||||||
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper.applyFilters
|
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper.applyFilters
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper.sortEvents
|
||||||
import com.tommasoberlose.anotherwidget.models.Event
|
import com.tommasoberlose.anotherwidget.models.Event
|
||||||
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
|
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
|
||||||
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
|
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
|
||||||
@ -44,8 +45,17 @@ class UpdateCalendarJob : JobIntentService() {
|
|||||||
set(Calendar.HOUR_OF_DAY, 0)
|
set(Calendar.HOUR_OF_DAY, 0)
|
||||||
}
|
}
|
||||||
val limit = Calendar.getInstance().apply {
|
val limit = Calendar.getInstance().apply {
|
||||||
timeInMillis = begin.timeInMillis
|
when (Preferences.showUntil) {
|
||||||
add(Calendar.DAY_OF_YEAR, 2)
|
0 -> add(Calendar.HOUR, 3)
|
||||||
|
1 -> add(Calendar.HOUR, 6)
|
||||||
|
2 -> add(Calendar.HOUR, 12)
|
||||||
|
3 -> add(Calendar.DAY_OF_MONTH, 1)
|
||||||
|
4 -> add(Calendar.DAY_OF_MONTH, 3)
|
||||||
|
5 -> add(Calendar.DAY_OF_MONTH, 7)
|
||||||
|
6 -> add(Calendar.MINUTE, 30)
|
||||||
|
7 -> add(Calendar.HOUR, 1)
|
||||||
|
else -> add(Calendar.HOUR, 6)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!checkGrantedPermission(
|
if (!checkGrantedPermission(
|
||||||
@ -75,6 +85,24 @@ class UpdateCalendarJob : JobIntentService() {
|
|||||||
instance.end =
|
instance.end =
|
||||||
end.timeInMillis - end.timeZone.getOffset(end.timeInMillis)
|
end.timeInMillis - end.timeZone.getOffset(end.timeInMillis)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check all day events
|
||||||
|
val startDate = Calendar.getInstance()
|
||||||
|
startDate.timeInMillis = instance.begin
|
||||||
|
val endDate = Calendar.getInstance()
|
||||||
|
endDate.timeInMillis = instance.end
|
||||||
|
|
||||||
|
val isAllDay = e.allDay || (
|
||||||
|
startDate.get(Calendar.MILLISECOND) == 0
|
||||||
|
&& startDate.get(Calendar.SECOND) == 0
|
||||||
|
&& startDate.get(Calendar.MINUTE) == 0
|
||||||
|
&& startDate.get(Calendar.HOUR_OF_DAY) == 0
|
||||||
|
&& endDate.get(Calendar.MILLISECOND) == 0
|
||||||
|
&& endDate.get(Calendar.SECOND) == 0
|
||||||
|
&& endDate.get(Calendar.MINUTE) == 0
|
||||||
|
&& endDate.get(Calendar.HOUR_OF_DAY) == 0
|
||||||
|
)
|
||||||
|
|
||||||
eventList.add(
|
eventList.add(
|
||||||
Event(
|
Event(
|
||||||
id = instance.id,
|
id = instance.id,
|
||||||
@ -83,7 +111,7 @@ class UpdateCalendarJob : JobIntentService() {
|
|||||||
startDate = instance.begin,
|
startDate = instance.begin,
|
||||||
endDate = instance.end,
|
endDate = instance.end,
|
||||||
calendarID = e.calendarId.toInt(),
|
calendarID = e.calendarId.toInt(),
|
||||||
allDay = e.allDay,
|
allDay = isAllDay,
|
||||||
address = e.eventLocation ?: "",
|
address = e.eventLocation ?: "",
|
||||||
selfAttendeeStatus = e.selfAttendeeStatus.toInt(),
|
selfAttendeeStatus = e.selfAttendeeStatus.toInt(),
|
||||||
availability = e.availability
|
availability = e.availability
|
||||||
@ -95,34 +123,16 @@ class UpdateCalendarJob : JobIntentService() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val filteredEventList = eventList
|
val sortedEvents = eventList.sortEvents()
|
||||||
|
val filteredEventList = sortedEvents
|
||||||
.applyFilters()
|
.applyFilters()
|
||||||
|
|
||||||
if (filteredEventList.isEmpty()) {
|
if (filteredEventList.isEmpty()) {
|
||||||
eventRepository.resetNextEventData()
|
eventRepository.resetNextEventData()
|
||||||
eventRepository.clearEvents()
|
eventRepository.clearEvents()
|
||||||
} else {
|
} else {
|
||||||
eventList.sortWith(Comparator { event: Event, event1: Event ->
|
|
||||||
val date = Calendar.getInstance().apply { timeInMillis = event.startDate }
|
|
||||||
val date1 = Calendar.getInstance().apply { timeInMillis = event1.startDate }
|
|
||||||
|
|
||||||
if (date.get(Calendar.DAY_OF_YEAR) == date1.get(Calendar.DAY_OF_YEAR) && date.get(Calendar.YEAR) == date1.get(Calendar.YEAR)) {
|
|
||||||
if (event.allDay && event1.allDay) {
|
|
||||||
event.startDate.compareTo(event1.startDate)
|
|
||||||
} else if (event.allDay) {
|
|
||||||
1
|
|
||||||
} else if (event1.allDay) {
|
|
||||||
-1
|
|
||||||
} else {
|
|
||||||
event.startDate.compareTo(event1.startDate)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
event.startDate.compareTo(event1.startDate)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
eventRepository.saveEvents(
|
eventRepository.saveEvents(
|
||||||
eventList
|
sortedEvents
|
||||||
)
|
)
|
||||||
eventRepository.saveNextEventData(filteredEventList.first())
|
eventRepository.saveNextEventData(filteredEventList.first())
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import kotlinx.android.synthetic.main.activity_choose_application.search
|
|||||||
import kotlinx.android.synthetic.main.activity_music_players_filter.*
|
import kotlinx.android.synthetic.main.activity_music_players_filter.*
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import net.idik.lib.slimadapter.SlimAdapter
|
import net.idik.lib.slimadapter.SlimAdapter
|
||||||
|
import net.idik.lib.slimadapter.SlimAdapterEx
|
||||||
|
|
||||||
|
|
||||||
class ChooseApplicationActivity : AppCompatActivity() {
|
class ChooseApplicationActivity : AppCompatActivity() {
|
||||||
@ -47,12 +48,12 @@ class ChooseApplicationActivity : AppCompatActivity() {
|
|||||||
val mLayoutManager = LinearLayoutManager(this)
|
val mLayoutManager = LinearLayoutManager(this)
|
||||||
list_view.layoutManager = mLayoutManager
|
list_view.layoutManager = mLayoutManager
|
||||||
|
|
||||||
adapter = SlimAdapter.create()
|
adapter = SlimAdapterEx.create()
|
||||||
adapter
|
adapter
|
||||||
.register<String>(R.layout.application_info_layout) { _, injector ->
|
.register<String>(R.layout.application_info_layout) { _, injector ->
|
||||||
injector
|
injector
|
||||||
.text(R.id.text, getString(R.string.default_name))
|
.text(R.id.text, getString(R.string.default_name))
|
||||||
.image(R.id.icon, R.drawable.round_add_to_home_screen)
|
.image(R.id.icon, R.drawable.round_add_to_home_screen_24)
|
||||||
.with<ImageView>(R.id.icon) {
|
.with<ImageView>(R.id.icon) {
|
||||||
it.scaleX = 0.8f
|
it.scaleX = 0.8f
|
||||||
it.scaleY = 0.8f
|
it.scaleY = 0.8f
|
||||||
|
@ -90,7 +90,7 @@ class CustomDateActivity : AppCompatActivity() {
|
|||||||
ERROR_STRING
|
ERROR_STRING
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
"__"
|
ERROR_STRING
|
||||||
}
|
}
|
||||||
|
|
||||||
if (viewModel.isDateCapitalize.value == true) {
|
if (viewModel.isDateCapitalize.value == true) {
|
||||||
@ -102,7 +102,6 @@ class CustomDateActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
action_save.isVisible = text != ERROR_STRING
|
|
||||||
loader.visibility = View.INVISIBLE
|
loader.visibility = View.INVISIBLE
|
||||||
date_format_value.text = text
|
date_format_value.text = text
|
||||||
}
|
}
|
||||||
@ -143,15 +142,6 @@ class CustomDateActivity : AppCompatActivity() {
|
|||||||
onBackPressed()
|
onBackPressed()
|
||||||
}
|
}
|
||||||
|
|
||||||
action_save.setOnClickListener {
|
|
||||||
Preferences.blockingBulk {
|
|
||||||
dateFormat = viewModel.dateInput.value ?: ""
|
|
||||||
isDateCapitalize = viewModel.isDateCapitalize.value ?: true
|
|
||||||
isDateUppercase = viewModel.isDateUppercase.value ?: false
|
|
||||||
}
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
action_capitalize.setOnClickListener {
|
action_capitalize.setOnClickListener {
|
||||||
when {
|
when {
|
||||||
viewModel.isDateUppercase.value == true -> {
|
viewModel.isDateUppercase.value == true -> {
|
||||||
@ -179,6 +169,15 @@ class CustomDateActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onBackPressed() {
|
||||||
|
Preferences.blockingBulk {
|
||||||
|
dateFormat = viewModel.dateInput.value ?: ""
|
||||||
|
isDateCapitalize = viewModel.isDateCapitalize.value ?: true
|
||||||
|
isDateUppercase = viewModel.isDateUppercase.value ?: false
|
||||||
|
}
|
||||||
|
super.onBackPressed()
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val ERROR_STRING = "--"
|
const val ERROR_STRING = "--"
|
||||||
val DATE: Calendar = Calendar.getInstance().apply {
|
val DATE: Calendar = Calendar.getInstance().apply {
|
||||||
|
@ -69,11 +69,7 @@ class CustomLocationActivity : AppCompatActivity() {
|
|||||||
injector
|
injector
|
||||||
.text(R.id.text, getString(R.string.custom_location_gps))
|
.text(R.id.text, getString(R.string.custom_location_gps))
|
||||||
.clicked(R.id.text) {
|
.clicked(R.id.text) {
|
||||||
MaterialBottomSheetDialog(this, message = getString(R.string.background_location_warning))
|
requirePermission()
|
||||||
.setPositiveButton(getString(android.R.string.ok)) {
|
|
||||||
requirePermission()
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.register<Address>(R.layout.custom_location_item) { item, injector ->
|
.register<Address>(R.layout.custom_location_item) { item, injector ->
|
||||||
@ -140,7 +136,7 @@ class CustomLocationActivity : AppCompatActivity() {
|
|||||||
private fun requirePermission() {
|
private fun requirePermission() {
|
||||||
Dexter.withContext(this)
|
Dexter.withContext(this)
|
||||||
.withPermissions(
|
.withPermissions(
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION
|
Manifest.permission.ACCESS_FINE_LOCATION
|
||||||
).withListener(object: MultiplePermissionsListener {
|
).withListener(object: MultiplePermissionsListener {
|
||||||
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
|
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
|
||||||
report?.let {
|
report?.let {
|
||||||
|
@ -66,6 +66,10 @@ class WeatherProviderActivity : AppCompatActivity() {
|
|||||||
injector
|
injector
|
||||||
.text(R.id.text, WeatherHelper.getProviderName(this, provider))
|
.text(R.id.text, WeatherHelper.getProviderName(this, provider))
|
||||||
.clicked(R.id.item) {
|
.clicked(R.id.item) {
|
||||||
|
if (Preferences.weatherProvider != provider.value) {
|
||||||
|
Preferences.weatherProviderError = "-"
|
||||||
|
Preferences.weatherProviderLocationError = ""
|
||||||
|
}
|
||||||
val oldValue = Preferences.weatherProvider
|
val oldValue = Preferences.weatherProvider
|
||||||
Preferences.weatherProvider = provider.value
|
Preferences.weatherProvider = provider.value
|
||||||
updateListItem(oldValue)
|
updateListItem(oldValue)
|
||||||
@ -77,6 +81,10 @@ class WeatherProviderActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.clicked(R.id.radioButton) {
|
.clicked(R.id.radioButton) {
|
||||||
|
if (Preferences.weatherProvider != provider.value) {
|
||||||
|
Preferences.weatherProviderError = "-"
|
||||||
|
Preferences.weatherProviderLocationError = ""
|
||||||
|
}
|
||||||
val oldValue = Preferences.weatherProvider
|
val oldValue = Preferences.weatherProvider
|
||||||
Preferences.weatherProvider = provider.value
|
Preferences.weatherProvider = provider.value
|
||||||
updateListItem(oldValue)
|
updateListItem(oldValue)
|
||||||
@ -121,7 +129,7 @@ class WeatherProviderActivity : AppCompatActivity() {
|
|||||||
it.isVisible = false
|
it.isVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.image(R.id.action_configure, ContextCompat.getDrawable(this, if (WeatherHelper.isKeyRequired(provider)) R.drawable.round_settings else R.drawable.outline_info_white))
|
.image(R.id.action_configure, ContextCompat.getDrawable(this, if (WeatherHelper.isKeyRequired(provider)) R.drawable.round_settings_24 else R.drawable.outline_info_24))
|
||||||
}.attachTo(list_view)
|
}.attachTo(list_view)
|
||||||
|
|
||||||
adapter.updateData(
|
adapter.updateData(
|
||||||
|
@ -15,7 +15,6 @@ 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.ImageView
|
||||||
import androidx.core.app.NotificationManagerCompat
|
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.databinding.DataBindingUtil
|
import androidx.databinding.DataBindingUtil
|
||||||
@ -51,7 +50,6 @@ import kotlinx.android.synthetic.main.fragment_glance_settings.*
|
|||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import net.idik.lib.slimadapter.SlimAdapter
|
import net.idik.lib.slimadapter.SlimAdapter
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
|
|
||||||
class GlanceTabFragment : Fragment() {
|
class GlanceTabFragment : Fragment() {
|
||||||
@ -63,6 +61,7 @@ class GlanceTabFragment : Fragment() {
|
|||||||
private var dialog: GlanceSettingsDialog? = null
|
private var dialog: GlanceSettingsDialog? = null
|
||||||
private lateinit var adapter: SlimAdapter
|
private lateinit var adapter: SlimAdapter
|
||||||
private lateinit var viewModel: MainViewModel
|
private lateinit var viewModel: MainViewModel
|
||||||
|
private lateinit var list: ArrayList<Constants.GlanceProviderId>
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@ -84,6 +83,8 @@ class GlanceTabFragment : Fragment() {
|
|||||||
binding.lifecycleOwner = this
|
binding.lifecycleOwner = this
|
||||||
binding.viewModel = viewModel
|
binding.viewModel = viewModel
|
||||||
|
|
||||||
|
list = GlanceProviderHelper.getGlanceProviders(requireContext())
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +108,9 @@ class GlanceTabFragment : Fragment() {
|
|||||||
.clicked(R.id.item) {
|
.clicked(R.id.item) {
|
||||||
if (Preferences.showGlance) {
|
if (Preferences.showGlance) {
|
||||||
if (provider == Constants.GlanceProviderId.CUSTOM_INFO) {
|
if (provider == Constants.GlanceProviderId.CUSTOM_INFO) {
|
||||||
CustomNotesDialog(requireContext()).show()
|
CustomNotesDialog(requireContext()){
|
||||||
|
adapter.notifyItemRangeChanged(0, adapter.data.size)
|
||||||
|
}.show()
|
||||||
} else {
|
} else {
|
||||||
dialog = GlanceSettingsDialog(requireActivity(), provider) {
|
dialog = GlanceSettingsDialog(requireActivity(), provider) {
|
||||||
adapter.notifyItemRangeChanged(0, adapter.data.size)
|
adapter.notifyItemRangeChanged(0, adapter.data.size)
|
||||||
@ -119,6 +122,7 @@ class GlanceTabFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var isVisible = false
|
||||||
when (provider) {
|
when (provider) {
|
||||||
Constants.GlanceProviderId.PLAYING_SONG -> {
|
Constants.GlanceProviderId.PLAYING_SONG -> {
|
||||||
when {
|
when {
|
||||||
@ -129,16 +133,19 @@ class GlanceTabFragment : Fragment() {
|
|||||||
injector.text(R.id.label,
|
injector.text(R.id.label,
|
||||||
if (Preferences.showMusic) getString(R.string.settings_visible) else getString(
|
if (Preferences.showMusic) getString(R.string.settings_visible) else getString(
|
||||||
R.string.settings_not_visible))
|
R.string.settings_not_visible))
|
||||||
|
isVisible = Preferences.showMusic
|
||||||
}
|
}
|
||||||
Preferences.showMusic -> {
|
Preferences.showMusic -> {
|
||||||
injector.visibility(R.id.error_icon, View.VISIBLE)
|
injector.visibility(R.id.error_icon, View.VISIBLE)
|
||||||
injector.visibility(R.id.info_icon, View.GONE)
|
injector.visibility(R.id.info_icon, View.GONE)
|
||||||
injector.text(R.id.label, getString(R.string.settings_not_visible))
|
injector.text(R.id.label, getString(R.string.settings_not_visible))
|
||||||
|
isVisible = false
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
injector.visibility(R.id.error_icon, View.GONE)
|
injector.visibility(R.id.error_icon, View.GONE)
|
||||||
injector.visibility(R.id.info_icon, View.VISIBLE)
|
injector.visibility(R.id.info_icon, View.VISIBLE)
|
||||||
injector.text(R.id.label, getString(R.string.settings_not_visible))
|
injector.text(R.id.label, getString(R.string.settings_not_visible))
|
||||||
|
isVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,6 +163,8 @@ class GlanceTabFragment : Fragment() {
|
|||||||
if (!(Preferences.showNextAlarm && AlarmHelper.isAlarmProbablyWrong(
|
if (!(Preferences.showNextAlarm && AlarmHelper.isAlarmProbablyWrong(
|
||||||
requireContext()))
|
requireContext()))
|
||||||
) View.VISIBLE else View.GONE)
|
) View.VISIBLE else View.GONE)
|
||||||
|
isVisible = !(Preferences.showNextAlarm && AlarmHelper.isAlarmProbablyWrong(
|
||||||
|
requireContext()))
|
||||||
}
|
}
|
||||||
Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> {
|
Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> {
|
||||||
injector.text(R.id.label,
|
injector.text(R.id.label,
|
||||||
@ -163,6 +172,7 @@ class GlanceTabFragment : Fragment() {
|
|||||||
R.string.settings_not_visible))
|
R.string.settings_not_visible))
|
||||||
injector.visibility(R.id.error_icon, View.GONE)
|
injector.visibility(R.id.error_icon, View.GONE)
|
||||||
injector.visibility(R.id.info_icon, View.VISIBLE)
|
injector.visibility(R.id.info_icon, View.VISIBLE)
|
||||||
|
isVisible = Preferences.showBatteryCharging
|
||||||
}
|
}
|
||||||
Constants.GlanceProviderId.NOTIFICATIONS -> {
|
Constants.GlanceProviderId.NOTIFICATIONS -> {
|
||||||
when {
|
when {
|
||||||
@ -172,16 +182,19 @@ class GlanceTabFragment : Fragment() {
|
|||||||
injector.text(R.id.label,
|
injector.text(R.id.label,
|
||||||
if (Preferences.showNotifications) getString(
|
if (Preferences.showNotifications) getString(
|
||||||
R.string.settings_visible) else getString(R.string.settings_not_visible))
|
R.string.settings_visible) else getString(R.string.settings_not_visible))
|
||||||
|
isVisible = Preferences.showNotifications
|
||||||
}
|
}
|
||||||
Preferences.showNotifications -> {
|
Preferences.showNotifications -> {
|
||||||
injector.visibility(R.id.error_icon, View.VISIBLE)
|
injector.visibility(R.id.error_icon, View.VISIBLE)
|
||||||
injector.visibility(R.id.info_icon, View.GONE)
|
injector.visibility(R.id.info_icon, View.GONE)
|
||||||
injector.text(R.id.label, getString(R.string.settings_not_visible))
|
injector.text(R.id.label, getString(R.string.settings_not_visible))
|
||||||
|
isVisible = false
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
injector.visibility(R.id.error_icon, View.GONE)
|
injector.visibility(R.id.error_icon, View.GONE)
|
||||||
injector.visibility(R.id.info_icon, View.VISIBLE)
|
injector.visibility(R.id.info_icon, View.VISIBLE)
|
||||||
injector.text(R.id.label, getString(R.string.settings_not_visible))
|
injector.text(R.id.label, getString(R.string.settings_not_visible))
|
||||||
|
isVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -191,6 +204,7 @@ class GlanceTabFragment : Fragment() {
|
|||||||
R.string.settings_not_visible))
|
R.string.settings_not_visible))
|
||||||
injector.visibility(R.id.error_icon, View.GONE)
|
injector.visibility(R.id.error_icon, View.GONE)
|
||||||
injector.visibility(R.id.info_icon, View.VISIBLE)
|
injector.visibility(R.id.info_icon, View.VISIBLE)
|
||||||
|
isVisible = Preferences.showGreetings
|
||||||
}
|
}
|
||||||
Constants.GlanceProviderId.CUSTOM_INFO -> {
|
Constants.GlanceProviderId.CUSTOM_INFO -> {
|
||||||
injector.text(R.id.label,
|
injector.text(R.id.label,
|
||||||
@ -198,6 +212,7 @@ class GlanceTabFragment : Fragment() {
|
|||||||
R.string.settings_not_visible))
|
R.string.settings_not_visible))
|
||||||
injector.visibility(R.id.error_icon, View.GONE)
|
injector.visibility(R.id.error_icon, View.GONE)
|
||||||
injector.visibility(R.id.info_icon, View.VISIBLE)
|
injector.visibility(R.id.info_icon, View.VISIBLE)
|
||||||
|
isVisible = Preferences.customNotes != ""
|
||||||
}
|
}
|
||||||
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> {
|
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> {
|
||||||
val account: GoogleSignInAccount? = GoogleSignIn.getLastSignedInAccount(context)
|
val account: GoogleSignInAccount? = GoogleSignIn.getLastSignedInAccount(context)
|
||||||
@ -209,19 +224,34 @@ class GlanceTabFragment : Fragment() {
|
|||||||
R.string.settings_not_visible))
|
R.string.settings_not_visible))
|
||||||
injector.visibility(R.id.error_icon, View.GONE)
|
injector.visibility(R.id.error_icon, View.GONE)
|
||||||
injector.visibility(R.id.info_icon, View.VISIBLE)
|
injector.visibility(R.id.info_icon, View.VISIBLE)
|
||||||
|
isVisible = Preferences.showDailySteps
|
||||||
} else if (Preferences.showDailySteps) {
|
} else if (Preferences.showDailySteps) {
|
||||||
ActivityDetectionReceiver.unregisterFence(requireContext())
|
ActivityDetectionReceiver.unregisterFence(requireContext())
|
||||||
injector.visibility(R.id.error_icon, View.VISIBLE)
|
injector.visibility(R.id.error_icon, View.VISIBLE)
|
||||||
injector.visibility(R.id.info_icon, View.GONE)
|
injector.visibility(R.id.info_icon, View.GONE)
|
||||||
injector.text(R.id.label, getString(R.string.settings_not_visible))
|
injector.text(R.id.label, getString(R.string.settings_not_visible))
|
||||||
|
isVisible = false
|
||||||
} else {
|
} else {
|
||||||
ActivityDetectionReceiver.unregisterFence(requireContext())
|
ActivityDetectionReceiver.unregisterFence(requireContext())
|
||||||
injector.text(R.id.label, getString(R.string.settings_not_visible))
|
injector.text(R.id.label, getString(R.string.settings_not_visible))
|
||||||
injector.visibility(R.id.error_icon, View.GONE)
|
injector.visibility(R.id.error_icon, View.GONE)
|
||||||
injector.visibility(R.id.info_icon, View.VISIBLE)
|
injector.visibility(R.id.info_icon, View.VISIBLE)
|
||||||
|
isVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Constants.GlanceProviderId.EVENTS -> {
|
||||||
|
isVisible = Preferences.showEventsAsGlanceProvider && Preferences.showEvents && requireContext().checkGrantedPermission(Manifest.permission.READ_CALENDAR)
|
||||||
|
injector.text(R.id.label,
|
||||||
|
if (isVisible) getString(R.string.settings_visible) else getString(
|
||||||
|
R.string.settings_not_visible))
|
||||||
|
injector.visibility(R.id.error_icon, if (isVisible) View.GONE else View.VISIBLE)
|
||||||
|
injector.visibility(R.id.info_icon, if (isVisible) View.VISIBLE else View.GONE)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
injector.alpha(R.id.title, if (isVisible) 1f else .25f)
|
||||||
|
injector.alpha(R.id.label, if (isVisible) 1f else .25f)
|
||||||
|
injector.alpha(R.id.icon, if (isVisible) 1f else .25f)
|
||||||
}
|
}
|
||||||
.attachTo(providers_list)
|
.attachTo(providers_list)
|
||||||
|
|
||||||
@ -231,8 +261,6 @@ class GlanceTabFragment : Fragment() {
|
|||||||
0
|
0
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val list = GlanceProviderHelper.getGlanceProviders(requireContext())
|
|
||||||
|
|
||||||
override fun onMove(
|
override fun onMove(
|
||||||
recyclerView: RecyclerView,
|
recyclerView: RecyclerView,
|
||||||
viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder,
|
viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder,
|
||||||
@ -241,11 +269,25 @@ class GlanceTabFragment : Fragment() {
|
|||||||
val toPos = target.adapterPosition
|
val toPos = target.adapterPosition
|
||||||
// move item in `fromPos` to `toPos` in adapter.
|
// move item in `fromPos` to `toPos` in adapter.
|
||||||
adapter.notifyItemMoved(fromPos, toPos)
|
adapter.notifyItemMoved(fromPos, toPos)
|
||||||
|
|
||||||
Collections.swap(list, fromPos, toPos)
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onMoved(
|
||||||
|
recyclerView: RecyclerView,
|
||||||
|
viewHolder: RecyclerView.ViewHolder,
|
||||||
|
fromPos: Int,
|
||||||
|
target: RecyclerView.ViewHolder,
|
||||||
|
toPos: Int,
|
||||||
|
x: Int,
|
||||||
|
y: Int
|
||||||
|
) {
|
||||||
|
with(list[toPos]) {
|
||||||
|
list[toPos] = list[fromPos]
|
||||||
|
list[fromPos] = this
|
||||||
|
}
|
||||||
|
super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y)
|
||||||
|
}
|
||||||
|
|
||||||
override fun isItemViewSwipeEnabled(): Boolean {
|
override fun isItemViewSwipeEnabled(): Boolean {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -255,7 +297,10 @@ class GlanceTabFragment : Fragment() {
|
|||||||
viewHolder: RecyclerView.ViewHolder
|
viewHolder: RecyclerView.ViewHolder
|
||||||
) {
|
) {
|
||||||
super.clearView(recyclerView, viewHolder)
|
super.clearView(recyclerView, viewHolder)
|
||||||
GlanceProviderHelper.saveGlanceProviderOrder(list)
|
GlanceProviderHelper.saveGlanceProviderOrder(
|
||||||
|
list
|
||||||
|
)
|
||||||
|
adapter.updateData(list.mapNotNull { GlanceProviderHelper.getGlanceProviderById(requireContext(), it) })
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onChildDraw(
|
override fun onChildDraw(
|
||||||
@ -279,7 +324,6 @@ class GlanceTabFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val topEdge = if ((view.top == 0 && dY < 0) || ((view.top + view.height >= recyclerView.height - 32f.convertDpToPixel(requireContext())) && dY > 0)) 0f else dY
|
val topEdge = if ((view.top == 0 && dY < 0) || ((view.top + view.height >= recyclerView.height - 32f.convertDpToPixel(requireContext())) && dY > 0)) 0f else dY
|
||||||
Log.d("ciao", "${view.top} + ${view.height} = ${view.top + view.height} to compare to ${recyclerView.height} - ${32f.convertDpToPixel(requireContext())}")
|
|
||||||
|
|
||||||
super.onChildDraw(c,
|
super.onChildDraw(c,
|
||||||
recyclerView,
|
recyclerView,
|
||||||
@ -299,11 +343,7 @@ class GlanceTabFragment : Fragment() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
mIth.attachToRecyclerView(providers_list)
|
mIth.attachToRecyclerView(providers_list)
|
||||||
adapter.updateData(
|
adapter.updateData(list.mapNotNull { GlanceProviderHelper.getGlanceProviderById(requireContext(), it) })
|
||||||
GlanceProviderHelper.getGlanceProviders(requireContext())
|
|
||||||
.mapNotNull { GlanceProviderHelper.getGlanceProviderById(requireContext(), it) }
|
|
||||||
.filterNot { it.id == Constants.GlanceProviderId.GREETINGS.id }
|
|
||||||
)
|
|
||||||
providers_list.isNestedScrollingEnabled = false
|
providers_list.isNestedScrollingEnabled = false
|
||||||
|
|
||||||
setupListener()
|
setupListener()
|
||||||
@ -333,6 +373,11 @@ class GlanceTabFragment : Fragment() {
|
|||||||
show_glance_switch.setOnCheckedChangeListener { _, enabled: Boolean ->
|
show_glance_switch.setOnCheckedChangeListener { _, enabled: Boolean ->
|
||||||
Preferences.showGlance = enabled
|
Preferences.showGlance = enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
action_show_glance.setOnLongClickListener {
|
||||||
|
Preferences.enabledGlanceProviderOrder = ""
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val nextAlarmChangeBroadcastReceiver = object : BroadcastReceiver() {
|
private val nextAlarmChangeBroadcastReceiver = object : BroadcastReceiver() {
|
||||||
|
@ -351,9 +351,10 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
}?.isVisible = if (Preferences.showWeather) {
|
}?.isVisible = if (Preferences.showWeather) {
|
||||||
(WeatherHelper.isKeyRequired() && WeatherHelper.getApiKey() == "")
|
(WeatherHelper.isKeyRequired() && WeatherHelper.getApiKey() == "")
|
||||||
|| (Preferences.customLocationAdd == "" && activity?.checkGrantedPermission(
|
|| (Preferences.customLocationAdd == "" && activity?.checkGrantedPermission(
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION
|
Manifest.permission.ACCESS_FINE_LOCATION
|
||||||
) != true)
|
) != true)
|
||||||
|| (Preferences.weatherProviderError != "" && Preferences.weatherProviderError != "-")
|
|| (Preferences.weatherProviderError != "" && Preferences.weatherProviderError != "-")
|
||||||
|
|| (Preferences.weatherProviderLocationError != "")
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@ -364,7 +365,8 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
badgeGravity = BadgeDrawable.TOP_END
|
badgeGravity = BadgeDrawable.TOP_END
|
||||||
}?.isVisible = ((Preferences.showMusic || Preferences.showNotifications) && !ActiveNotificationsHelper.checkNotificationAccess(requireContext())) ||
|
}?.isVisible = ((Preferences.showMusic || Preferences.showNotifications) && !ActiveNotificationsHelper.checkNotificationAccess(requireContext())) ||
|
||||||
(Preferences.showDailySteps && !(Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || requireActivity().checkGrantedPermission(Manifest.permission.ACTIVITY_RECOGNITION))) ||
|
(Preferences.showDailySteps && !(Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || requireActivity().checkGrantedPermission(Manifest.permission.ACTIVITY_RECOGNITION))) ||
|
||||||
(AlarmHelper.isAlarmProbablyWrong(requireContext()))
|
(AlarmHelper.isAlarmProbablyWrong(requireContext())) ||
|
||||||
|
(Preferences.showEventsAsGlanceProvider && (!Preferences.showEvents || !requireContext().checkGrantedPermission(Manifest.permission.READ_CALENDAR)))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
@ -395,6 +397,7 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
}
|
}
|
||||||
|
|
||||||
class UpdateUiMessageEvent
|
class UpdateUiMessageEvent
|
||||||
|
class ChangeTabEvent(val page: Int)
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
fun onMessageEvent(ignore: UpdateUiMessageEvent?) {
|
fun onMessageEvent(ignore: UpdateUiMessageEvent?) {
|
||||||
@ -406,4 +409,11 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
|
fun onMessageEvent(event: ChangeTabEvent?) {
|
||||||
|
event?.let {
|
||||||
|
pager.setCurrentItem(event.page, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,8 @@ import com.tommasoberlose.anotherwidget.ui.activities.WeatherProviderActivity
|
|||||||
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
|
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
|
||||||
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||||
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.collapse
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.expand
|
||||||
import kotlinx.android.synthetic.main.fragment_weather_settings.*
|
import kotlinx.android.synthetic.main.fragment_weather_settings.*
|
||||||
import kotlinx.android.synthetic.main.fragment_weather_settings.scrollView
|
import kotlinx.android.synthetic.main.fragment_weather_settings.scrollView
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
@ -87,11 +89,6 @@ class WeatherTabFragment : Fragment() {
|
|||||||
) {
|
) {
|
||||||
binding.isWeatherVisible = Preferences.showWeather
|
binding.isWeatherVisible = Preferences.showWeather
|
||||||
|
|
||||||
viewModel.showWeatherWarning.observe(viewLifecycleOwner, Observer {
|
|
||||||
weather_warning?.isVisible = it
|
|
||||||
checkLocationPermission()
|
|
||||||
})
|
|
||||||
|
|
||||||
viewModel.showWeather.observe(viewLifecycleOwner, Observer {
|
viewModel.showWeather.observe(viewLifecycleOwner, Observer {
|
||||||
maintainScrollPosition {
|
maintainScrollPosition {
|
||||||
show_weather_label?.text =
|
show_weather_label?.text =
|
||||||
@ -100,6 +97,7 @@ class WeatherTabFragment : Fragment() {
|
|||||||
binding.isWeatherVisible = it
|
binding.isWeatherVisible = it
|
||||||
}
|
}
|
||||||
checkLocationPermission()
|
checkLocationPermission()
|
||||||
|
checkWeatherProviderConfig()
|
||||||
})
|
})
|
||||||
|
|
||||||
viewModel.weatherProvider.observe(viewLifecycleOwner, Observer {
|
viewModel.weatherProvider.observe(viewLifecycleOwner, Observer {
|
||||||
@ -119,7 +117,6 @@ class WeatherTabFragment : Fragment() {
|
|||||||
|
|
||||||
viewModel.customLocationAdd.observe(viewLifecycleOwner, Observer {
|
viewModel.customLocationAdd.observe(viewLifecycleOwner, Observer {
|
||||||
maintainScrollPosition {
|
maintainScrollPosition {
|
||||||
background_location_warning.isVisible = it == ""
|
|
||||||
label_custom_location?.text =
|
label_custom_location?.text =
|
||||||
if (it == "") getString(R.string.custom_location_gps) else it
|
if (it == "") getString(R.string.custom_location_gps) else it
|
||||||
}
|
}
|
||||||
@ -163,18 +160,11 @@ class WeatherTabFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun checkLocationPermission() {
|
private fun checkLocationPermission() {
|
||||||
// Background permission
|
if (requireActivity().checkGrantedPermission(Manifest.permission.ACCESS_FINE_LOCATION)) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && activity?.checkGrantedPermission(Manifest.permission.ACCESS_FINE_LOCATION) == true && activity?.checkGrantedPermission(Manifest.permission.ACCESS_BACKGROUND_LOCATION) != true) {
|
|
||||||
requirePermission()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (activity?.checkGrantedPermission(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION) == true) {
|
|
||||||
location_permission_alert?.isVisible = false
|
location_permission_alert?.isVisible = false
|
||||||
background_location_warning.isVisible = Preferences.customLocationAdd == ""
|
|
||||||
WeatherReceiver.setUpdates(requireContext())
|
WeatherReceiver.setUpdates(requireContext())
|
||||||
} else if (Preferences.showWeather && Preferences.customLocationAdd == "") {
|
} else if (Preferences.showWeather && Preferences.customLocationAdd == "") {
|
||||||
location_permission_alert?.isVisible = true
|
location_permission_alert?.isVisible = true
|
||||||
background_location_warning.isVisible = false
|
|
||||||
location_permission_alert?.setOnClickListener {
|
location_permission_alert?.setOnClickListener {
|
||||||
MaterialBottomSheetDialog(requireContext(), message = getString(R.string.background_location_warning))
|
MaterialBottomSheetDialog(requireContext(), message = getString(R.string.background_location_warning))
|
||||||
.setPositiveButton(getString(android.R.string.ok)) {
|
.setPositiveButton(getString(android.R.string.ok)) {
|
||||||
@ -188,18 +178,22 @@ class WeatherTabFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun checkWeatherProviderConfig() {
|
private fun checkWeatherProviderConfig() {
|
||||||
weather_provider_error.isVisible = Preferences.weatherProviderError != "" && Preferences.weatherProviderError != "-"
|
if (Preferences.showWeather && Preferences.weatherProviderError != "" && Preferences.weatherProviderError != "-" && !location_permission_alert.isVisible) {
|
||||||
|
weather_provider_error.expand()
|
||||||
|
} else {
|
||||||
|
weather_provider_error.collapse()
|
||||||
|
}
|
||||||
weather_provider_error?.text = Preferences.weatherProviderError
|
weather_provider_error?.text = Preferences.weatherProviderError
|
||||||
|
|
||||||
weather_provider_location_error.isVisible = Preferences.weatherProviderLocationError != ""
|
if (Preferences.showWeather && Preferences.weatherProviderLocationError != "" && !location_permission_alert.isVisible) {
|
||||||
|
weather_provider_location_error.expand()
|
||||||
|
} else {
|
||||||
|
weather_provider_location_error.collapse()
|
||||||
|
}
|
||||||
weather_provider_location_error?.text = Preferences.weatherProviderLocationError
|
weather_provider_location_error?.text = Preferences.weatherProviderLocationError
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupListener() {
|
private fun setupListener() {
|
||||||
action_hide_weather_warning.setOnClickListener {
|
|
||||||
Preferences.showWeatherWarning = false
|
|
||||||
}
|
|
||||||
|
|
||||||
action_show_weather.setOnClickListener {
|
action_show_weather.setOnClickListener {
|
||||||
Preferences.showWeather = !Preferences.showWeather
|
Preferences.showWeather = !Preferences.showWeather
|
||||||
}
|
}
|
||||||
@ -297,7 +291,7 @@ class WeatherTabFragment : Fragment() {
|
|||||||
private fun requirePermission() {
|
private fun requirePermission() {
|
||||||
Dexter.withContext(requireContext())
|
Dexter.withContext(requireContext())
|
||||||
.withPermissions(
|
.withPermissions(
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION
|
Manifest.permission.ACCESS_FINE_LOCATION
|
||||||
).withListener(object: MultiplePermissionsListener {
|
).withListener(object: MultiplePermissionsListener {
|
||||||
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
|
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
|
||||||
report?.let {
|
report?.let {
|
||||||
|
@ -29,6 +29,7 @@ import com.tommasoberlose.anotherwidget.global.Constants
|
|||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.helpers.*
|
import com.tommasoberlose.anotherwidget.helpers.*
|
||||||
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toIntValue
|
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toIntValue
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.ImageHelper.applyShadow
|
||||||
import com.tommasoberlose.anotherwidget.receivers.*
|
import com.tommasoberlose.anotherwidget.receivers.*
|
||||||
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
||||||
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
|
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
|
||||||
@ -171,7 +172,7 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
val nextEvent = eventRepository.getNextEvent()
|
val nextEvent = eventRepository.getNextEvent()
|
||||||
val nextAlarm = AlarmHelper.getNextAlarm(context)
|
val nextAlarm = AlarmHelper.getNextAlarm(context)
|
||||||
|
|
||||||
if (Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null) {
|
if (Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null && !Preferences.showEventsAsGlanceProvider) {
|
||||||
if (Preferences.showNextEvent && eventRepository.getEventsCount() > 1) {
|
if (Preferences.showNextEvent && eventRepository.getEventsCount() > 1) {
|
||||||
views.setImageViewBitmap(
|
views.setImageViewBitmap(
|
||||||
R.id.action_next_rect,
|
R.id.action_next_rect,
|
||||||
@ -350,8 +351,12 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
Constants.GlanceProviderId.NOTIFICATIONS -> {
|
Constants.GlanceProviderId.NOTIFICATIONS -> {
|
||||||
if (Preferences.showNotifications && ActiveNotificationsHelper.showLastNotification()) {
|
if (Preferences.showNotifications && ActiveNotificationsHelper.showLastNotification()) {
|
||||||
try {
|
try {
|
||||||
val remotePackageContext = context.createPackageContext(Preferences.lastNotificationPackage, 0)
|
if (Preferences.lastNotificationIcon != 0) {
|
||||||
val icon = ContextCompat.getDrawable(remotePackageContext, Preferences.lastNotificationIcon)
|
val remotePackageContext = context.createPackageContext(Preferences.lastNotificationPackage, 0)
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
remotePackageContext,
|
||||||
|
Preferences.lastNotificationIcon)
|
||||||
|
}
|
||||||
val notificationIntent = PendingIntent.getActivity(
|
val notificationIntent = PendingIntent.getActivity(
|
||||||
context,
|
context,
|
||||||
widgetID,
|
widgetID,
|
||||||
@ -367,6 +372,32 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
} catch (ex: Exception) {}
|
} catch (ex: Exception) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Constants.GlanceProviderId.GREETINGS -> {
|
||||||
|
if (Preferences.showGreetings && GreetingsHelper.showGreetings() && GreetingsHelper.getRandomString(context).isNotBlank()) {
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.EVENTS -> {
|
||||||
|
if (Preferences.showEventsAsGlanceProvider&& Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null) {
|
||||||
|
val pIntentDetail = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getEventIntent(
|
||||||
|
context,
|
||||||
|
nextEvent,
|
||||||
|
forceEventDetails = true
|
||||||
|
),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(
|
||||||
|
R.id.second_row_rect,
|
||||||
|
pIntentDetail
|
||||||
|
)
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,7 +572,7 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
val nextEvent = eventRepository.getNextEvent()
|
val nextEvent = eventRepository.getNextEvent()
|
||||||
val nextAlarm = AlarmHelper.getNextAlarm(context)
|
val nextAlarm = AlarmHelper.getNextAlarm(context)
|
||||||
|
|
||||||
if (Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null) {
|
if (Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null && !Preferences.showEventsAsGlanceProvider) {
|
||||||
// Multiple counter
|
// Multiple counter
|
||||||
v.action_next.isVisible =
|
v.action_next.isVisible =
|
||||||
Preferences.showNextEvent && eventRepository.getEventsCount() > 1
|
Preferences.showNextEvent && eventRepository.getEventsCount() > 1
|
||||||
@ -574,7 +605,7 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
v.second_row_icon.setImageDrawable(
|
v.second_row_icon.setImageDrawable(
|
||||||
ContextCompat.getDrawable(
|
ContextCompat.getDrawable(
|
||||||
context,
|
context,
|
||||||
R.drawable.round_place
|
R.drawable.round_place_24
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
v.next_event_date.text = nextEvent.address
|
v.next_event_date.text = nextEvent.address
|
||||||
@ -582,7 +613,7 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
v.second_row_icon.setImageDrawable(
|
v.second_row_icon.setImageDrawable(
|
||||||
ContextCompat.getDrawable(
|
ContextCompat.getDrawable(
|
||||||
context,
|
context,
|
||||||
R.drawable.round_today
|
R.drawable.round_today_24
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if (!nextEvent.allDay) {
|
if (!nextEvent.allDay) {
|
||||||
@ -606,7 +637,7 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
dayDiff++
|
dayDiff++
|
||||||
} else if (startCal.get(Calendar.HOUR_OF_DAY) == endCal.get(Calendar.HOUR_OF_DAY) && startCal.get(
|
} else if (startCal.get(Calendar.HOUR_OF_DAY) == endCal.get(Calendar.HOUR_OF_DAY) && startCal.get(
|
||||||
Calendar.MINUTE
|
Calendar.MINUTE
|
||||||
) >= endCal.get(Calendar.MINUTE)
|
) > endCal.get(Calendar.MINUTE)
|
||||||
) {
|
) {
|
||||||
dayDiff++
|
dayDiff++
|
||||||
}
|
}
|
||||||
@ -618,14 +649,27 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
context.getString(R.string.day_char)
|
context.getString(R.string.day_char)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
v.next_event_date.text =
|
|
||||||
String.format("%s - %s%s", startHour, endHour, multipleDay)
|
if (nextEvent.startDate != nextEvent.endDate) {
|
||||||
|
v.next_event_date.text =
|
||||||
|
String.format("%s - %s%s", startHour, endHour, multipleDay)
|
||||||
|
} else {
|
||||||
|
v.next_event_date.text =
|
||||||
|
String.format("%s", startHour)
|
||||||
|
}
|
||||||
|
|
||||||
} 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
|
||||||
v.next_event_date.text =
|
val start = Calendar.getInstance().apply { timeInMillis = nextEvent.startDate }
|
||||||
|
|
||||||
|
v.next_event_date.text = if (now.get(Calendar.DAY_OF_YEAR) == start.get(Calendar.DAY_OF_YEAR)) {
|
||||||
DateUtils.formatDateTime(context, nextEvent.startDate, flags)
|
DateUtils.formatDateTime(context, nextEvent.startDate, flags)
|
||||||
|
} else if (now.get(Calendar.DAY_OF_YEAR) > start.get(Calendar.DAY_OF_YEAR) || now.get(Calendar.YEAR) > start.get(Calendar.YEAR)) {
|
||||||
|
DateUtils.formatDateTime(context, now.timeInMillis, flags)
|
||||||
|
} else {
|
||||||
|
DateUtils.formatDateTime(context, nextEvent.startDate, flags)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -650,7 +694,7 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
v.second_row_icon.setImageDrawable(
|
v.second_row_icon.setImageDrawable(
|
||||||
ContextCompat.getDrawable(
|
ContextCompat.getDrawable(
|
||||||
context,
|
context,
|
||||||
R.drawable.round_music_note
|
R.drawable.round_music_note_24
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
v.next_event_date.text = MediaPlayerHelper.getMediaInfo()
|
v.next_event_date.text = MediaPlayerHelper.getMediaInfo()
|
||||||
@ -663,7 +707,7 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
v.second_row_icon.setImageDrawable(
|
v.second_row_icon.setImageDrawable(
|
||||||
ContextCompat.getDrawable(
|
ContextCompat.getDrawable(
|
||||||
context,
|
context,
|
||||||
R.drawable.round_alarm
|
R.drawable.round_alarm_24
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
v.next_event_date.text = AlarmHelper.getNextAlarm(context)
|
v.next_event_date.text = AlarmHelper.getNextAlarm(context)
|
||||||
@ -698,7 +742,6 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
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.gravity
|
|
||||||
v.next_event_date.maxLines = 2
|
v.next_event_date.maxLines = 2
|
||||||
showSomething = true
|
showSomething = true
|
||||||
break@loop
|
break@loop
|
||||||
@ -717,16 +760,60 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
Constants.GlanceProviderId.NOTIFICATIONS -> {
|
Constants.GlanceProviderId.NOTIFICATIONS -> {
|
||||||
if (Preferences.showNotifications && ActiveNotificationsHelper.showLastNotification()) {
|
if (Preferences.showNotifications && ActiveNotificationsHelper.showLastNotification()) {
|
||||||
try {
|
try {
|
||||||
val remotePackageContext = context.createPackageContext(Preferences.lastNotificationPackage, 0)
|
if (Preferences.lastNotificationIcon != 0) {
|
||||||
val icon = ContextCompat.getDrawable(remotePackageContext, Preferences.lastNotificationIcon)
|
val remotePackageContext = context.createPackageContext(Preferences.lastNotificationPackage, 0)
|
||||||
v.second_row_icon.isVisible = true
|
val icon = ContextCompat.getDrawable(remotePackageContext,
|
||||||
v.second_row_icon.setImageDrawable(icon)
|
Preferences.lastNotificationIcon)
|
||||||
|
v.second_row_icon.isVisible = true
|
||||||
|
v.second_row_icon.setImageDrawable(icon)
|
||||||
|
} else {
|
||||||
|
v.second_row_icon.isVisible = false
|
||||||
|
}
|
||||||
v.next_event_date.text = Preferences.lastNotificationTitle
|
v.next_event_date.text = Preferences.lastNotificationTitle
|
||||||
showSomething = true
|
showSomething = true
|
||||||
break@loop
|
break@loop
|
||||||
} catch (ex: Exception) {}
|
} catch (ex: Exception) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Constants.GlanceProviderId.GREETINGS -> {
|
||||||
|
val greetingsText = GreetingsHelper.getRandomString(context)
|
||||||
|
if (Preferences.showGreetings && GreetingsHelper.showGreetings() && greetingsText.isNotBlank()) {
|
||||||
|
v.next_event_date.text = greetingsText
|
||||||
|
v.next_event_date.maxLines = 2
|
||||||
|
v.second_row_icon.isVisible = false
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Constants.GlanceProviderId.EVENTS -> {
|
||||||
|
if (Preferences.showEventsAsGlanceProvider && Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null) {
|
||||||
|
v.next_event_date.text = context.getString(R.string.events_glance_provider_format).format(nextEvent.title, if (Preferences.showDiffTime && now.timeInMillis < nextEvent.startDate) {
|
||||||
|
if (!nextEvent.allDay) {
|
||||||
|
SettingsStringHelper.getDifferenceText(
|
||||||
|
context,
|
||||||
|
now.timeInMillis,
|
||||||
|
nextEvent.startDate
|
||||||
|
)
|
||||||
|
.toLowerCase(Locale.getDefault())
|
||||||
|
} else {
|
||||||
|
SettingsStringHelper.getAllDayEventDifferenceText(
|
||||||
|
context,
|
||||||
|
now.timeInMillis,
|
||||||
|
nextEvent.startDate
|
||||||
|
).toLowerCase(Locale.getDefault())
|
||||||
|
}
|
||||||
|
} else "").trimEnd()
|
||||||
|
v.second_row_icon.isVisible = true
|
||||||
|
v.second_row_icon.setImageDrawable(
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
context,
|
||||||
|
R.drawable.round_today_24
|
||||||
|
)
|
||||||
|
)
|
||||||
|
showSomething = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -782,9 +869,9 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Preferences.weatherIconPack != Constants.WeatherIconPack.MINIMAL.value) {
|
if (Preferences.weatherIconPack != Constants.WeatherIconPack.MINIMAL.value) {
|
||||||
listOf<ImageView>(v.second_row_icon)
|
listOf<ImageView>(v.second_row_icon, v.second_row_icon_shadow)
|
||||||
} else {
|
} else {
|
||||||
listOf<ImageView>(v.second_row_icon, v.weather_icon)
|
listOf<ImageView>(v.second_row_icon, v.weather_icon, v.second_row_icon_shadow)
|
||||||
}.forEach {
|
}.forEach {
|
||||||
it.setColorFilter(ColorHelper.getSecondaryFontColorRgb(context.applicationContext.isDarkTheme()))
|
it.setColorFilter(ColorHelper.getSecondaryFontColorRgb(context.applicationContext.isDarkTheme()))
|
||||||
it.alpha =
|
it.alpha =
|
||||||
@ -825,8 +912,8 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
v.action_previous.scaleX = Preferences.textMainSize / 28f
|
v.action_previous.scaleX = Preferences.textMainSize / 28f
|
||||||
v.action_previous.scaleY = Preferences.textMainSize / 28f
|
v.action_previous.scaleY = Preferences.textMainSize / 28f
|
||||||
|
|
||||||
v.special_weather_icon.scaleX = Preferences.textMainSize / 20f
|
v.special_weather_icon.scaleX = Preferences.textMainSize / 18f
|
||||||
v.special_weather_icon.scaleY = Preferences.textMainSize / 20f
|
v.special_weather_icon.scaleY = Preferences.textMainSize / 18f
|
||||||
|
|
||||||
|
|
||||||
// Shadows
|
// Shadows
|
||||||
@ -867,6 +954,38 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
it.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
it.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Icons shadow
|
||||||
|
|
||||||
|
listOf(
|
||||||
|
Pair(v.second_row_icon, v.second_row_icon_shadow),
|
||||||
|
).forEach {
|
||||||
|
if ((if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) == 0) {
|
||||||
|
it.second.isVisible = false
|
||||||
|
} else {
|
||||||
|
it.second.isVisible = it.first.isVisible
|
||||||
|
it.second.scaleX = it.first.scaleX
|
||||||
|
it.second.scaleY = it.first.scaleY
|
||||||
|
it.second.applyShadow(it.first)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listOf(
|
||||||
|
Pair(v.action_next, v.action_next_shadow),
|
||||||
|
Pair(v.action_previous, v.action_previous_shadow),
|
||||||
|
).forEach {
|
||||||
|
if ((if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) == 0) {
|
||||||
|
it.second.isVisible = false
|
||||||
|
} else {
|
||||||
|
it.second.isVisible = it.first.isVisible
|
||||||
|
it.second.scaleX = it.first.scaleX
|
||||||
|
it.second.scaleY = it.first.scaleY
|
||||||
|
it.second.applyShadow(it.first, 0.6f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
v.action_previous.scaleX = v.action_previous.scaleX * -1
|
||||||
|
v.action_previous_shadow.scaleX = v.action_previous_shadow.scaleX * -1
|
||||||
|
|
||||||
// Custom Font
|
// Custom Font
|
||||||
if (Preferences.customFont == Constants.CUSTOM_FONT_GOOGLE_SANS) {
|
if (Preferences.customFont == Constants.CUSTOM_FONT_GOOGLE_SANS) {
|
||||||
val googleSans: Typeface = when (Preferences.customFontVariant) {
|
val googleSans: Typeface = when (Preferences.customFontVariant) {
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
package com.tommasoberlose.anotherwidget.utils
|
package com.tommasoberlose.anotherwidget.utils
|
||||||
|
|
||||||
|
import android.animation.*
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewAnimationUtils
|
import android.view.ViewAnimationUtils
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import android.animation.Animator
|
|
||||||
import android.animation.AnimatorListenerAdapter
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.WallpaperManager
|
import android.app.WallpaperManager
|
||||||
import android.content.*
|
import android.content.*
|
||||||
@ -22,11 +21,22 @@ import android.content.Intent
|
|||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.util.DisplayMetrics
|
import android.util.DisplayMetrics
|
||||||
|
import android.util.Log
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
|
import android.view.ViewPropertyAnimator
|
||||||
import android.view.animation.Animation
|
import android.view.animation.Animation
|
||||||
import android.view.animation.Transformation
|
import android.view.animation.Transformation
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.RelativeLayout
|
||||||
|
import androidx.core.animation.addListener
|
||||||
|
import androidx.core.animation.doOnEnd
|
||||||
|
import androidx.core.animation.doOnStart
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import com.tommasoberlose.anotherwidget.R
|
import com.tommasoberlose.anotherwidget.R
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
|
||||||
|
import kotlinx.android.synthetic.main.fragment_app_main.*
|
||||||
|
import kotlinx.android.synthetic.main.the_widget_sans.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
@ -68,55 +78,72 @@ fun View.reveal(initialX: Int? = null, initialY: Int? = null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun View.expand() {
|
fun View.expand(duration: Long = 500L) {
|
||||||
if (visibility != View.VISIBLE) {
|
clearAnimation()
|
||||||
measure(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
try {
|
||||||
val targetHeight = measuredHeight
|
val animator = (tag as ValueAnimator)
|
||||||
|
animator.removeAllListeners()
|
||||||
|
animator.cancel()
|
||||||
|
} catch (ex: java.lang.Exception) {}
|
||||||
|
|
||||||
layoutParams.height = 0
|
layoutParams = layoutParams.apply {
|
||||||
visibility = View.VISIBLE
|
height = RelativeLayout.LayoutParams.WRAP_CONTENT
|
||||||
val a = object : Animation() {
|
|
||||||
protected override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
|
|
||||||
layoutParams.height = if (interpolatedTime == 1f)
|
|
||||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
|
||||||
else
|
|
||||||
(targetHeight * interpolatedTime).toInt()
|
|
||||||
translationY = 0f
|
|
||||||
requestLayout()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun willChangeBounds(): Boolean {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a.duration = 500L
|
|
||||||
startAnimation(a)
|
|
||||||
}
|
}
|
||||||
|
measure(0, 0)
|
||||||
|
|
||||||
|
val initialHeight = measuredHeight
|
||||||
|
val anim = ValueAnimator.ofFloat(
|
||||||
|
alpha,
|
||||||
|
1f
|
||||||
|
).apply {
|
||||||
|
this.duration = duration
|
||||||
|
addUpdateListener {
|
||||||
|
val animatedValue = animatedValue as Float
|
||||||
|
layoutParams = layoutParams.apply {
|
||||||
|
height = (initialHeight * animatedValue).toInt()
|
||||||
|
}
|
||||||
|
translationY = (initialHeight * animatedValue - initialHeight)
|
||||||
|
alpha = animatedValue
|
||||||
|
}
|
||||||
|
addListener(
|
||||||
|
onStart = {
|
||||||
|
isVisible = true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
tag = anim
|
||||||
|
anim.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun View.collapse(duration: Long = 500L) {
|
fun View.collapse(duration: Long = 500L) {
|
||||||
if (visibility != View.GONE) {
|
clearAnimation()
|
||||||
val initialHeight = measuredHeight
|
try {
|
||||||
|
val animator = (tag as ValueAnimator)
|
||||||
val a = object : Animation() {
|
animator.removeAllListeners()
|
||||||
protected override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
|
animator.cancel()
|
||||||
if (interpolatedTime == 1f) {
|
} catch (ex: java.lang.Exception) {}
|
||||||
visibility = View.GONE
|
val initialHeight = measuredHeight
|
||||||
} else {
|
val anim = ValueAnimator.ofFloat(
|
||||||
layoutParams.height = initialHeight - (initialHeight * interpolatedTime).toInt()
|
alpha,
|
||||||
requestLayout()
|
0f
|
||||||
}
|
).apply {
|
||||||
}
|
this.duration = duration
|
||||||
|
addUpdateListener {
|
||||||
override fun willChangeBounds(): Boolean {
|
val animatedValue = animatedValue as Float
|
||||||
return true
|
layoutParams = layoutParams.apply {
|
||||||
|
height = (initialHeight * animatedValue).toInt()
|
||||||
}
|
}
|
||||||
|
translationY = (initialHeight * animatedValue - initialHeight)
|
||||||
|
alpha = animatedValue
|
||||||
}
|
}
|
||||||
|
addListener(
|
||||||
a.duration = duration //(initialHeight / v.context.resources.displayMetrics.density).toLong()
|
onEnd = {
|
||||||
startAnimation(a)
|
isVisible = false
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
tag = anim
|
||||||
|
anim.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.openURI(url: String) {
|
fun Context.openURI(url: String) {
|
||||||
@ -230,4 +257,11 @@ fun Intent.isDefaultSet(context: Context): Boolean {
|
|||||||
} catch (ex: java.lang.Exception) {
|
} catch (ex: java.lang.Exception) {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Locale.isMetric(): Boolean {
|
||||||
|
return when (country.toUpperCase(this)) {
|
||||||
|
"US", "LR", "MM", "GB" -> false
|
||||||
|
else -> true
|
||||||
|
}
|
||||||
}
|
}
|
BIN
app/src/main/res/drawable-hdpi/ic_stat_notification.png
Normal file
After Width: | Height: | Size: 674 B |
Before Width: | Height: | Size: 518 B |
Before Width: | Height: | Size: 449 B |
Before Width: | Height: | Size: 751 B |
Before Width: | Height: | Size: 953 B |
Before Width: | Height: | Size: 868 B |
Before Width: | Height: | Size: 459 B |
Before Width: | Height: | Size: 601 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 229 B |
Before Width: | Height: | Size: 465 B |
Before Width: | Height: | Size: 548 B |
Before Width: | Height: | Size: 804 B |
Before Width: | Height: | Size: 1013 B |
Before Width: | Height: | Size: 399 B |
Before Width: | Height: | Size: 277 B |
Before Width: | Height: | Size: 289 B |
Before Width: | Height: | Size: 439 B |
Before Width: | Height: | Size: 150 B |
Before Width: | Height: | Size: 163 B |
Before Width: | Height: | Size: 242 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 459 B |
Before Width: | Height: | Size: 601 B |
Before Width: | Height: | Size: 868 B |
Before Width: | Height: | Size: 465 B |
Before Width: | Height: | Size: 399 B |
Before Width: | Height: | Size: 665 B |
Before Width: | Height: | Size: 867 B |
Before Width: | Height: | Size: 329 B |
Before Width: | Height: | Size: 407 B |
Before Width: | Height: | Size: 538 B |
Before Width: | Height: | Size: 648 B |
Before Width: | Height: | Size: 183 B |
Before Width: | Height: | Size: 158 B |
Before Width: | Height: | Size: 183 B |
Before Width: | Height: | Size: 244 B |
Before Width: | Height: | Size: 275 B |
Before Width: | Height: | Size: 536 B |
Before Width: | Height: | Size: 466 B |
Before Width: | Height: | Size: 778 B |
Before Width: | Height: | Size: 1005 B |
Before Width: | Height: | Size: 295 B |
Before Width: | Height: | Size: 275 B |
Before Width: | Height: | Size: 399 B |
Before Width: | Height: | Size: 428 B |
Before Width: | Height: | Size: 426 B |
Before Width: | Height: | Size: 238 B |
Before Width: | Height: | Size: 263 B |
Before Width: | Height: | Size: 355 B |
Before Width: | Height: | Size: 186 B |
Before Width: | Height: | Size: 184 B |
Before Width: | Height: | Size: 241 B |
Before Width: | Height: | Size: 248 B |
Before Width: | Height: | Size: 616 B |
Before Width: | Height: | Size: 324 B |
Before Width: | Height: | Size: 372 B |
Before Width: | Height: | Size: 517 B |
Before Width: | Height: | Size: 361 B |
Before Width: | Height: | Size: 333 B |
Before Width: | Height: | Size: 509 B |
Before Width: | Height: | Size: 642 B |
Before Width: | Height: | Size: 393 B |
Before Width: | Height: | Size: 441 B |
Before Width: | Height: | Size: 628 B |
Before Width: | Height: | Size: 802 B |
Before Width: | Height: | Size: 399 B |