Compare commits
10 Commits
v2.0.5-bet
...
v2.0.6-bet
Author | SHA1 | Date | |
---|---|---|---|
f013be5a7a | |||
4cc55edb15 | |||
d08ad6171e | |||
9e2eacef73 | |||
f8f8a8f051 | |||
60531061d7 | |||
654ec3fe66 | |||
d86d2cadd4 | |||
cb6c2c7764 | |||
6a4cfdf22b |
1
.gitignore
vendored
@ -8,3 +8,4 @@
|
|||||||
/captures
|
/captures
|
||||||
.externalNativeBuild
|
.externalNativeBuild
|
||||||
/tasksintegration/build
|
/tasksintegration/build
|
||||||
|
apikey.properties
|
BIN
.idea/caches/build_file_checksums.ser
generated
1
.idea/gradle.xml
generated
@ -11,6 +11,7 @@
|
|||||||
<set>
|
<set>
|
||||||
<option value="$PROJECT_DIR$" />
|
<option value="$PROJECT_DIR$" />
|
||||||
<option value="$PROJECT_DIR$/app" />
|
<option value="$PROJECT_DIR$/app" />
|
||||||
|
<option value="$PROJECT_DIR$/googlefit" />
|
||||||
<option value="$PROJECT_DIR$/tasksintegration" />
|
<option value="$PROJECT_DIR$/tasksintegration" />
|
||||||
</set>
|
</set>
|
||||||
</option>
|
</option>
|
||||||
|
1
.idea/modules.xml
generated
@ -4,6 +4,7 @@
|
|||||||
<modules>
|
<modules>
|
||||||
<module fileurl="file://$PROJECT_DIR$/Another Widget.iml" filepath="$PROJECT_DIR$/Another Widget.iml" group="Another Widget" />
|
<module fileurl="file://$PROJECT_DIR$/Another Widget.iml" filepath="$PROJECT_DIR$/Another Widget.iml" group="Another Widget" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" group="Another Widget/app" />
|
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" group="Another Widget/app" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/googlefit/googlefit.iml" filepath="$PROJECT_DIR$/googlefit/googlefit.iml" group="Another Widget/googlefit" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/tasksintegration/tasksintegration.iml" filepath="$PROJECT_DIR$/tasksintegration/tasksintegration.iml" group="Another Widget/tasksintegration" />
|
<module fileurl="file://$PROJECT_DIR$/tasksintegration/tasksintegration.iml" filepath="$PROJECT_DIR$/tasksintegration/tasksintegration.iml" group="Another Widget/tasksintegration" />
|
||||||
</modules>
|
</modules>
|
||||||
</component>
|
</component>
|
||||||
|
52
.idea/navEditor.xml
generated
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="navEditor-manualLayoutAlgorithm2">
|
||||||
|
<option name="myPositions">
|
||||||
|
<map>
|
||||||
|
<entry key="nav_graph.xml">
|
||||||
|
<value>
|
||||||
|
<LayoutPositions>
|
||||||
|
<option name="myPositions">
|
||||||
|
<map>
|
||||||
|
<entry key="appMainFragment">
|
||||||
|
<value>
|
||||||
|
<LayoutPositions>
|
||||||
|
<option name="myPosition">
|
||||||
|
<Point>
|
||||||
|
<option name="x" value="242" />
|
||||||
|
<option name="y" value="352" />
|
||||||
|
</Point>
|
||||||
|
</option>
|
||||||
|
<option name="myPositions">
|
||||||
|
<map>
|
||||||
|
<entry key="action_appMainFragment_to_appSettingsFragment">
|
||||||
|
<value>
|
||||||
|
<LayoutPositions />
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</LayoutPositions>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="appSettingsFragment">
|
||||||
|
<value>
|
||||||
|
<LayoutPositions>
|
||||||
|
<option name="myPosition">
|
||||||
|
<Point>
|
||||||
|
<option name="x" value="532" />
|
||||||
|
<option name="y" value="353" />
|
||||||
|
</Point>
|
||||||
|
</option>
|
||||||
|
</LayoutPositions>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</LayoutPositions>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -18,8 +18,8 @@ android {
|
|||||||
applicationId "com.tommasoberlose.anotherwidget"
|
applicationId "com.tommasoberlose.anotherwidget"
|
||||||
minSdkVersion 23
|
minSdkVersion 23
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
versionCode 75
|
versionCode 80
|
||||||
versionName "2.0.5"
|
versionName "2.0.6"
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
@ -53,7 +53,9 @@ android {
|
|||||||
|
|
||||||
viewBinding.enabled = true
|
viewBinding.enabled = true
|
||||||
|
|
||||||
dynamicFeatures = [":tasksintegration"]
|
dynamicFeatures = [":tasksintegration", ":googlefit"]
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -110,9 +112,6 @@ dependencies {
|
|||||||
implementation "androidx.palette:palette-ktx:1.0.0"
|
implementation "androidx.palette:palette-ktx:1.0.0"
|
||||||
implementation 'androidx.core:core-ktx:1.2.0'
|
implementation 'androidx.core:core-ktx:1.2.0'
|
||||||
|
|
||||||
// Recommended: Add the Firebase SDK for Google Analytics.
|
|
||||||
implementation 'com.google.firebase:firebase-analytics:17.4.0'
|
|
||||||
|
|
||||||
// Add the Firebase SDK for Crashlytics.
|
// Add the Firebase SDK for Crashlytics.
|
||||||
implementation 'com.google.firebase:firebase-crashlytics:17.0.0'
|
implementation 'com.google.firebase:firebase-crashlytics:17.0.0'
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
<activity android:name=".ui.activities.WeatherProviderActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
|
<activity android:name=".ui.activities.WeatherProviderActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
|
||||||
<activity android:name=".ui.activities.SupportDevActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
|
<activity android:name=".ui.activities.SupportDevActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
|
||||||
<activity android:name=".ui.activities.CustomDateActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
|
<activity android:name=".ui.activities.CustomDateActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
|
||||||
|
<activity android:name=".ui.activities.IntegrationsActivity" android:launchMode="singleInstance" android:screenOrientation="portrait" />
|
||||||
|
|
||||||
|
|
||||||
<receiver android:name=".ui.widgets.MainWidget">
|
<receiver android:name=".ui.widgets.MainWidget">
|
||||||
@ -139,6 +140,12 @@
|
|||||||
|
|
||||||
<service android:name=".services.EventListenerJob" android:permission="android.permission.BIND_JOB_SERVICE" />
|
<service android:name=".services.EventListenerJob" android:permission="android.permission.BIND_JOB_SERVICE" />
|
||||||
|
|
||||||
|
<service android:name=".receivers.MusicNotificationListener"
|
||||||
|
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.service.notification.NotificationListenerService" />
|
||||||
|
</intent-filter>
|
||||||
|
</service>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
@ -9,6 +9,7 @@ object Preferences : KotprefModel() {
|
|||||||
|
|
||||||
var darkThemePreference by intPref(default = MODE_NIGHT_FOLLOW_SYSTEM)
|
var darkThemePreference by intPref(default = MODE_NIGHT_FOLLOW_SYSTEM)
|
||||||
|
|
||||||
|
// Calendar and weather
|
||||||
var showEvents by booleanPref(key = "PREF_SHOW_EVENTS", default = false)
|
var showEvents by booleanPref(key = "PREF_SHOW_EVENTS", default = false)
|
||||||
var showWeather by booleanPref(key = "PREF_SHOW_WEATHER", default = false)
|
var showWeather by booleanPref(key = "PREF_SHOW_WEATHER", default = false)
|
||||||
var weatherIcon by stringPref(key = "PREF_WEATHER_ICON", default = "")
|
var weatherIcon by stringPref(key = "PREF_WEATHER_ICON", default = "")
|
||||||
@ -45,6 +46,10 @@ object Preferences : KotprefModel() {
|
|||||||
var backgroundCardColor by stringPref(default = "#000000")
|
var backgroundCardColor by stringPref(default = "#000000")
|
||||||
var backgroundCardAlpha by stringPref(default = "00")
|
var backgroundCardAlpha by stringPref(default = "00")
|
||||||
|
|
||||||
|
var clockTextColor by stringPref(default = "#FFFFFF")
|
||||||
|
var clockTextAlpha by stringPref(default = "FF")
|
||||||
|
|
||||||
|
// Global
|
||||||
var textMainSize by floatPref(key = "PREF_TEXT_MAIN_SIZE", default = 26f)
|
var textMainSize by floatPref(key = "PREF_TEXT_MAIN_SIZE", default = 26f)
|
||||||
var textSecondSize by floatPref(key = "PREF_TEXT_SECOND_SIZE", default = 18f)
|
var textSecondSize by floatPref(key = "PREF_TEXT_SECOND_SIZE", default = 18f)
|
||||||
var clockTextSize by floatPref(key = "PREF_TEXT_CLOCK_SIZE", default = 90f)
|
var clockTextSize by floatPref(key = "PREF_TEXT_CLOCK_SIZE", default = 90f)
|
||||||
@ -61,9 +66,21 @@ object Preferences : KotprefModel() {
|
|||||||
var customFontFile by stringPref(key = "PREF_CUSTOM_FONT_FILE")
|
var customFontFile by stringPref(key = "PREF_CUSTOM_FONT_FILE")
|
||||||
var showNextEvent by booleanPref(key = "PREF_SHOW_NEXT_EVENT", default = true)
|
var showNextEvent by booleanPref(key = "PREF_SHOW_NEXT_EVENT", default = true)
|
||||||
|
|
||||||
|
// Settings
|
||||||
var showWallpaper by booleanPref(default = true)
|
var showWallpaper by booleanPref(default = true)
|
||||||
var showBigClockWarning by booleanPref(default = true)
|
var showBigClockWarning by booleanPref(default = true)
|
||||||
var showWeatherWarning by booleanPref(default = true)
|
var showWeatherWarning by booleanPref(default = true)
|
||||||
var showPreview by booleanPref(default = true)
|
var showPreview by booleanPref(default = true)
|
||||||
var showXiaomiWarning by booleanPref(default = true)
|
var showXiaomiWarning by booleanPref(default = true)
|
||||||
|
|
||||||
|
// Music
|
||||||
|
var showMusic by booleanPref(default = false)
|
||||||
|
var mediaInfoFormat by stringPref(default = "")
|
||||||
|
var mediaPlayerTitle by stringPref(default = "")
|
||||||
|
var mediaPlayerAlbum by stringPref(default = "")
|
||||||
|
var mediaPlayerArtist by stringPref(default = "")
|
||||||
|
var mediaPlayerPackage by stringPref(default = "")
|
||||||
|
|
||||||
|
// Integrations
|
||||||
|
var installedIntegrations by intPref(default = 0)
|
||||||
}
|
}
|
||||||
|
@ -15,22 +15,43 @@ object BitmapHelper {
|
|||||||
|
|
||||||
fun getBitmapFromView(view: View, width: Int? = null, height: Int? = null, draw: Boolean = true): Bitmap {
|
fun getBitmapFromView(view: View, width: Int? = null, height: Int? = null, draw: Boolean = true): Bitmap {
|
||||||
//Define a bitmap with the same size as the view
|
//Define a bitmap with the same size as the view
|
||||||
val measuredWidth = View.MeasureSpec.makeMeasureSpec(width ?: view.width, if (width != null) View.MeasureSpec.EXACTLY else View.MeasureSpec.UNSPECIFIED)
|
val measuredWidth = View.MeasureSpec.makeMeasureSpec(width ?: view.width, if (width != null) View.MeasureSpec.EXACTLY else View.MeasureSpec.AT_MOST)
|
||||||
val measuredHeight = View.MeasureSpec.makeMeasureSpec(height ?: view.height, if (height != null) View.MeasureSpec.EXACTLY else View.MeasureSpec.UNSPECIFIED)
|
val measuredHeight = View.MeasureSpec.makeMeasureSpec(height ?: view.height, if (height != null) View.MeasureSpec.EXACTLY else View.MeasureSpec.UNSPECIFIED)
|
||||||
view.measure(measuredWidth, measuredHeight)
|
view.measure(
|
||||||
|
if (measuredWidth > 0) measuredWidth else 0,
|
||||||
|
if (measuredHeight > 0) measuredHeight else 0
|
||||||
|
)
|
||||||
|
|
||||||
|
val calculatedWidth = view.measuredWidth
|
||||||
|
val widgetWidth = if (calculatedWidth in 1..16000) {
|
||||||
|
calculatedWidth
|
||||||
|
} else if (width != null && width > 0) {
|
||||||
|
width
|
||||||
|
} else {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
val calculatedHeight = view.measuredHeight
|
||||||
|
val widgetHeight = if (calculatedHeight in 1..16000) {
|
||||||
|
calculatedHeight
|
||||||
|
} else if (height != null && height > 0) {
|
||||||
|
height
|
||||||
|
} else {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
|
||||||
if (draw) {
|
if (draw) {
|
||||||
FirebaseCrashlytics.getInstance().setCustomKey("measuredWidth", view.measuredWidth)
|
FirebaseCrashlytics.getInstance().setCustomKey("WIDTH SPEC", measuredWidth)
|
||||||
FirebaseCrashlytics.getInstance().setCustomKey("measuredWidth_spec", measuredWidth)
|
FirebaseCrashlytics.getInstance().setCustomKey("HEIGHT SPEC", measuredHeight)
|
||||||
FirebaseCrashlytics.getInstance().setCustomKey("measuredHeight", view.measuredHeight)
|
FirebaseCrashlytics.getInstance().setCustomKey("VIEW measuredWidth", view.measuredWidth)
|
||||||
FirebaseCrashlytics.getInstance()
|
FirebaseCrashlytics.getInstance().setCustomKey("VIEW measuredHeight", view.measuredHeight)
|
||||||
.setCustomKey("measuredHeight_spec", measuredHeight)
|
FirebaseCrashlytics.getInstance().setCustomKey("WIDGET final width", measuredWidth)
|
||||||
|
FirebaseCrashlytics.getInstance().setCustomKey("WIDGET final height", view.measuredHeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
val btm = Bitmap.createBitmap(
|
val btm = Bitmap.createBitmap(
|
||||||
view.measuredWidth,
|
widgetWidth,
|
||||||
view.measuredHeight,
|
widgetHeight,
|
||||||
if (draw) Bitmap.Config.ARGB_8888 else Bitmap.Config.ALPHA_8
|
if (draw) Bitmap.Config.ARGB_8888 else Bitmap.Config.ALPHA_8
|
||||||
)
|
)
|
||||||
if (draw) {
|
if (draw) {
|
||||||
|
@ -4,13 +4,12 @@ import android.Manifest
|
|||||||
import android.content.ContentUris
|
import android.content.ContentUris
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.provider.CalendarContract
|
import android.provider.CalendarContract
|
||||||
import android.util.Log
|
|
||||||
import com.tommasoberlose.anotherwidget.services.EventListenerJob
|
import com.tommasoberlose.anotherwidget.services.EventListenerJob
|
||||||
import com.tommasoberlose.anotherwidget.db.EventRepository
|
import com.tommasoberlose.anotherwidget.db.EventRepository
|
||||||
import com.tommasoberlose.anotherwidget.models.Event
|
import com.tommasoberlose.anotherwidget.models.Event
|
||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
|
import com.tommasoberlose.anotherwidget.receivers.UpdatesReceiver
|
||||||
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
|
import com.tommasoberlose.anotherwidget.ui.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
|
||||||
import me.everything.providers.android.calendar.CalendarProvider
|
import me.everything.providers.android.calendar.CalendarProvider
|
||||||
@ -127,7 +126,7 @@ object CalendarHelper {
|
|||||||
UpdatesReceiver.setUpdates(context)
|
UpdatesReceiver.setUpdates(context)
|
||||||
MainWidget.updateWidget(context)
|
MainWidget.updateWidget(context)
|
||||||
|
|
||||||
EventBus.getDefault().post(MainActivity.UpdateUiMessageEvent())
|
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCalendarList(context: Context): List<me.everything.providers.android.calendar.Calendar> {
|
fun getCalendarList(context: Context): List<me.everything.providers.android.calendar.Calendar> {
|
||||||
|
@ -30,6 +30,29 @@ object ColorHelper {
|
|||||||
Color.parseColor("#000000")
|
Color.parseColor("#000000")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fun getClockFontColor(): Int {
|
||||||
|
return try {
|
||||||
|
Color.parseColor("#%s%s".format(Preferences.clockTextAlpha, Preferences.clockTextColor.replace("#", "")))
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Color.parseColor("#FFFFFFFF")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getClockFontColorAlpha(): Int {
|
||||||
|
return try {
|
||||||
|
Preferences.clockTextAlpha.toIntValue().toDouble() * 255 / 100
|
||||||
|
} catch (e: Exception) {
|
||||||
|
"FF".toIntValue().toDouble() * 255 / 100
|
||||||
|
}.roundToInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getClockFontColorRgb(): Int {
|
||||||
|
return try {
|
||||||
|
Color.parseColor(Preferences.clockTextColor)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Color.parseColor("#000000")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getBackgroundColor(): Int {
|
fun getBackgroundColor(): Int {
|
||||||
return try {
|
return try {
|
||||||
|
@ -160,4 +160,22 @@ object IntentHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getMusicIntent(context: Context): Intent {
|
||||||
|
return when (Preferences.mediaPlayerPackage) {
|
||||||
|
"" -> {
|
||||||
|
Intent()
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
val pm: PackageManager = context.packageManager
|
||||||
|
try {
|
||||||
|
pm.getLaunchIntentForPackage(Preferences.mediaPlayerPackage)!!.apply {
|
||||||
|
addCategory(Intent.CATEGORY_LAUNCHER)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Intent()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
package com.tommasoberlose.anotherwidget.helpers
|
||||||
|
|
||||||
|
import android.app.Notification
|
||||||
|
import android.content.ComponentName
|
||||||
|
import android.content.Context
|
||||||
|
import android.media.MediaMetadata
|
||||||
|
import android.media.session.MediaController
|
||||||
|
import android.media.session.MediaSession
|
||||||
|
import android.media.session.MediaSessionManager
|
||||||
|
import android.media.session.PlaybackState
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import com.chibatching.kotpref.bulk
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
|
import com.tommasoberlose.anotherwidget.receivers.MusicNotificationListener
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||||
|
import java.lang.Exception
|
||||||
|
|
||||||
|
object MediaPlayerHelper {
|
||||||
|
fun isSomeonePlaying(context: Context) = Preferences.showMusic && NotificationManagerCompat.getEnabledListenerPackages(context).contains(context.packageName) && Preferences.mediaPlayerTitle != ""
|
||||||
|
|
||||||
|
fun getMediaInfo(): String {
|
||||||
|
return if (Preferences.mediaPlayerArtist == "") {
|
||||||
|
Preferences.mediaPlayerTitle
|
||||||
|
} else {
|
||||||
|
"%s, %s".format(Preferences.mediaPlayerTitle, Preferences.mediaPlayerArtist)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updatePlayingMediaInfo(context: Context) {
|
||||||
|
if (NotificationManagerCompat.getEnabledListenerPackages(context).contains(context.packageName)) {
|
||||||
|
val list = try {
|
||||||
|
(context.getSystemService(Context.MEDIA_SESSION_SERVICE) as MediaSessionManager).getActiveSessions(
|
||||||
|
ComponentName(context.packageName, MusicNotificationListener::class.java.name)
|
||||||
|
)
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
emptyList<MediaController>()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list.isNotEmpty()) {
|
||||||
|
var isSomeonePlaying = false
|
||||||
|
list.forEach { mc ->
|
||||||
|
val metadata = mc.metadata
|
||||||
|
val isPlaying =
|
||||||
|
mc.playbackState?.state == PlaybackState.STATE_PLAYING || mc.playbackState?.state == PlaybackState.STATE_CONNECTING
|
||||||
|
|
||||||
|
if (isPlaying) {
|
||||||
|
isSomeonePlaying = true
|
||||||
|
if (metadata != null) {
|
||||||
|
Preferences.bulk {
|
||||||
|
mediaPlayerTitle =
|
||||||
|
metadata.getText(MediaMetadata.METADATA_KEY_TITLE)?.toString()
|
||||||
|
?: ""
|
||||||
|
mediaPlayerArtist =
|
||||||
|
metadata.getText(MediaMetadata.METADATA_KEY_ARTIST)?.toString()
|
||||||
|
?: ""
|
||||||
|
mediaPlayerAlbum =
|
||||||
|
metadata.getText(MediaMetadata.METADATA_KEY_ALBUM)?.toString()
|
||||||
|
?: ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Preferences.mediaPlayerPackage = mc.packageName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isSomeonePlaying) {
|
||||||
|
removeMediaInfo()
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
removeMediaInfo()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
removeMediaInfo()
|
||||||
|
}
|
||||||
|
MainWidget.updateWidget(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun removeMediaInfo() {
|
||||||
|
Preferences.bulk {
|
||||||
|
remove(Preferences::mediaPlayerTitle)
|
||||||
|
remove(Preferences::mediaPlayerArtist)
|
||||||
|
remove(Preferences::mediaPlayerAlbum)
|
||||||
|
remove(Preferences::mediaPlayerPackage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -39,7 +39,6 @@ object SettingsStringHelper {
|
|||||||
return when (info) {
|
return when (info) {
|
||||||
0 -> R.string.settings_second_row_info_subtitle_0
|
0 -> R.string.settings_second_row_info_subtitle_0
|
||||||
1 -> R.string.settings_second_row_info_subtitle_1
|
1 -> R.string.settings_second_row_info_subtitle_1
|
||||||
2 -> R.string.settings_second_row_info_subtitle_2
|
|
||||||
else -> R.string.settings_second_row_info_subtitle_0
|
else -> R.string.settings_second_row_info_subtitle_0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,17 +3,12 @@ package com.tommasoberlose.anotherwidget.helpers
|
|||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.util.EventLog
|
|
||||||
import android.util.Log
|
|
||||||
import com.google.android.gms.location.LocationServices
|
import com.google.android.gms.location.LocationServices
|
||||||
import com.kwabenaberko.openweathermaplib.constants.Units
|
|
||||||
import com.kwabenaberko.openweathermaplib.implementation.OpenWeatherMapHelper
|
|
||||||
import com.kwabenaberko.openweathermaplib.implementation.callbacks.CurrentWeatherCallback
|
|
||||||
import com.kwabenaberko.openweathermaplib.models.currentweather.CurrentWeather
|
|
||||||
import com.tommasoberlose.anotherwidget.R
|
import com.tommasoberlose.anotherwidget.R
|
||||||
|
import com.tommasoberlose.anotherwidget.db.EventRepository
|
||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.network.WeatherNetworkApi
|
import com.tommasoberlose.anotherwidget.network.WeatherNetworkApi
|
||||||
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
|
import com.tommasoberlose.anotherwidget.ui.fragments.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
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
@ -38,7 +33,7 @@ object WeatherHelper {
|
|||||||
Preferences.customLocationLon = location.longitude.toString()
|
Preferences.customLocationLon = location.longitude.toString()
|
||||||
|
|
||||||
networkApi.updateWeather()
|
networkApi.updateWeather()
|
||||||
EventBus.getDefault().post(MainActivity.UpdateUiMessageEvent())
|
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,9 @@ package com.tommasoberlose.anotherwidget.helpers
|
|||||||
import android.appwidget.AppWidgetManager
|
import android.appwidget.AppWidgetManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.Configuration.ORIENTATION_PORTRAIT
|
import android.content.res.Configuration.ORIENTATION_PORTRAIT
|
||||||
|
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||||
|
import com.tommasoberlose.anotherwidget.db.EventRepository
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
|
|
||||||
object WidgetHelper {
|
object WidgetHelper {
|
||||||
class WidgetSizeProvider(
|
class WidgetSizeProvider(
|
||||||
@ -16,6 +19,8 @@ object WidgetHelper {
|
|||||||
val height = getWidgetHeight(isPortrait, widgetId)
|
val height = getWidgetHeight(isPortrait, widgetId)
|
||||||
val widthInPx = context.dip(width)
|
val widthInPx = context.dip(width)
|
||||||
val heightInPx = context.dip(height)
|
val heightInPx = context.dip(height)
|
||||||
|
FirebaseCrashlytics.getInstance().setCustomKey("widthInPx", widthInPx)
|
||||||
|
FirebaseCrashlytics.getInstance().setCustomKey("heightInPx", heightInPx)
|
||||||
return widthInPx to heightInPx
|
return widthInPx to heightInPx
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,4 +53,11 @@ object WidgetHelper {
|
|||||||
width to second * factor
|
width to second * factor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun showSpecialWeather(context: Context): Boolean {
|
||||||
|
return EventRepository(context).getEventsCount() == 0 && (
|
||||||
|
(Preferences.showNextAlarm && AlarmHelper.getNextAlarm(context) != "") ||
|
||||||
|
(MediaPlayerHelper.isSomeonePlaying(context))
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,14 +1,13 @@
|
|||||||
package com.tommasoberlose.anotherwidget.network
|
package com.tommasoberlose.anotherwidget.network
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.Log
|
|
||||||
import com.kwabenaberko.openweathermaplib.constants.Units
|
import com.kwabenaberko.openweathermaplib.constants.Units
|
||||||
import com.kwabenaberko.openweathermaplib.implementation.OpenWeatherMapHelper
|
import com.kwabenaberko.openweathermaplib.implementation.OpenWeatherMapHelper
|
||||||
import com.kwabenaberko.openweathermaplib.implementation.callbacks.CurrentWeatherCallback
|
import com.kwabenaberko.openweathermaplib.implementation.callbacks.CurrentWeatherCallback
|
||||||
import com.kwabenaberko.openweathermaplib.models.currentweather.CurrentWeather
|
import com.kwabenaberko.openweathermaplib.models.currentweather.CurrentWeather
|
||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
|
import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
|
||||||
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
|
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
|
||||||
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
|
||||||
@ -26,7 +25,7 @@ class WeatherNetworkApi(val context: Context) {
|
|||||||
Preferences.weatherRealTempUnit = Preferences.weatherTempUnit
|
Preferences.weatherRealTempUnit = Preferences.weatherTempUnit
|
||||||
MainWidget.updateWidget(context)
|
MainWidget.updateWidget(context)
|
||||||
|
|
||||||
EventBus.getDefault().post(MainActivity.UpdateUiMessageEvent())
|
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.tommasoberlose.anotherwidget.receivers
|
||||||
|
|
||||||
|
import android.app.Notification
|
||||||
|
import android.media.MediaMetadata
|
||||||
|
import android.media.session.MediaController
|
||||||
|
import android.media.session.MediaSession
|
||||||
|
import android.media.session.PlaybackState
|
||||||
|
import android.service.notification.NotificationListenerService
|
||||||
|
import android.service.notification.StatusBarNotification
|
||||||
|
import android.util.Log
|
||||||
|
import com.chibatching.kotpref.bulk
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.WidgetHelper
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||||
|
|
||||||
|
|
||||||
|
class MusicNotificationListener : NotificationListenerService() {
|
||||||
|
override fun onListenerConnected() {
|
||||||
|
MediaPlayerHelper.updatePlayingMediaInfo(this)
|
||||||
|
super.onListenerConnected()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNotificationPosted(sbn: StatusBarNotification?) {
|
||||||
|
sbn?.notification?.extras?.let { bundle ->
|
||||||
|
bundle.getParcelable<MediaSession.Token>(Notification.EXTRA_MEDIA_SESSION)?.let {
|
||||||
|
MediaPlayerHelper.updatePlayingMediaInfo(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.onNotificationPosted(sbn)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNotificationRemoved(sbn: StatusBarNotification?) {
|
||||||
|
MediaPlayerHelper.updatePlayingMediaInfo(this)
|
||||||
|
super.onNotificationRemoved(sbn)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package com.tommasoberlose.anotherwidget.ui.activities
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.databinding.DataBindingUtil
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import com.tommasoberlose.anotherwidget.R
|
||||||
|
import com.tommasoberlose.anotherwidget.databinding.ActivityIntegrationsBinding
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.viewmodels.IntegrationsViewModel
|
||||||
|
import kotlinx.android.synthetic.main.activity_integrations.*
|
||||||
|
import net.idik.lib.slimadapter.SlimAdapter
|
||||||
|
|
||||||
|
class IntegrationsActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
private lateinit var adapter: SlimAdapter
|
||||||
|
private lateinit var viewModel: IntegrationsViewModel
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
viewModel = ViewModelProvider(this).get(IntegrationsViewModel::class.java)
|
||||||
|
val binding = DataBindingUtil.setContentView<ActivityIntegrationsBinding>(this, R.layout.activity_integrations)
|
||||||
|
|
||||||
|
list_view.setHasFixedSize(true)
|
||||||
|
val mLayoutManager = LinearLayoutManager(this)
|
||||||
|
list_view.layoutManager = mLayoutManager
|
||||||
|
|
||||||
|
adapter = SlimAdapter.create()
|
||||||
|
adapter
|
||||||
|
.register<String>(R.layout.application_info_layout) { _, injector ->
|
||||||
|
injector
|
||||||
|
.text(R.id.text, getString(R.string.default_name))
|
||||||
|
|
||||||
|
}
|
||||||
|
.attachTo(list_view)
|
||||||
|
|
||||||
|
setupListener()
|
||||||
|
subscribeUi(binding, viewModel)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun subscribeUi(binding: ActivityIntegrationsBinding, viewModel: IntegrationsViewModel) {
|
||||||
|
binding.viewModel = viewModel
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupListener() {
|
||||||
|
action_back.setOnClickListener {
|
||||||
|
onBackPressed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -24,8 +24,15 @@ import androidx.core.view.isVisible
|
|||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import androidx.navigation.Navigation
|
||||||
import com.google.android.material.badge.BadgeDrawable
|
import com.google.android.material.badge.BadgeDrawable
|
||||||
import com.google.android.material.tabs.TabLayoutMediator
|
import com.google.android.material.tabs.TabLayoutMediator
|
||||||
|
import com.karumi.dexter.Dexter
|
||||||
|
import com.karumi.dexter.MultiplePermissionsReport
|
||||||
|
import com.karumi.dexter.PermissionToken
|
||||||
|
import com.karumi.dexter.listener.PermissionRequest
|
||||||
|
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
|
||||||
import com.tommasoberlose.anotherwidget.R
|
import com.tommasoberlose.anotherwidget.R
|
||||||
import com.tommasoberlose.anotherwidget.components.MaterialBottomSheetDialog
|
import com.tommasoberlose.anotherwidget.components.MaterialBottomSheetDialog
|
||||||
import com.tommasoberlose.anotherwidget.global.Actions
|
import com.tommasoberlose.anotherwidget.global.Actions
|
||||||
@ -50,10 +57,16 @@ import org.greenrobot.eventbus.Subscribe
|
|||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
|
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceChangeListener {
|
class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private var mAppWidgetId: Int = -1
|
private var mAppWidgetId: Int = -1
|
||||||
private lateinit var viewModel: MainViewModel
|
private lateinit var viewModel: MainViewModel
|
||||||
|
private val mainNavController: NavController? by lazy {
|
||||||
|
Navigation.findNavController(
|
||||||
|
this,
|
||||||
|
R.id.content_fragment
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@ -62,236 +75,20 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
|
|||||||
viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
|
viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
|
||||||
|
|
||||||
controlExtras(intent)
|
controlExtras(intent)
|
||||||
|
requirePermission()
|
||||||
// Viewpager
|
|
||||||
pager.adapter = ViewPagerAdapter(this)
|
|
||||||
pager.offscreenPageLimit = 4
|
|
||||||
TabLayoutMediator(tabs, pager) { tab, position ->
|
|
||||||
tab.text = when (position) {
|
|
||||||
0 -> getString(R.string.settings_general_title)
|
|
||||||
1 -> getString(R.string.settings_calendar_title)
|
|
||||||
2 -> getString(R.string.settings_weather_title)
|
|
||||||
3 -> getString(R.string.settings_clock_title)
|
|
||||||
4 -> getString(R.string.advanced_settings_title)
|
|
||||||
else -> ""
|
|
||||||
}
|
|
||||||
}.attach()
|
|
||||||
|
|
||||||
// Init clock
|
|
||||||
time.setTextColor(ColorHelper.getFontColor())
|
|
||||||
time.setTextSize(TypedValue.COMPLEX_UNIT_SP, Preferences.clockTextSize.toPixel(this@MainActivity))
|
|
||||||
time_am_pm.setTextColor(ColorHelper.getFontColor())
|
|
||||||
time_am_pm.setTextSize(TypedValue.COMPLEX_UNIT_SP, Preferences.clockTextSize.toPixel(this@MainActivity) / 5 * 2)
|
|
||||||
time_container.isVisible = Preferences.showClock
|
|
||||||
|
|
||||||
preview.layoutParams = preview.layoutParams.apply {
|
|
||||||
height = 160.toPixel(this@MainActivity) + if (Preferences.showClock) 100.toPixel(this@MainActivity) else 0
|
|
||||||
}
|
|
||||||
|
|
||||||
Preferences.preferences.registerOnSharedPreferenceChangeListener(this)
|
|
||||||
subscribeUi(viewModel)
|
|
||||||
updateUI()
|
|
||||||
|
|
||||||
// Warnings
|
|
||||||
if (getString(R.string.xiaomi_manufacturer).equals(Build.MANUFACTURER, ignoreCase = true) && Preferences.showXiaomiWarning) {
|
|
||||||
MaterialBottomSheetDialog(this, getString(R.string.xiaomi_warning_title), getString(R.string.xiaomi_warning_message))
|
|
||||||
.setNegativeButton(getString(R.string.action_ignore)) {
|
|
||||||
Preferences.showXiaomiWarning = false
|
|
||||||
}
|
|
||||||
.setPositiveButton(getString(R.string.action_grant_permission)) {
|
|
||||||
Preferences.showXiaomiWarning = false
|
|
||||||
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
|
|
||||||
data = Uri.parse("package:$packageName")
|
|
||||||
}
|
|
||||||
startActivity(intent)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private var uiJob: Job? = null
|
|
||||||
|
|
||||||
private fun updateUI() {
|
|
||||||
uiJob?.cancel()
|
|
||||||
|
|
||||||
if (Preferences.showPreview) {
|
|
||||||
preview.setCardBackgroundColor(
|
|
||||||
getColor(
|
|
||||||
if (ColorHelper.getFontColor()
|
|
||||||
.isColorDark()
|
|
||||||
) android.R.color.white else R.color.colorAccent
|
|
||||||
)
|
|
||||||
)
|
|
||||||
widget_shape_background.setImageDrawable(BitmapHelper.getTintedDrawable(this, R.drawable.card_background, ColorHelper.getBackgroundColor()))
|
|
||||||
uiJob = lifecycleScope.launch(Dispatchers.IO) {
|
|
||||||
delay(200)
|
|
||||||
val generatedView = MainWidget.generateWidgetView(this@MainActivity)
|
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
generatedView.measure(0, 0)
|
|
||||||
preview.measure(0, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
val bitmap = BitmapHelper.getBitmapFromView(
|
|
||||||
generatedView,
|
|
||||||
if (preview.width > 0) preview.width else generatedView.measuredWidth,
|
|
||||||
generatedView.measuredHeight
|
|
||||||
)
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
// Clock
|
|
||||||
time.setTextColor(ColorHelper.getFontColor())
|
|
||||||
time_am_pm.setTextColor(ColorHelper.getFontColor())
|
|
||||||
time.setTextSize(
|
|
||||||
TypedValue.COMPLEX_UNIT_SP,
|
|
||||||
Preferences.clockTextSize.toPixel(this@MainActivity)
|
|
||||||
)
|
|
||||||
time_am_pm.setTextSize(
|
|
||||||
TypedValue.COMPLEX_UNIT_SP,
|
|
||||||
Preferences.clockTextSize.toPixel(this@MainActivity) / 5 * 2
|
|
||||||
)
|
|
||||||
|
|
||||||
// Clock bottom margin
|
|
||||||
clock_bottom_margin_none.isVisible =
|
|
||||||
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.NONE.value
|
|
||||||
clock_bottom_margin_small.isVisible =
|
|
||||||
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.SMALL.value
|
|
||||||
clock_bottom_margin_medium.isVisible =
|
|
||||||
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.MEDIUM.value
|
|
||||||
clock_bottom_margin_large.isVisible =
|
|
||||||
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.LARGE.value
|
|
||||||
|
|
||||||
if ((Preferences.showClock && !time_container.isVisible) || (!Preferences.showClock && time_container.isVisible)) {
|
|
||||||
if (Preferences.showClock) {
|
|
||||||
time_container.layoutParams = time_container.layoutParams.apply {
|
|
||||||
height = RelativeLayout.LayoutParams.WRAP_CONTENT
|
|
||||||
}
|
|
||||||
time_container.measure(0, 0)
|
|
||||||
}
|
|
||||||
val initialHeight = time_container.measuredHeight
|
|
||||||
ValueAnimator.ofFloat(
|
|
||||||
if (Preferences.showClock) 0f else 1f,
|
|
||||||
if (Preferences.showClock) 1f else 0f
|
|
||||||
).apply {
|
|
||||||
duration = 500L
|
|
||||||
addUpdateListener {
|
|
||||||
val animatedValue = animatedValue as Float
|
|
||||||
time_container.layoutParams = time_container.layoutParams.apply {
|
|
||||||
height = (initialHeight * animatedValue).toInt()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
addListener(
|
|
||||||
onStart = {
|
|
||||||
if (Preferences.showClock) {
|
|
||||||
time_container.isVisible = true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onEnd = {
|
|
||||||
if (!Preferences.showClock) {
|
|
||||||
time_container.isVisible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}.start()
|
|
||||||
|
|
||||||
ValueAnimator.ofInt(
|
|
||||||
preview.height,
|
|
||||||
160.toPixel(this@MainActivity) + if (Preferences.showClock) 100.toPixel(
|
|
||||||
this@MainActivity
|
|
||||||
) else 0
|
|
||||||
).apply {
|
|
||||||
duration = 500L
|
|
||||||
addUpdateListener {
|
|
||||||
val animatedValue = animatedValue as Int
|
|
||||||
val layoutParams = preview.layoutParams
|
|
||||||
layoutParams.height = animatedValue
|
|
||||||
preview.layoutParams = layoutParams
|
|
||||||
}
|
|
||||||
}.start()
|
|
||||||
} else {
|
|
||||||
time_container.layoutParams = time_container.layoutParams.apply {
|
|
||||||
height = RelativeLayout.LayoutParams.WRAP_CONTENT
|
|
||||||
}
|
|
||||||
time_container.measure(0, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (preview.height == 0) {
|
|
||||||
ValueAnimator.ofInt(
|
|
||||||
preview.height,
|
|
||||||
160.toPixel(this@MainActivity) + if (Preferences.showClock) 100.toPixel(
|
|
||||||
this@MainActivity
|
|
||||||
) else 0
|
|
||||||
).apply {
|
|
||||||
duration = 300L
|
|
||||||
addUpdateListener {
|
|
||||||
val animatedValue = animatedValue as Int
|
|
||||||
val layoutParams = preview.layoutParams
|
|
||||||
layoutParams.height = animatedValue
|
|
||||||
preview.layoutParams = layoutParams
|
|
||||||
}
|
|
||||||
}.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
bitmap_container.setImageBitmap(bitmap)
|
|
||||||
widget_loader.animate().scaleX(0f).scaleY(0f).start()
|
|
||||||
widget.animate().alpha(1f).start()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ValueAnimator.ofInt(
|
|
||||||
preview.height,
|
|
||||||
0
|
|
||||||
).apply {
|
|
||||||
duration = 300L
|
|
||||||
addUpdateListener {
|
|
||||||
val animatedValue = animatedValue as Int
|
|
||||||
val layoutParams = preview.layoutParams
|
|
||||||
layoutParams.height = animatedValue
|
|
||||||
preview.layoutParams = layoutParams
|
|
||||||
}
|
|
||||||
}.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Calendar error indicator
|
|
||||||
tabs.getTabAt(1)?.orCreateBadge?.apply {
|
|
||||||
backgroundColor = ContextCompat.getColor(this@MainActivity, R.color.errorColorText)
|
|
||||||
badgeGravity = BadgeDrawable.TOP_END
|
|
||||||
}?.isVisible = Preferences.showEvents && !checkGrantedPermission(Manifest.permission.READ_CALENDAR)
|
|
||||||
|
|
||||||
// Weather error indicator
|
|
||||||
tabs.getTabAt(2)?.orCreateBadge?.apply {
|
|
||||||
backgroundColor = ContextCompat.getColor(this@MainActivity, R.color.errorColorText)
|
|
||||||
badgeGravity = BadgeDrawable.TOP_END
|
|
||||||
}?.isVisible = Preferences.showWeather && (Preferences.weatherProviderApi == "" || (Preferences.customLocationAdd == "" && !checkGrantedPermission(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION)))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun subscribeUi(viewModel: MainViewModel) {
|
|
||||||
viewModel.showWallpaper.observe(this, Observer {
|
|
||||||
val wallpaper = getCurrentWallpaper()
|
|
||||||
widget_bg.setImageDrawable(if (it) wallpaper else null)
|
|
||||||
widget_bg.layoutParams = widget_bg.layoutParams.apply {
|
|
||||||
|
|
||||||
val metrics = DisplayMetrics()
|
|
||||||
windowManager.defaultDisplay.getMetrics(metrics)
|
|
||||||
|
|
||||||
height = metrics.heightPixels
|
|
||||||
width = (wallpaper?.intrinsicWidth ?: 1) * metrics.heightPixels / (wallpaper?.intrinsicWidth ?: 1)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
logo.setOnClickListener {
|
|
||||||
// startActivity(Intent(this, SupportDevActivity::class.java))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
|
if (mainNavController?.currentDestination?.id == R.id.appMainFragment) {
|
||||||
if (mAppWidgetId > 0) {
|
if (mAppWidgetId > 0) {
|
||||||
addNewWidget()
|
addNewWidget()
|
||||||
} else {
|
} else {
|
||||||
setResult(Activity.RESULT_OK)
|
setResult(Activity.RESULT_OK)
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
super.onBackPressed()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNewIntent(intent: Intent?) {
|
override fun onNewIntent(intent: Intent?) {
|
||||||
@ -330,30 +127,27 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
|
|||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
private fun requirePermission() {
|
||||||
super.onDestroy()
|
Dexter.withContext(this)
|
||||||
Preferences.preferences.unregisterOnSharedPreferenceChangeListener(this)
|
.withPermissions(
|
||||||
|
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||||
|
).withListener(object : MultiplePermissionsListener {
|
||||||
|
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
|
||||||
|
report?.let {
|
||||||
|
Preferences.showWallpaper = false
|
||||||
|
Preferences.showWallpaper = report.areAllPermissionsGranted()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSharedPreferenceChanged(preferences: SharedPreferences, p1: String) {
|
override fun onPermissionRationaleShouldBeShown(
|
||||||
updateUI()
|
permissions: MutableList<PermissionRequest>?,
|
||||||
MainWidget.updateWidget(this)
|
token: PermissionToken?
|
||||||
|
) {
|
||||||
|
// Remember to invoke this method when the custom rationale is closed
|
||||||
|
// or just by default if you don't want to use any custom rationale.
|
||||||
|
token?.cancelPermissionRequest()
|
||||||
}
|
}
|
||||||
|
})
|
||||||
override fun onStart() {
|
.check()
|
||||||
super.onStart()
|
|
||||||
EventBus.getDefault().register(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStop() {
|
|
||||||
super.onStop()
|
|
||||||
EventBus.getDefault().unregister(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
class UpdateUiMessageEvent
|
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
|
||||||
fun onMessageEvent(ignore: UpdateUiMessageEvent?) {
|
|
||||||
updateUI()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,11 +12,11 @@ class ViewPagerAdapter(fragmentActivity: FragmentActivity) :
|
|||||||
|
|
||||||
override fun createFragment(position: Int): Fragment {
|
override fun createFragment(position: Int): Fragment {
|
||||||
return when (position) {
|
return when (position) {
|
||||||
1 -> CalendarSettingsFragment.newInstance()
|
1 -> CalendarTabFragment.newInstance()
|
||||||
2 -> WeatherSettingsFragment.newInstance()
|
2 -> WeatherTabFragment.newInstance()
|
||||||
3 -> ClockSettingsFragment.newInstance()
|
3 -> ClockTabFragment.newInstance()
|
||||||
4 -> AdvancedSettingsFragment.newInstance()
|
4 -> AtAGlanceTabFragment.newInstance()
|
||||||
else -> GeneralSettingsFragment.newInstance()
|
else -> GeneralTabFragment.newInstance()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,165 @@
|
|||||||
|
package com.tommasoberlose.anotherwidget.ui.fragments
|
||||||
|
|
||||||
|
import android.app.AlarmManager
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.IntentFilter
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.databinding.DataBindingUtil
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.Observer
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import com.tommasoberlose.anotherwidget.R
|
||||||
|
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
|
||||||
|
import com.tommasoberlose.anotherwidget.databinding.FragmentAtAGlanceSettingsBinding
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.AlarmHelper
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
|
||||||
|
import kotlinx.android.synthetic.main.fragment_at_a_glance_settings.*
|
||||||
|
import kotlinx.android.synthetic.main.fragment_at_a_glance_settings.scrollView
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import java.lang.Exception
|
||||||
|
|
||||||
|
class AtAGlanceTabFragment : Fragment() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun newInstance() = AtAGlanceTabFragment()
|
||||||
|
}
|
||||||
|
|
||||||
|
private lateinit var viewModel: MainViewModel
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
|
||||||
|
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
|
||||||
|
val binding = DataBindingUtil.inflate<FragmentAtAGlanceSettingsBinding>(inflater, R.layout.fragment_at_a_glance_settings, container, false)
|
||||||
|
|
||||||
|
subscribeUi(binding, viewModel)
|
||||||
|
|
||||||
|
binding.lifecycleOwner = this
|
||||||
|
binding.viewModel = viewModel
|
||||||
|
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
|
||||||
|
setupListener()
|
||||||
|
updateNextAlarmWarningUi()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun subscribeUi(
|
||||||
|
binding: FragmentAtAGlanceSettingsBinding,
|
||||||
|
viewModel: MainViewModel
|
||||||
|
) {
|
||||||
|
|
||||||
|
viewModel.showMusic.observe(viewLifecycleOwner, Observer {
|
||||||
|
checkNotificationPermission()
|
||||||
|
})
|
||||||
|
|
||||||
|
viewModel.showNextAlarm.observe(viewLifecycleOwner, Observer {
|
||||||
|
updateNextAlarmWarningUi()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupListener() {
|
||||||
|
action_show_music.setOnClickListener {
|
||||||
|
Preferences.showMusic = !Preferences.showMusic
|
||||||
|
}
|
||||||
|
|
||||||
|
action_show_next_alarm.setOnClickListener {
|
||||||
|
BottomSheetMenu<Boolean>(requireContext(), header = getString(R.string.settings_show_next_alarm_title)).setSelectedValue(Preferences.showNextAlarm)
|
||||||
|
.addItem(getString(R.string.settings_visible), true)
|
||||||
|
.addItem(getString(R.string.settings_not_visible), false)
|
||||||
|
.addOnSelectItemListener { value ->
|
||||||
|
Preferences.showNextAlarm = value
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateNextAlarmWarningUi() {
|
||||||
|
with(requireContext().getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
|
||||||
|
val alarm = nextAlarmClock
|
||||||
|
if (AlarmHelper.isAlarmProbablyWrong(requireContext()) && alarm != null && alarm.showIntent != null) {
|
||||||
|
val pm = requireContext().packageManager as PackageManager
|
||||||
|
val appNameOrPackage = try {
|
||||||
|
pm.getApplicationLabel(pm.getApplicationInfo(alarm.showIntent?.creatorPackage ?: "", 0))
|
||||||
|
} catch (e: Exception) {
|
||||||
|
alarm.showIntent?.creatorPackage ?: ""
|
||||||
|
}
|
||||||
|
show_next_alarm_warning.text = getString(R.string.next_alarm_warning).format(appNameOrPackage)
|
||||||
|
} else {
|
||||||
|
maintainScrollPosition {
|
||||||
|
show_next_alarm_label?.text = if (Preferences.showNextAlarm) getString(R.string.settings_visible) else getString(
|
||||||
|
R.string.settings_not_visible)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val nextAlarmChangeBroadcastReceiver = object : BroadcastReceiver() {
|
||||||
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
|
updateNextAlarmWarningUi()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
activity?.registerReceiver(nextAlarmChangeBroadcastReceiver, IntentFilter(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
activity?.unregisterReceiver(nextAlarmChangeBroadcastReceiver)
|
||||||
|
super.onStop()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkNotificationPermission() {
|
||||||
|
if (NotificationManagerCompat.getEnabledListenerPackages(requireContext()).contains(requireContext().packageName)) {
|
||||||
|
notification_permission_alert?.isVisible = false
|
||||||
|
MediaPlayerHelper.updatePlayingMediaInfo(requireContext())
|
||||||
|
show_music_label?.text = if (Preferences.showMusic) getString(R.string.settings_show_music_enabled_subtitle) else getString(R.string.settings_show_music_disabled_subtitle)
|
||||||
|
} else if (Preferences.showMusic) {
|
||||||
|
notification_permission_alert?.isVisible = true
|
||||||
|
show_music_label?.text = getString(R.string.settings_request_notification_access)
|
||||||
|
notification_permission_alert?.setOnClickListener {
|
||||||
|
activity?.startActivity(Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
show_music_label?.text = getString(R.string.settings_show_music_disabled_subtitle)
|
||||||
|
notification_permission_alert?.isVisible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun maintainScrollPosition(callback: () -> Unit) {
|
||||||
|
val scrollPosition = scrollView.scrollY
|
||||||
|
callback.invoke()
|
||||||
|
lifecycleScope.launch {
|
||||||
|
delay(200)
|
||||||
|
scrollView.smoothScrollTo(0, scrollPosition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
checkNotificationPermission()
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,6 @@ import android.os.Bundle
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.databinding.DataBindingUtil
|
import androidx.databinding.DataBindingUtil
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
@ -43,10 +42,10 @@ import kotlinx.coroutines.launch
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.Comparator
|
import kotlin.Comparator
|
||||||
|
|
||||||
class CalendarSettingsFragment : Fragment() {
|
class CalendarTabFragment : Fragment() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun newInstance() = CalendarSettingsFragment()
|
fun newInstance() = CalendarTabFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var viewModel: MainViewModel
|
private lateinit var viewModel: MainViewModel
|
||||||
@ -271,7 +270,7 @@ class CalendarSettingsFragment : Fragment() {
|
|||||||
action_show_until.setOnClickListener {
|
action_show_until.setOnClickListener {
|
||||||
if (Preferences.showEvents) {
|
if (Preferences.showEvents) {
|
||||||
val dialog = BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_show_until_title)).setSelectedValue(Preferences.showUntil)
|
val dialog = BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_show_until_title)).setSelectedValue(Preferences.showUntil)
|
||||||
intArrayOf(6,7,0,1,2,3,4,5).forEach {
|
intArrayOf(6,7,0,1,2).forEach {
|
||||||
dialog.addItem(getString(SettingsStringHelper.getShowUntilString(it)), it)
|
dialog.addItem(getString(SettingsStringHelper.getShowUntilString(it)), it)
|
||||||
}
|
}
|
||||||
dialog.addOnSelectItemListener { value ->
|
dialog.addOnSelectItemListener { value ->
|
@ -6,7 +6,6 @@ import android.content.BroadcastReceiver
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
import android.content.pm.ApplicationInfo
|
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
@ -20,29 +19,35 @@ import androidx.lifecycle.ViewModelProvider
|
|||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.chibatching.kotpref.bulk
|
import com.chibatching.kotpref.bulk
|
||||||
import com.tommasoberlose.anotherwidget.R
|
import com.tommasoberlose.anotherwidget.R
|
||||||
|
import com.tommasoberlose.anotherwidget.components.BottomSheetColorPicker
|
||||||
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
|
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
|
||||||
import com.tommasoberlose.anotherwidget.databinding.FragmentClockSettingsBinding
|
import com.tommasoberlose.anotherwidget.databinding.FragmentClockSettingsBinding
|
||||||
import com.tommasoberlose.anotherwidget.global.Constants
|
import com.tommasoberlose.anotherwidget.global.Constants
|
||||||
import com.tommasoberlose.anotherwidget.global.Preferences
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
import com.tommasoberlose.anotherwidget.global.RequestCode
|
import com.tommasoberlose.anotherwidget.global.RequestCode
|
||||||
import com.tommasoberlose.anotherwidget.helpers.AlarmHelper
|
import com.tommasoberlose.anotherwidget.helpers.AlarmHelper
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.ColorHelper
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toHexValue
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.toIntValue
|
||||||
import com.tommasoberlose.anotherwidget.ui.activities.ChooseApplicationActivity
|
import com.tommasoberlose.anotherwidget.ui.activities.ChooseApplicationActivity
|
||||||
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
|
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
|
||||||
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
|
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
|
||||||
import com.tommasoberlose.anotherwidget.utils.toast
|
|
||||||
import kotlinx.android.synthetic.main.fragment_clock_settings.*
|
import kotlinx.android.synthetic.main.fragment_clock_settings.*
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
|
|
||||||
|
|
||||||
class ClockSettingsFragment : Fragment() {
|
class ClockTabFragment : Fragment() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun newInstance() = ClockSettingsFragment()
|
fun newInstance() = ClockTabFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var viewModel: MainViewModel
|
private lateinit var viewModel: MainViewModel
|
||||||
|
private lateinit var colors: IntArray
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@ -67,8 +72,13 @@ class ClockSettingsFragment : Fragment() {
|
|||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
|
||||||
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
|
val lazyColors = requireContext().resources.getIntArray(R.array.material_colors)
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
colors = lazyColors
|
||||||
|
}
|
||||||
|
}
|
||||||
setupListener()
|
setupListener()
|
||||||
updateNextAlarmWarningUi()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun subscribeUi(
|
private fun subscribeUi(
|
||||||
@ -94,6 +104,28 @@ class ClockSettingsFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
viewModel.clockTextColor.observe(viewLifecycleOwner, Observer {
|
||||||
|
maintainScrollPosition {
|
||||||
|
if (Preferences.clockTextAlpha == "00") {
|
||||||
|
clock_text_color_label?.text = getString(R.string.transparent)
|
||||||
|
} else {
|
||||||
|
clock_text_color_label?.text =
|
||||||
|
"#%s".format(Integer.toHexString(ColorHelper.getClockFontColor())).toUpperCase()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
viewModel.clockTextAlpha.observe(viewLifecycleOwner, Observer {
|
||||||
|
maintainScrollPosition {
|
||||||
|
if (Preferences.clockTextAlpha == "00") {
|
||||||
|
clock_text_color_label?.text = getString(R.string.transparent)
|
||||||
|
} else {
|
||||||
|
clock_text_color_label?.text =
|
||||||
|
"#%s".format(Integer.toHexString(ColorHelper.getClockFontColor())).toUpperCase()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
viewModel.clockBottomMargin.observe(viewLifecycleOwner, Observer {
|
viewModel.clockBottomMargin.observe(viewLifecycleOwner, Observer {
|
||||||
maintainScrollPosition {
|
maintainScrollPosition {
|
||||||
clock_bottom_margin_label?.text = when (it) {
|
clock_bottom_margin_label?.text = when (it) {
|
||||||
@ -105,10 +137,6 @@ class ClockSettingsFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
viewModel.showNextAlarm.observe(viewLifecycleOwner, Observer {
|
|
||||||
updateNextAlarmWarningUi()
|
|
||||||
})
|
|
||||||
|
|
||||||
viewModel.clockAppName.observe(viewLifecycleOwner, Observer {
|
viewModel.clockAppName.observe(viewLifecycleOwner, Observer {
|
||||||
maintainScrollPosition {
|
maintainScrollPosition {
|
||||||
clock_app_label?.text =
|
clock_app_label?.text =
|
||||||
@ -136,6 +164,23 @@ class ClockSettingsFragment : Fragment() {
|
|||||||
}.show()
|
}.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
action_clock_text_color.setOnClickListener {
|
||||||
|
BottomSheetColorPicker(requireContext(),
|
||||||
|
colors = colors,
|
||||||
|
header = getString(R.string.settings_font_color_title),
|
||||||
|
getSelected = ColorHelper::getClockFontColorRgb,
|
||||||
|
onColorSelected = { color: Int ->
|
||||||
|
val colorString = Integer.toHexString(color)
|
||||||
|
Preferences.clockTextColor = "#" + if (colorString.length > 6) colorString.substring(2) else colorString
|
||||||
|
},
|
||||||
|
showAlphaSelector = true,
|
||||||
|
alpha = Preferences.clockTextAlpha.toIntValue(),
|
||||||
|
onAlphaChangeListener = { alpha ->
|
||||||
|
Preferences.clockTextAlpha = alpha.toHexValue()
|
||||||
|
}
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
|
||||||
action_clock_bottom_margin_size.setOnClickListener {
|
action_clock_bottom_margin_size.setOnClickListener {
|
||||||
BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_show_next_alarm_title)).setSelectedValue(Preferences.clockBottomMargin)
|
BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_show_next_alarm_title)).setSelectedValue(Preferences.clockBottomMargin)
|
||||||
.addItem(getString(R.string.settings_clock_bottom_margin_subtitle_none), Constants.ClockBottomMargin.NONE.value)
|
.addItem(getString(R.string.settings_clock_bottom_margin_subtitle_none), Constants.ClockBottomMargin.NONE.value)
|
||||||
@ -154,50 +199,6 @@ class ClockSettingsFragment : Fragment() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
action_show_next_alarm.setOnClickListener {
|
|
||||||
BottomSheetMenu<Boolean>(requireContext(), header = getString(R.string.settings_show_next_alarm_title)).setSelectedValue(Preferences.showNextAlarm)
|
|
||||||
.addItem(getString(R.string.settings_visible), true)
|
|
||||||
.addItem(getString(R.string.settings_not_visible), false)
|
|
||||||
.addOnSelectItemListener { value ->
|
|
||||||
Preferences.showNextAlarm = value
|
|
||||||
}.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateNextAlarmWarningUi() {
|
|
||||||
with(requireContext().getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
|
|
||||||
val alarm = nextAlarmClock
|
|
||||||
if (AlarmHelper.isAlarmProbablyWrong(requireContext()) && alarm != null && alarm.showIntent != null) {
|
|
||||||
val pm = requireContext().packageManager as PackageManager
|
|
||||||
val appNameOrPackage = try {
|
|
||||||
pm.getApplicationLabel(pm.getApplicationInfo(alarm.showIntent?.creatorPackage ?: "", 0))
|
|
||||||
} catch (e: Exception) {
|
|
||||||
alarm.showIntent?.creatorPackage ?: ""
|
|
||||||
}
|
|
||||||
show_next_alarm_warning.text = getString(R.string.next_alarm_warning).format(appNameOrPackage)
|
|
||||||
} else {
|
|
||||||
maintainScrollPosition {
|
|
||||||
show_next_alarm_label?.text = if (Preferences.showNextAlarm) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val nextAlarmChangeBroadcastReceiver = object : BroadcastReceiver() {
|
|
||||||
override fun onReceive(context: Context?, intent: Intent?) {
|
|
||||||
updateNextAlarmWarningUi()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStart() {
|
|
||||||
super.onStart()
|
|
||||||
activity?.registerReceiver(nextAlarmChangeBroadcastReceiver, IntentFilter(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStop() {
|
|
||||||
activity?.unregisterReceiver(nextAlarmChangeBroadcastReceiver)
|
|
||||||
super.onStop()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
@ -3,9 +3,7 @@ package com.tommasoberlose.anotherwidget.ui.fragments
|
|||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Color
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@ -33,10 +31,10 @@ import kotlinx.coroutines.launch
|
|||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
|
||||||
class GeneralSettingsFragment : Fragment() {
|
class GeneralTabFragment : Fragment() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun newInstance() = GeneralSettingsFragment()
|
fun newInstance() = GeneralTabFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var viewModel: MainViewModel
|
private lateinit var viewModel: MainViewModel
|
@ -0,0 +1,340 @@
|
|||||||
|
package com.tommasoberlose.anotherwidget.ui.fragments
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.animation.ValueAnimator
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.provider.Settings
|
||||||
|
import android.util.DisplayMetrics
|
||||||
|
import android.util.TypedValue
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.RelativeLayout
|
||||||
|
import androidx.core.animation.addListener
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.Observer
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.navigation.Navigation
|
||||||
|
import com.google.android.material.badge.BadgeDrawable
|
||||||
|
import com.google.android.material.tabs.TabLayoutMediator
|
||||||
|
import com.google.android.material.transition.MaterialSharedAxis
|
||||||
|
import com.tommasoberlose.anotherwidget.R
|
||||||
|
import com.tommasoberlose.anotherwidget.components.MaterialBottomSheetDialog
|
||||||
|
import com.tommasoberlose.anotherwidget.databinding.FragmentAdvancedSettingsBinding
|
||||||
|
import com.tommasoberlose.anotherwidget.databinding.FragmentAppMainBinding
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Constants
|
||||||
|
import com.tommasoberlose.anotherwidget.global.Preferences
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.BitmapHelper
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.ColorHelper
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.adapters.ViewPagerAdapter
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
|
||||||
|
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.getCurrentWallpaper
|
||||||
|
import com.tommasoberlose.anotherwidget.utils.toPixel
|
||||||
|
import kotlinx.android.synthetic.main.fragment_app_main.*
|
||||||
|
import kotlinx.android.synthetic.main.the_widget_sans.*
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import org.greenrobot.eventbus.Subscribe
|
||||||
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
|
|
||||||
|
class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun newInstance() = MainFragment()
|
||||||
|
}
|
||||||
|
|
||||||
|
private lateinit var viewModel: MainViewModel
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
enterTransition = MaterialSharedAxis.create(MaterialSharedAxis.X, true)
|
||||||
|
reenterTransition = MaterialSharedAxis.create(MaterialSharedAxis.X, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
|
||||||
|
return inflater.inflate(R.layout.fragment_app_main, container, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
subscribeUi(viewModel)
|
||||||
|
|
||||||
|
// Viewpager
|
||||||
|
pager.adapter = ViewPagerAdapter(requireActivity())
|
||||||
|
pager.offscreenPageLimit = 4
|
||||||
|
TabLayoutMediator(tabs, pager) { tab, position ->
|
||||||
|
tab.text = when (position) {
|
||||||
|
0 -> getString(R.string.settings_general_title)
|
||||||
|
1 -> getString(R.string.settings_calendar_title)
|
||||||
|
2 -> getString(R.string.settings_weather_title)
|
||||||
|
3 -> getString(R.string.settings_clock_title)
|
||||||
|
4 -> getString(R.string.settings_at_a_glance_title)
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
}.attach()
|
||||||
|
|
||||||
|
// Init clock
|
||||||
|
time.setTextColor(ColorHelper.getClockFontColor())
|
||||||
|
time.setTextSize(TypedValue.COMPLEX_UNIT_SP, Preferences.clockTextSize.toPixel(requireContext()))
|
||||||
|
time_am_pm.setTextColor(ColorHelper.getClockFontColor())
|
||||||
|
time_am_pm.setTextSize(TypedValue.COMPLEX_UNIT_SP, Preferences.clockTextSize.toPixel(requireContext()) / 5 * 2)
|
||||||
|
time_container.isVisible = Preferences.showClock
|
||||||
|
|
||||||
|
preview.layoutParams = preview.layoutParams.apply {
|
||||||
|
height = 160.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(requireContext()) else 0
|
||||||
|
}
|
||||||
|
subscribeUi(viewModel)
|
||||||
|
updateUI()
|
||||||
|
|
||||||
|
// Warnings
|
||||||
|
if (getString(R.string.xiaomi_manufacturer).equals(Build.MANUFACTURER, ignoreCase = true) && Preferences.showXiaomiWarning) {
|
||||||
|
MaterialBottomSheetDialog(requireContext(), getString(R.string.xiaomi_warning_title), getString(R.string.xiaomi_warning_message))
|
||||||
|
.setNegativeButton(getString(R.string.action_ignore)) {
|
||||||
|
Preferences.showXiaomiWarning = false
|
||||||
|
}
|
||||||
|
.setPositiveButton(getString(R.string.action_grant_permission)) {
|
||||||
|
Preferences.showXiaomiWarning = false
|
||||||
|
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
|
||||||
|
data = Uri.parse("package:${activity?.packageName}")
|
||||||
|
}
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var uiJob: Job? = null
|
||||||
|
|
||||||
|
private fun updateUI() {
|
||||||
|
uiJob?.cancel()
|
||||||
|
|
||||||
|
if (Preferences.showPreview) {
|
||||||
|
preview.setCardBackgroundColor(
|
||||||
|
ContextCompat.getColor(
|
||||||
|
requireContext(),
|
||||||
|
if (ColorHelper.getFontColor()
|
||||||
|
.isColorDark()
|
||||||
|
) android.R.color.white else R.color.colorAccent
|
||||||
|
)
|
||||||
|
)
|
||||||
|
widget_shape_background.setImageDrawable(BitmapHelper.getTintedDrawable(requireContext(), R.drawable.card_background, ColorHelper.getBackgroundColor()))
|
||||||
|
uiJob = viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
|
||||||
|
delay(200)
|
||||||
|
val generatedView = MainWidget.generateWidgetView(requireContext())
|
||||||
|
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
generatedView.measure(0, 0)
|
||||||
|
preview.measure(0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
val bitmap = BitmapHelper.getBitmapFromView(
|
||||||
|
generatedView,
|
||||||
|
if (preview.width > 0) preview.width else generatedView.measuredWidth,
|
||||||
|
generatedView.measuredHeight
|
||||||
|
)
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
// Clock
|
||||||
|
time.setTextColor(ColorHelper.getClockFontColor())
|
||||||
|
time_am_pm.setTextColor(ColorHelper.getClockFontColor())
|
||||||
|
time.setTextSize(
|
||||||
|
TypedValue.COMPLEX_UNIT_SP,
|
||||||
|
Preferences.clockTextSize.toPixel(requireContext())
|
||||||
|
)
|
||||||
|
time_am_pm.setTextSize(
|
||||||
|
TypedValue.COMPLEX_UNIT_SP,
|
||||||
|
Preferences.clockTextSize.toPixel(requireContext()) / 5 * 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// Clock bottom margin
|
||||||
|
clock_bottom_margin_none.isVisible =
|
||||||
|
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.NONE.value
|
||||||
|
clock_bottom_margin_small.isVisible =
|
||||||
|
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.SMALL.value
|
||||||
|
clock_bottom_margin_medium.isVisible =
|
||||||
|
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.MEDIUM.value
|
||||||
|
clock_bottom_margin_large.isVisible =
|
||||||
|
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.LARGE.value
|
||||||
|
|
||||||
|
if ((Preferences.showClock && !time_container.isVisible) || (!Preferences.showClock && time_container.isVisible)) {
|
||||||
|
if (Preferences.showClock) {
|
||||||
|
time_container.layoutParams = time_container.layoutParams.apply {
|
||||||
|
height = RelativeLayout.LayoutParams.WRAP_CONTENT
|
||||||
|
}
|
||||||
|
time_container.measure(0, 0)
|
||||||
|
}
|
||||||
|
val initialHeight = time_container.measuredHeight
|
||||||
|
ValueAnimator.ofFloat(
|
||||||
|
if (Preferences.showClock) 0f else 1f,
|
||||||
|
if (Preferences.showClock) 1f else 0f
|
||||||
|
).apply {
|
||||||
|
duration = 500L
|
||||||
|
addUpdateListener {
|
||||||
|
val animatedValue = animatedValue as Float
|
||||||
|
time_container.layoutParams = time_container.layoutParams.apply {
|
||||||
|
height = (initialHeight * animatedValue).toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addListener(
|
||||||
|
onStart = {
|
||||||
|
if (Preferences.showClock) {
|
||||||
|
time_container.isVisible = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onEnd = {
|
||||||
|
if (!Preferences.showClock) {
|
||||||
|
time_container.isVisible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}.start()
|
||||||
|
|
||||||
|
ValueAnimator.ofInt(
|
||||||
|
preview.height,
|
||||||
|
160.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(
|
||||||
|
requireContext()
|
||||||
|
) else 0
|
||||||
|
).apply {
|
||||||
|
duration = 500L
|
||||||
|
addUpdateListener {
|
||||||
|
val animatedValue = animatedValue as Int
|
||||||
|
val layoutParams = preview.layoutParams
|
||||||
|
layoutParams.height = animatedValue
|
||||||
|
preview.layoutParams = layoutParams
|
||||||
|
}
|
||||||
|
}.start()
|
||||||
|
} else {
|
||||||
|
time_container.layoutParams = time_container.layoutParams.apply {
|
||||||
|
height = RelativeLayout.LayoutParams.WRAP_CONTENT
|
||||||
|
}
|
||||||
|
time_container.measure(0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preview.height == 0) {
|
||||||
|
ValueAnimator.ofInt(
|
||||||
|
preview.height,
|
||||||
|
160.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(
|
||||||
|
requireContext()
|
||||||
|
) else 0
|
||||||
|
).apply {
|
||||||
|
duration = 300L
|
||||||
|
addUpdateListener {
|
||||||
|
val animatedValue = animatedValue as Int
|
||||||
|
val layoutParams = preview.layoutParams
|
||||||
|
layoutParams.height = animatedValue
|
||||||
|
preview.layoutParams = layoutParams
|
||||||
|
}
|
||||||
|
}.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
bitmap_container.setImageBitmap(bitmap)
|
||||||
|
widget_loader.animate().scaleX(0f).scaleY(0f).start()
|
||||||
|
widget.animate().alpha(1f).start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ValueAnimator.ofInt(
|
||||||
|
preview.height,
|
||||||
|
0
|
||||||
|
).apply {
|
||||||
|
duration = 300L
|
||||||
|
addUpdateListener {
|
||||||
|
val animatedValue = animatedValue as Int
|
||||||
|
val layoutParams = preview.layoutParams
|
||||||
|
layoutParams.height = animatedValue
|
||||||
|
preview.layoutParams = layoutParams
|
||||||
|
}
|
||||||
|
}.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
showErrorBadge()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun subscribeUi(viewModel: MainViewModel) {
|
||||||
|
viewModel.showWallpaper.observe(viewLifecycleOwner, Observer {
|
||||||
|
activity?.let { act ->
|
||||||
|
val wallpaper = act.getCurrentWallpaper()
|
||||||
|
widget_bg.setImageDrawable(if (it) wallpaper else null)
|
||||||
|
widget_bg.layoutParams = widget_bg.layoutParams.apply {
|
||||||
|
|
||||||
|
val metrics = DisplayMetrics()
|
||||||
|
act.windowManager.defaultDisplay.getMetrics(metrics)
|
||||||
|
|
||||||
|
height = metrics.heightPixels
|
||||||
|
width = (wallpaper?.intrinsicWidth ?: 1) * metrics.heightPixels / (wallpaper?.intrinsicWidth ?: 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
logo.setOnClickListener {
|
||||||
|
// startActivity(Intent(this, SupportDevActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
action_settings.setOnClickListener {
|
||||||
|
Navigation.findNavController(it).navigate(R.id.action_appMainFragment_to_appSettingsFragment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showErrorBadge() {
|
||||||
|
// Calendar error indicator
|
||||||
|
tabs?.getTabAt(1)?.orCreateBadge?.apply {
|
||||||
|
backgroundColor = ContextCompat.getColor(requireContext(), R.color.errorColorText)
|
||||||
|
badgeGravity = BadgeDrawable.TOP_END
|
||||||
|
}?.isVisible = Preferences.showEvents && activity?.checkGrantedPermission(Manifest.permission.READ_CALENDAR) != true
|
||||||
|
|
||||||
|
// Weather error indicator
|
||||||
|
tabs?.getTabAt(2)?.orCreateBadge?.apply {
|
||||||
|
backgroundColor = ContextCompat.getColor(requireContext(), R.color.errorColorText)
|
||||||
|
badgeGravity = BadgeDrawable.TOP_END
|
||||||
|
}?.isVisible = Preferences.showWeather && (Preferences.weatherProviderApi == "" || (Preferences.customLocationAdd == "" && activity?.checkGrantedPermission(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACCESS_BACKGROUND_LOCATION else Manifest.permission.ACCESS_FINE_LOCATION) != true))
|
||||||
|
|
||||||
|
|
||||||
|
// Music error indicator
|
||||||
|
tabs?.getTabAt(4)?.orCreateBadge?.apply {
|
||||||
|
backgroundColor = ContextCompat.getColor(requireContext(), R.color.errorColorText)
|
||||||
|
badgeGravity = BadgeDrawable.TOP_END
|
||||||
|
}?.isVisible = Preferences.showMusic && !NotificationManagerCompat.getEnabledListenerPackages(requireContext()).contains(requireContext().packageName)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSharedPreferenceChanged(preferences: SharedPreferences, p1: String) {
|
||||||
|
updateUI()
|
||||||
|
MainWidget.updateWidget(requireContext())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
Preferences.preferences.registerOnSharedPreferenceChangeListener(this)
|
||||||
|
EventBus.getDefault().register(this)
|
||||||
|
showErrorBadge()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPause() {
|
||||||
|
Preferences.preferences.unregisterOnSharedPreferenceChangeListener(this)
|
||||||
|
EventBus.getDefault().unregister(this)
|
||||||
|
super.onPause()
|
||||||
|
}
|
||||||
|
|
||||||
|
class UpdateUiMessageEvent
|
||||||
|
|
||||||
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
|
fun onMessageEvent(ignore: UpdateUiMessageEvent?) {
|
||||||
|
updateUI()
|
||||||
|
}
|
||||||
|
}
|
@ -2,10 +2,8 @@ package com.tommasoberlose.anotherwidget.ui.fragments
|
|||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@ -15,6 +13,9 @@ import androidx.fragment.app.Fragment
|
|||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.navigation.Navigation
|
||||||
|
import com.google.android.material.transition.MaterialContainerTransform
|
||||||
|
import com.google.android.material.transition.MaterialSharedAxis
|
||||||
import com.karumi.dexter.Dexter
|
import com.karumi.dexter.Dexter
|
||||||
import com.karumi.dexter.MultiplePermissionsReport
|
import com.karumi.dexter.MultiplePermissionsReport
|
||||||
import com.karumi.dexter.PermissionToken
|
import com.karumi.dexter.PermissionToken
|
||||||
@ -29,8 +30,9 @@ import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
|
|||||||
import com.tommasoberlose.anotherwidget.ui.activities.SupportDevActivity
|
import com.tommasoberlose.anotherwidget.ui.activities.SupportDevActivity
|
||||||
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
|
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
|
||||||
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper
|
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper
|
||||||
|
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
|
||||||
import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
|
import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
|
||||||
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
|
import com.tommasoberlose.anotherwidget.ui.activities.IntegrationsActivity
|
||||||
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
|
||||||
import com.tommasoberlose.anotherwidget.utils.openURI
|
import com.tommasoberlose.anotherwidget.utils.openURI
|
||||||
import kotlinx.android.synthetic.main.fragment_advanced_settings.*
|
import kotlinx.android.synthetic.main.fragment_advanced_settings.*
|
||||||
@ -38,16 +40,18 @@ import kotlinx.coroutines.delay
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
|
||||||
class AdvancedSettingsFragment : Fragment() {
|
class SettingsFragment : Fragment() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun newInstance() = AdvancedSettingsFragment()
|
fun newInstance() = SettingsFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var viewModel: MainViewModel
|
private lateinit var viewModel: MainViewModel
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
enterTransition = MaterialSharedAxis.create(MaterialSharedAxis.X, true)
|
||||||
|
returnTransition = MaterialSharedAxis.create(MaterialSharedAxis.X, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
@ -58,8 +62,6 @@ class AdvancedSettingsFragment : Fragment() {
|
|||||||
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
|
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
|
||||||
val binding = DataBindingUtil.inflate<FragmentAdvancedSettingsBinding>(inflater, R.layout.fragment_advanced_settings, container, false)
|
val binding = DataBindingUtil.inflate<FragmentAdvancedSettingsBinding>(inflater, R.layout.fragment_advanced_settings, container, false)
|
||||||
|
|
||||||
subscribeUi(viewModel)
|
|
||||||
|
|
||||||
binding.lifecycleOwner = this
|
binding.lifecycleOwner = this
|
||||||
binding.viewModel = viewModel
|
binding.viewModel = viewModel
|
||||||
|
|
||||||
@ -69,10 +71,15 @@ class AdvancedSettingsFragment : Fragment() {
|
|||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
|
||||||
|
action_back.setOnClickListener {
|
||||||
|
Navigation.findNavController(it).popBackStack()
|
||||||
|
}
|
||||||
|
|
||||||
|
subscribeUi(viewModel)
|
||||||
|
|
||||||
setupListener()
|
setupListener()
|
||||||
|
|
||||||
app_version.text = "v%s (%s)".format(BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE)
|
app_version.text = "v%s (%s)".format(BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE)
|
||||||
requirePermission()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun subscribeUi(
|
private fun subscribeUi(
|
||||||
@ -91,6 +98,10 @@ class AdvancedSettingsFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
viewModel.installedIntegrations.observe(viewLifecycleOwner, Observer {
|
||||||
|
integrations_count_label?.text = getString(R.string.label_count_installed_integrations).format(it)
|
||||||
|
})
|
||||||
|
|
||||||
viewModel.showPreview.observe(viewLifecycleOwner, Observer {
|
viewModel.showPreview.observe(viewLifecycleOwner, Observer {
|
||||||
maintainScrollPosition {
|
maintainScrollPosition {
|
||||||
show_widget_preview_label?.text =
|
show_widget_preview_label?.text =
|
||||||
@ -109,27 +120,6 @@ class AdvancedSettingsFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setupListener() {
|
private fun setupListener() {
|
||||||
action_change_theme.setOnClickListener {
|
|
||||||
maintainScrollPosition {
|
|
||||||
BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_theme_title))
|
|
||||||
.setSelectedValue(Preferences.darkThemePreference)
|
|
||||||
.addItem(
|
|
||||||
getString(R.string.settings_subtitle_dark_theme_light),
|
|
||||||
AppCompatDelegate.MODE_NIGHT_NO
|
|
||||||
)
|
|
||||||
.addItem(
|
|
||||||
getString(R.string.settings_subtitle_dark_theme_dark),
|
|
||||||
AppCompatDelegate.MODE_NIGHT_YES
|
|
||||||
)
|
|
||||||
.addItem(
|
|
||||||
getString(R.string.settings_subtitle_dark_theme_default),
|
|
||||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM else AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY
|
|
||||||
)
|
|
||||||
.addOnSelectItemListener { value ->
|
|
||||||
Preferences.darkThemePreference = value
|
|
||||||
}.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
action_show_widget_preview.setOnClickListener {
|
action_show_widget_preview.setOnClickListener {
|
||||||
maintainScrollPosition {
|
maintainScrollPosition {
|
||||||
@ -171,6 +161,32 @@ class AdvancedSettingsFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
action_integrations.setOnClickListener {
|
||||||
|
startActivity(Intent(requireContext(), IntegrationsActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
action_change_theme.setOnClickListener {
|
||||||
|
maintainScrollPosition {
|
||||||
|
BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_theme_title))
|
||||||
|
.setSelectedValue(Preferences.darkThemePreference)
|
||||||
|
.addItem(
|
||||||
|
getString(R.string.settings_subtitle_dark_theme_light),
|
||||||
|
AppCompatDelegate.MODE_NIGHT_NO
|
||||||
|
)
|
||||||
|
.addItem(
|
||||||
|
getString(R.string.settings_subtitle_dark_theme_dark),
|
||||||
|
AppCompatDelegate.MODE_NIGHT_YES
|
||||||
|
)
|
||||||
|
.addItem(
|
||||||
|
getString(R.string.settings_subtitle_dark_theme_default),
|
||||||
|
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM else AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY
|
||||||
|
)
|
||||||
|
.addOnSelectItemListener { value ->
|
||||||
|
Preferences.darkThemePreference = value
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
action_translate.setOnClickListener {
|
action_translate.setOnClickListener {
|
||||||
activity?.openURI("https://github.com/tommasoberlose/another-widget/blob/master/app/src/main/res/values/strings.xml")
|
activity?.openURI("https://github.com/tommasoberlose/another-widget/blob/master/app/src/main/res/values/strings.xml")
|
||||||
}
|
}
|
||||||
@ -190,6 +206,7 @@ class AdvancedSettingsFragment : Fragment() {
|
|||||||
action_refresh_widget.setOnClickListener {
|
action_refresh_widget.setOnClickListener {
|
||||||
WeatherHelper.updateWeather(requireContext())
|
WeatherHelper.updateWeather(requireContext())
|
||||||
CalendarHelper.updateEventList(requireContext())
|
CalendarHelper.updateEventList(requireContext())
|
||||||
|
MediaPlayerHelper.updatePlayingMediaInfo(requireContext())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -41,10 +41,10 @@ import kotlinx.android.synthetic.main.fragment_weather_settings.scrollView
|
|||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class WeatherSettingsFragment : Fragment() {
|
class WeatherTabFragment : Fragment() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun newInstance() = WeatherSettingsFragment()
|
fun newInstance() = WeatherTabFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var viewModel: MainViewModel
|
private lateinit var viewModel: MainViewModel
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.tommasoberlose.anotherwidget.ui.viewmodels
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import androidx.lifecycle.AndroidViewModel
|
||||||
|
|
||||||
|
class IntegrationsViewModel(application: Application) : AndroidViewModel(application) {
|
||||||
|
}
|
@ -27,10 +27,11 @@ class MainViewModel : ViewModel() {
|
|||||||
val openEventDetails = Preferences.asLiveData(Preferences::openEventDetails)
|
val openEventDetails = Preferences.asLiveData(Preferences::openEventDetails)
|
||||||
val calendarAppName = Preferences.asLiveData(Preferences::calendarAppName)
|
val calendarAppName = Preferences.asLiveData(Preferences::calendarAppName)
|
||||||
|
|
||||||
|
|
||||||
// Clock Settings
|
// Clock Settings
|
||||||
val showClock = Preferences.asLiveData(Preferences::showClock)
|
val showClock = Preferences.asLiveData(Preferences::showClock)
|
||||||
val clockTextSize = Preferences.asLiveData(Preferences::clockTextSize)
|
val clockTextSize = Preferences.asLiveData(Preferences::clockTextSize)
|
||||||
|
val clockTextColor = Preferences.asLiveData(Preferences::clockTextColor)
|
||||||
|
val clockTextAlpha = Preferences.asLiveData(Preferences::clockTextAlpha)
|
||||||
|
|
||||||
val clockAppName = Preferences.asLiveData(Preferences::clockAppName)
|
val clockAppName = Preferences.asLiveData(Preferences::clockAppName)
|
||||||
val showNextAlarm = Preferences.asLiveData(Preferences::showNextAlarm)
|
val showNextAlarm = Preferences.asLiveData(Preferences::showNextAlarm)
|
||||||
@ -51,8 +52,13 @@ class MainViewModel : ViewModel() {
|
|||||||
|
|
||||||
val showWeatherWarning = Preferences.asLiveData(Preferences::showWeatherWarning)
|
val showWeatherWarning = Preferences.asLiveData(Preferences::showWeatherWarning)
|
||||||
|
|
||||||
|
// Music
|
||||||
|
val showMusic = Preferences.asLiveData(Preferences::showMusic)
|
||||||
|
val mediaInfoFormat = Preferences.asLiveData(Preferences::mediaInfoFormat)
|
||||||
|
|
||||||
// Advanced Settings
|
// Advanced Settings
|
||||||
val darkThemePreference = Preferences.asLiveData(Preferences::darkThemePreference)
|
val darkThemePreference = Preferences.asLiveData(Preferences::darkThemePreference)
|
||||||
val showWallpaper = Preferences.asLiveData(Preferences::showWallpaper)
|
val showWallpaper = Preferences.asLiveData(Preferences::showWallpaper)
|
||||||
val showPreview = Preferences.asLiveData(Preferences::showPreview)
|
val showPreview = Preferences.asLiveData(Preferences::showPreview)
|
||||||
|
val installedIntegrations = Preferences.asLiveData(Preferences::installedIntegrations)
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import android.graphics.Color
|
|||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.format.DateUtils
|
import android.text.format.DateUtils
|
||||||
|
import android.util.Log
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
@ -19,7 +20,6 @@ import android.widget.RemoteViews
|
|||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
|
||||||
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.Actions
|
import com.tommasoberlose.anotherwidget.global.Actions
|
||||||
@ -53,6 +53,7 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
override fun onEnabled(context: Context) {
|
override fun onEnabled(context: Context) {
|
||||||
CalendarHelper.updateEventList(context)
|
CalendarHelper.updateEventList(context)
|
||||||
WeatherReceiver.setUpdates(context)
|
WeatherReceiver.setUpdates(context)
|
||||||
|
MediaPlayerHelper.updatePlayingMediaInfo(context)
|
||||||
|
|
||||||
if (Preferences.showEvents) {
|
if (Preferences.showEvents) {
|
||||||
CalendarHelper.setEventUpdatesAndroidN(context)
|
CalendarHelper.setEventUpdatesAndroidN(context)
|
||||||
@ -148,6 +149,7 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
views.setViewVisibility(R.id.empty_layout_rect, View.VISIBLE)
|
views.setViewVisibility(R.id.empty_layout_rect, View.VISIBLE)
|
||||||
views.setViewVisibility(R.id.calendar_layout_rect, View.GONE)
|
views.setViewVisibility(R.id.calendar_layout_rect, View.GONE)
|
||||||
views.setViewVisibility(R.id.second_row_rect, View.GONE)
|
views.setViewVisibility(R.id.second_row_rect, View.GONE)
|
||||||
|
views.setViewVisibility(R.id.next_event_difference_time_rect, View.GONE)
|
||||||
|
|
||||||
val calPIntent = PendingIntent.getActivity(
|
val calPIntent = PendingIntent.getActivity(
|
||||||
context,
|
context,
|
||||||
@ -259,14 +261,14 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
|
|
||||||
views.setViewVisibility(R.id.empty_layout_rect, View.GONE)
|
views.setViewVisibility(R.id.empty_layout_rect, View.GONE)
|
||||||
views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE)
|
views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE)
|
||||||
} else if (Preferences.showNextAlarm && nextAlarm != "") {
|
} else if (MediaPlayerHelper.isSomeonePlaying(context)) {
|
||||||
val clockIntent = PendingIntent.getActivity(
|
val musicIntent = PendingIntent.getActivity(
|
||||||
context,
|
context,
|
||||||
widgetID,
|
widgetID,
|
||||||
IntentHelper.getClockIntent(context),
|
IntentHelper.getMusicIntent(context),
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
views.setOnClickPendingIntent(R.id.second_row_rect, clockIntent)
|
views.setOnClickPendingIntent(R.id.second_row_rect, musicIntent)
|
||||||
|
|
||||||
views.setImageViewBitmap(
|
views.setImageViewBitmap(
|
||||||
R.id.next_event_rect,
|
R.id.next_event_rect,
|
||||||
@ -281,6 +283,30 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
|
|
||||||
views.setViewVisibility(R.id.empty_layout_rect, View.GONE)
|
views.setViewVisibility(R.id.empty_layout_rect, View.GONE)
|
||||||
views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE)
|
views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE)
|
||||||
|
views.setOnClickPendingIntent(R.id.next_event_rect, calPIntent)
|
||||||
|
} else if (Preferences.showNextAlarm && nextAlarm != "") {
|
||||||
|
val alarmIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
widgetID,
|
||||||
|
IntentHelper.getClockIntent(context),
|
||||||
|
0
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.second_row_rect, alarmIntent)
|
||||||
|
|
||||||
|
views.setImageViewBitmap(
|
||||||
|
R.id.next_event_rect,
|
||||||
|
BitmapHelper.getBitmapFromView(v.next_event, draw = false)
|
||||||
|
)
|
||||||
|
|
||||||
|
views.setImageViewBitmap(
|
||||||
|
R.id.second_row_rect,
|
||||||
|
BitmapHelper.getBitmapFromView(v.second_row, draw = false)
|
||||||
|
)
|
||||||
|
views.setViewVisibility(R.id.second_row_rect, View.VISIBLE)
|
||||||
|
|
||||||
|
views.setViewVisibility(R.id.empty_layout_rect, View.GONE)
|
||||||
|
views.setViewVisibility(R.id.calendar_layout_rect, View.VISIBLE)
|
||||||
|
views.setOnClickPendingIntent(R.id.next_event_rect, calPIntent)
|
||||||
}
|
}
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
ex.printStackTrace()
|
ex.printStackTrace()
|
||||||
@ -295,6 +321,7 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
if (Preferences.showWeather && Preferences.weatherIcon != "") {
|
if (Preferences.showWeather && Preferences.weatherIcon != "") {
|
||||||
views.setViewVisibility(R.id.weather_rect, View.VISIBLE)
|
views.setViewVisibility(R.id.weather_rect, View.VISIBLE)
|
||||||
views.setViewVisibility(R.id.calendar_weather_rect, View.VISIBLE)
|
views.setViewVisibility(R.id.calendar_weather_rect, View.VISIBLE)
|
||||||
|
views.setViewVisibility(R.id.special_weather_rect, View.VISIBLE)
|
||||||
|
|
||||||
val i = Intent(context, WidgetClickListenerReceiver::class.java)
|
val i = Intent(context, WidgetClickListenerReceiver::class.java)
|
||||||
i.action = Actions.ACTION_OPEN_WEATHER_INTENT
|
i.action = Actions.ACTION_OPEN_WEATHER_INTENT
|
||||||
@ -302,6 +329,7 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
|
|
||||||
views.setOnClickPendingIntent(R.id.weather_rect, weatherPIntent)
|
views.setOnClickPendingIntent(R.id.weather_rect, weatherPIntent)
|
||||||
views.setOnClickPendingIntent(R.id.calendar_weather_rect, weatherPIntent)
|
views.setOnClickPendingIntent(R.id.calendar_weather_rect, weatherPIntent)
|
||||||
|
views.setOnClickPendingIntent(R.id.special_weather_rect, weatherPIntent)
|
||||||
|
|
||||||
views.setImageViewBitmap(
|
views.setImageViewBitmap(
|
||||||
R.id.weather_rect,
|
R.id.weather_rect,
|
||||||
@ -312,9 +340,21 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
R.id.calendar_weather_rect,
|
R.id.calendar_weather_rect,
|
||||||
BitmapHelper.getBitmapFromView(v.calendar_weather, draw = false)
|
BitmapHelper.getBitmapFromView(v.calendar_weather, draw = false)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
views.setImageViewBitmap(
|
||||||
|
R.id.special_weather_rect,
|
||||||
|
BitmapHelper.getBitmapFromView(v.calendar_weather, draw = false)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (WidgetHelper.showSpecialWeather(context)) {
|
||||||
|
views.setViewVisibility(R.id.calendar_weather_rect, View.GONE)
|
||||||
|
} else {
|
||||||
|
views.setViewVisibility(R.id.special_weather_rect, View.GONE)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
views.setViewVisibility(R.id.weather_rect, View.GONE)
|
views.setViewVisibility(R.id.weather_rect, View.GONE)
|
||||||
views.setViewVisibility(R.id.calendar_weather_rect, View.GONE)
|
views.setViewVisibility(R.id.calendar_weather_rect, View.GONE)
|
||||||
|
views.setViewVisibility(R.id.special_weather_rect, View.GONE)
|
||||||
}
|
}
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
ex.printStackTrace()
|
ex.printStackTrace()
|
||||||
@ -333,8 +373,8 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
views.setViewVisibility(R.id.clock_bottom_margin_medium, View.GONE)
|
views.setViewVisibility(R.id.clock_bottom_margin_medium, View.GONE)
|
||||||
views.setViewVisibility(R.id.clock_bottom_margin_large, View.GONE)
|
views.setViewVisibility(R.id.clock_bottom_margin_large, View.GONE)
|
||||||
} else {
|
} else {
|
||||||
views.setTextColor(R.id.time, ColorHelper.getFontColor())
|
views.setTextColor(R.id.time, ColorHelper.getClockFontColor())
|
||||||
views.setTextColor(R.id.time_am_pm, ColorHelper.getFontColor())
|
views.setTextColor(R.id.time_am_pm, ColorHelper.getClockFontColor())
|
||||||
views.setTextViewTextSize(
|
views.setTextViewTextSize(
|
||||||
R.id.time,
|
R.id.time,
|
||||||
TypedValue.COMPLEX_UNIT_SP,
|
TypedValue.COMPLEX_UNIT_SP,
|
||||||
@ -391,6 +431,7 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
|
|
||||||
v.empty_layout.visibility = View.VISIBLE
|
v.empty_layout.visibility = View.VISIBLE
|
||||||
v.calendar_layout.visibility = View.GONE
|
v.calendar_layout.visibility = View.GONE
|
||||||
|
v.next_event_difference_time.visibility = View.GONE
|
||||||
v.action_next.isVisible = false
|
v.action_next.isVisible = false
|
||||||
v.action_previous.isVisible = false
|
v.action_previous.isVisible = false
|
||||||
|
|
||||||
@ -456,6 +497,17 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v.empty_layout.visibility = View.GONE
|
||||||
|
v.calendar_layout.visibility = View.VISIBLE
|
||||||
|
} else if (MediaPlayerHelper.isSomeonePlaying(context)) {
|
||||||
|
v.second_row_icon.setImageDrawable(
|
||||||
|
ContextCompat.getDrawable(
|
||||||
|
context,
|
||||||
|
R.drawable.round_music_note
|
||||||
|
)
|
||||||
|
)
|
||||||
|
v.next_event.text = DateHelper.getDateText(context, now)
|
||||||
|
v.next_event_date.text = MediaPlayerHelper.getMediaInfo()
|
||||||
v.empty_layout.visibility = View.GONE
|
v.empty_layout.visibility = View.GONE
|
||||||
v.calendar_layout.visibility = View.VISIBLE
|
v.calendar_layout.visibility = View.VISIBLE
|
||||||
} else if (Preferences.showNextAlarm && nextAlarm != "") {
|
} else if (Preferences.showNextAlarm && nextAlarm != "") {
|
||||||
@ -473,7 +525,7 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
|
|
||||||
|
|
||||||
// Color
|
// Color
|
||||||
listOf<TextView>(v.empty_date, v.divider1, v.temp, v.next_event, v.next_event_difference_time, v.next_event_date, v.divider2, v.calendar_temp).forEach {
|
listOf<TextView>(v.empty_date, v.divider1, v.temp, v.next_event, v.next_event_difference_time, v.next_event_date, v.divider2, v.calendar_temp, v.divider3, v.special_temp).forEach {
|
||||||
it.setTextColor(ColorHelper.getFontColor())
|
it.setTextColor(ColorHelper.getFontColor())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -484,13 +536,15 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
// Text Size
|
// Text Size
|
||||||
listOf<Pair<TextView, Float>>(
|
listOf<Pair<TextView, Float>>(
|
||||||
v.empty_date to Preferences.textMainSize,
|
v.empty_date to Preferences.textMainSize,
|
||||||
v.divider1 to Preferences.textMainSize,
|
v.divider1 to (Preferences.textMainSize - 2),
|
||||||
v.temp to Preferences.textMainSize,
|
v.temp to Preferences.textMainSize,
|
||||||
v.next_event to Preferences.textMainSize,
|
v.next_event to Preferences.textMainSize,
|
||||||
v.next_event_difference_time to Preferences.textMainSize,
|
v.next_event_difference_time to Preferences.textMainSize,
|
||||||
v.next_event_date to Preferences.textSecondSize,
|
v.next_event_date to Preferences.textSecondSize,
|
||||||
v.divider2 to Preferences.textSecondSize,
|
v.divider2 to (Preferences.textSecondSize - 2),
|
||||||
v.calendar_temp to Preferences.textSecondSize
|
v.calendar_temp to Preferences.textSecondSize,
|
||||||
|
v.divider3 to (Preferences.textMainSize - 2),
|
||||||
|
v.special_temp to Preferences.textMainSize
|
||||||
).forEach {
|
).forEach {
|
||||||
it.first.setTextSize(TypedValue.COMPLEX_UNIT_SP, it.second)
|
it.first.setTextSize(TypedValue.COMPLEX_UNIT_SP, it.second)
|
||||||
}
|
}
|
||||||
@ -511,6 +565,9 @@ 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.scaleY = Preferences.textMainSize / 20f
|
||||||
|
|
||||||
|
|
||||||
// Shadows
|
// Shadows
|
||||||
val shadowRadius = when (Preferences.textShadow) {
|
val shadowRadius = when (Preferences.textShadow) {
|
||||||
@ -532,14 +589,14 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
else -> 0f
|
else -> 0f
|
||||||
}
|
}
|
||||||
|
|
||||||
listOf<TextView>(v.empty_date, v.divider1, v.temp, v.next_event, v.next_event_difference_time, v.next_event_date, v.divider2, v.calendar_temp).forEach {
|
listOf<TextView>(v.empty_date, v.divider1, v.temp, v.next_event, v.next_event_difference_time, v.next_event_date, v.divider2, v.calendar_temp, v.divider3, v.special_temp).forEach {
|
||||||
it.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
it.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom Font
|
// Custom Font
|
||||||
if (Preferences.customFont == Constants.CUSTOM_FONT_PRODUCT_SANS) {
|
if (Preferences.customFont == Constants.CUSTOM_FONT_PRODUCT_SANS) {
|
||||||
val productSans: Typeface = Typeface.createFromAsset(context.assets, "fonts/product_sans_regular.ttf")
|
val productSans: Typeface = Typeface.createFromAsset(context.assets, "fonts/product_sans_regular.ttf")
|
||||||
listOf<TextView>(v.empty_date, v.divider1, v.temp, v.next_event, v.next_event_difference_time, v.next_event_date, v.divider2, v.calendar_temp).forEach {
|
listOf<TextView>(v.empty_date, v.divider1, v.temp, v.next_event, v.next_event_difference_time, v.next_event_date, v.divider2, v.calendar_temp, v.divider3, v.special_temp).forEach {
|
||||||
it.typeface = productSans
|
it.typeface = productSans
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -548,24 +605,36 @@ class MainWidget : AppWidgetProvider() {
|
|||||||
if (Preferences.showWeather && Preferences.weatherIcon != "") {
|
if (Preferences.showWeather && Preferences.weatherIcon != "") {
|
||||||
v.weather.visibility = View.VISIBLE
|
v.weather.visibility = View.VISIBLE
|
||||||
v.calendar_weather.visibility = View.VISIBLE
|
v.calendar_weather.visibility = View.VISIBLE
|
||||||
|
v.special_weather.visibility = View.VISIBLE
|
||||||
val currentTemp = String.format(Locale.getDefault(), "%.0f °%s", Preferences.weatherTemp, Preferences.weatherRealTempUnit)
|
val currentTemp = String.format(Locale.getDefault(), "%.0f °%s", Preferences.weatherTemp, Preferences.weatherRealTempUnit)
|
||||||
|
|
||||||
val icon: String = Preferences.weatherIcon
|
val icon: String = Preferences.weatherIcon
|
||||||
if (icon == "") {
|
if (icon == "") {
|
||||||
v.weather_icon.visibility = View.GONE
|
v.weather_icon.visibility = View.GONE
|
||||||
v.empty_weather_icon.visibility = View.GONE
|
v.empty_weather_icon.visibility = View.GONE
|
||||||
|
v.special_weather_icon.visibility = View.GONE
|
||||||
} else {
|
} else {
|
||||||
v.weather_icon.setImageResource(WeatherHelper.getWeatherIconResource(icon))
|
v.weather_icon.setImageResource(WeatherHelper.getWeatherIconResource(icon))
|
||||||
v.empty_weather_icon.setImageResource(WeatherHelper.getWeatherIconResource(icon))
|
v.empty_weather_icon.setImageResource(WeatherHelper.getWeatherIconResource(icon))
|
||||||
|
v.special_weather_icon.setImageResource(WeatherHelper.getWeatherIconResource(icon))
|
||||||
v.weather_icon.visibility = View.VISIBLE
|
v.weather_icon.visibility = View.VISIBLE
|
||||||
v.empty_weather_icon.visibility = View.VISIBLE
|
v.empty_weather_icon.visibility = View.VISIBLE
|
||||||
|
v.special_weather_icon.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
v.temp.text = currentTemp
|
v.temp.text = currentTemp
|
||||||
v.calendar_temp.text = currentTemp
|
v.calendar_temp.text = currentTemp
|
||||||
|
v.special_temp.text = currentTemp
|
||||||
|
|
||||||
|
if (WidgetHelper.showSpecialWeather(context)) {
|
||||||
|
v.calendar_weather.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
v.special_weather.visibility = View.GONE
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
v.weather.visibility = View.GONE
|
v.weather.visibility = View.GONE
|
||||||
v.calendar_weather.visibility = View.GONE
|
v.calendar_weather.visibility = View.GONE
|
||||||
|
v.special_weather.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
return v
|
return v
|
||||||
|
BIN
app/src/main/res/drawable-hdpi/round_arrow_back.png
Normal file
After Width: | Height: | Size: 183 B |
BIN
app/src/main/res/drawable-hdpi/round_extension.png
Normal file
After Width: | Height: | Size: 279 B |
BIN
app/src/main/res/drawable-hdpi/round_extension_black_24.png
Normal file
After Width: | Height: | Size: 322 B |
BIN
app/src/main/res/drawable-hdpi/round_extension_black_36.png
Normal file
After Width: | Height: | Size: 435 B |
BIN
app/src/main/res/drawable-hdpi/round_extension_black_48.png
Normal file
After Width: | Height: | Size: 503 B |
BIN
app/src/main/res/drawable-hdpi/round_music_note.png
Normal file
After Width: | Height: | Size: 405 B |
BIN
app/src/main/res/drawable-hdpi/round_music_note_black_18.png
Normal file
After Width: | Height: | Size: 218 B |
BIN
app/src/main/res/drawable-hdpi/round_music_note_black_24.png
Normal file
After Width: | Height: | Size: 248 B |
BIN
app/src/main/res/drawable-hdpi/round_music_note_black_36.png
Normal file
After Width: | Height: | Size: 338 B |
BIN
app/src/main/res/drawable-hdpi/round_queue_music.png
Normal file
After Width: | Height: | Size: 360 B |
BIN
app/src/main/res/drawable-hdpi/round_queue_music_black_18.png
Normal file
After Width: | Height: | Size: 254 B |
BIN
app/src/main/res/drawable-hdpi/round_queue_music_black_24.png
Normal file
After Width: | Height: | Size: 257 B |
BIN
app/src/main/res/drawable-hdpi/round_queue_music_black_48.png
Normal file
After Width: | Height: | Size: 412 B |
BIN
app/src/main/res/drawable-hdpi/round_short_text.png
Normal file
After Width: | Height: | Size: 198 B |
BIN
app/src/main/res/drawable-hdpi/round_short_text_black_18.png
Normal file
After Width: | Height: | Size: 144 B |
BIN
app/src/main/res/drawable-hdpi/round_short_text_black_24.png
Normal file
After Width: | Height: | Size: 151 B |
BIN
app/src/main/res/drawable-hdpi/round_short_text_black_36.png
Normal file
After Width: | Height: | Size: 190 B |
BIN
app/src/main/res/drawable-mdpi/round_arrow_back.png
Normal file
After Width: | Height: | Size: 138 B |
BIN
app/src/main/res/drawable-mdpi/round_extension.png
Normal file
After Width: | Height: | Size: 220 B |
BIN
app/src/main/res/drawable-mdpi/round_extension_black_24.png
Normal file
After Width: | Height: | Size: 233 B |
BIN
app/src/main/res/drawable-mdpi/round_extension_black_36.png
Normal file
After Width: | Height: | Size: 322 B |
BIN
app/src/main/res/drawable-mdpi/round_extension_black_48.png
Normal file
After Width: | Height: | Size: 366 B |
BIN
app/src/main/res/drawable-mdpi/round_music_note.png
Normal file
After Width: | Height: | Size: 286 B |
BIN
app/src/main/res/drawable-mdpi/round_music_note_black_18.png
Normal file
After Width: | Height: | Size: 175 B |
BIN
app/src/main/res/drawable-mdpi/round_music_note_black_24.png
Normal file
After Width: | Height: | Size: 181 B |
BIN
app/src/main/res/drawable-mdpi/round_music_note_black_36.png
Normal file
After Width: | Height: | Size: 248 B |
BIN
app/src/main/res/drawable-mdpi/round_queue_music.png
Normal file
After Width: | Height: | Size: 257 B |
BIN
app/src/main/res/drawable-mdpi/round_queue_music_black_18.png
Normal file
After Width: | Height: | Size: 168 B |
BIN
app/src/main/res/drawable-mdpi/round_queue_music_black_24.png
Normal file
After Width: | Height: | Size: 165 B |
BIN
app/src/main/res/drawable-mdpi/round_queue_music_black_48.png
Normal file
After Width: | Height: | Size: 283 B |
BIN
app/src/main/res/drawable-mdpi/round_short_text.png
Normal file
After Width: | Height: | Size: 148 B |
BIN
app/src/main/res/drawable-mdpi/round_short_text_black_18.png
Normal file
After Width: | Height: | Size: 112 B |
BIN
app/src/main/res/drawable-mdpi/round_short_text_black_24.png
Normal file
After Width: | Height: | Size: 102 B |
BIN
app/src/main/res/drawable-mdpi/round_short_text_black_36.png
Normal file
After Width: | Height: | Size: 151 B |
BIN
app/src/main/res/drawable-xhdpi/round_arrow_back.png
Normal file
After Width: | Height: | Size: 221 B |
BIN
app/src/main/res/drawable-xhdpi/round_extension.png
Normal file
After Width: | Height: | Size: 322 B |
BIN
app/src/main/res/drawable-xhdpi/round_extension_black_24.png
Normal file
After Width: | Height: | Size: 366 B |
BIN
app/src/main/res/drawable-xhdpi/round_extension_black_36.png
Normal file
After Width: | Height: | Size: 503 B |
BIN
app/src/main/res/drawable-xhdpi/round_extension_black_48.png
Normal file
After Width: | Height: | Size: 605 B |
BIN
app/src/main/res/drawable-xhdpi/round_music_note.png
Normal file
After Width: | Height: | Size: 525 B |
BIN
app/src/main/res/drawable-xhdpi/round_music_note_black_18.png
Normal file
After Width: | Height: | Size: 248 B |
BIN
app/src/main/res/drawable-xhdpi/round_music_note_black_24.png
Normal file
After Width: | Height: | Size: 286 B |
BIN
app/src/main/res/drawable-xhdpi/round_music_note_black_36.png
Normal file
After Width: | Height: | Size: 405 B |
BIN
app/src/main/res/drawable-xhdpi/round_queue_music.png
Normal file
After Width: | Height: | Size: 412 B |
BIN
app/src/main/res/drawable-xhdpi/round_queue_music_black_18.png
Normal file
After Width: | Height: | Size: 257 B |
BIN
app/src/main/res/drawable-xhdpi/round_queue_music_black_24.png
Normal file
After Width: | Height: | Size: 283 B |
BIN
app/src/main/res/drawable-xhdpi/round_queue_music_black_48.png
Normal file
After Width: | Height: | Size: 507 B |
BIN
app/src/main/res/drawable-xhdpi/round_short_text.png
Normal file
After Width: | Height: | Size: 233 B |
BIN
app/src/main/res/drawable-xhdpi/round_short_text_black_18.png
Normal file
After Width: | Height: | Size: 151 B |
BIN
app/src/main/res/drawable-xhdpi/round_short_text_black_24.png
Normal file
After Width: | Height: | Size: 148 B |
BIN
app/src/main/res/drawable-xhdpi/round_short_text_black_36.png
Normal file
After Width: | Height: | Size: 198 B |
BIN
app/src/main/res/drawable-xxhdpi/round_arrow_back.png
Normal file
After Width: | Height: | Size: 275 B |
BIN
app/src/main/res/drawable-xxhdpi/round_extension.png
Normal file
After Width: | Height: | Size: 435 B |
BIN
app/src/main/res/drawable-xxhdpi/round_extension_black_24.png
Normal file
After Width: | Height: | Size: 503 B |
BIN
app/src/main/res/drawable-xxhdpi/round_extension_black_36.png
Normal file
After Width: | Height: | Size: 753 B |
BIN
app/src/main/res/drawable-xxhdpi/round_extension_black_48.png
Normal file
After Width: | Height: | Size: 933 B |
BIN
app/src/main/res/drawable-xxhdpi/round_music_note.png
Normal file
After Width: | Height: | Size: 774 B |
BIN
app/src/main/res/drawable-xxhdpi/round_music_note_black_18.png
Normal file
After Width: | Height: | Size: 338 B |
BIN
app/src/main/res/drawable-xxhdpi/round_music_note_black_24.png
Normal file
After Width: | Height: | Size: 405 B |
BIN
app/src/main/res/drawable-xxhdpi/round_music_note_black_36.png
Normal file
After Width: | Height: | Size: 588 B |
BIN
app/src/main/res/drawable-xxhdpi/round_queue_music.png
Normal file
After Width: | Height: | Size: 618 B |
BIN
app/src/main/res/drawable-xxhdpi/round_queue_music_black_18.png
Normal file
After Width: | Height: | Size: 360 B |
BIN
app/src/main/res/drawable-xxhdpi/round_queue_music_black_24.png
Normal file
After Width: | Height: | Size: 412 B |
BIN
app/src/main/res/drawable-xxhdpi/round_queue_music_black_48.png
Normal file
After Width: | Height: | Size: 789 B |
BIN
app/src/main/res/drawable-xxhdpi/round_short_text.png
Normal file
After Width: | Height: | Size: 339 B |
BIN
app/src/main/res/drawable-xxhdpi/round_short_text_black_18.png
Normal file
After Width: | Height: | Size: 190 B |
BIN
app/src/main/res/drawable-xxhdpi/round_short_text_black_24.png
Normal file
After Width: | Height: | Size: 198 B |
BIN
app/src/main/res/drawable-xxhdpi/round_short_text_black_36.png
Normal file
After Width: | Height: | Size: 283 B |