From a2ed821d18cac6506f6657497a5062bff60bb2fd Mon Sep 17 00:00:00 2001 From: Harsh Panchal Date: Sun, 10 Mar 2024 12:33:00 +0530 Subject: [PATCH] Implemented Home screen widget to display current active spot --- app/build.gradle.kts | 3 + app/src/main/AndroidManifest.xml | 19 ++- .../java/dev/harsh/tradow/MainActivity.kt | 11 +- .../dev/harsh/tradow/widget/TradowWidget.kt | 116 ++++++++++++++++++ .../tradow/widget/TradowWidgetReceiver.kt | 9 ++ app/src/main/res/drawable/location.xml | 12 +- app/src/main/res/drawable/refresh.xml | 5 + app/src/main/res/layout/preview_widget.xml | 18 +++ app/src/main/res/xml/app_widget_provider.xml | 21 ++++ gradle/libs.versions.toml | 3 + 10 files changed, 207 insertions(+), 10 deletions(-) create mode 100644 app/src/main/java/dev/harsh/tradow/widget/TradowWidget.kt create mode 100644 app/src/main/java/dev/harsh/tradow/widget/TradowWidgetReceiver.kt create mode 100644 app/src/main/res/drawable/refresh.xml create mode 100644 app/src/main/res/layout/preview_widget.xml create mode 100644 app/src/main/res/xml/app_widget_provider.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a2e1cda..ab2c5fd 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -77,4 +77,7 @@ dependencies { implementation(libs.accompanist.permissions) implementation(libs.accompanist.systemuicontroller) implementation(libs.gson) + + implementation(libs.androidx.glance) + implementation(libs.androidx.glance.appwidget) } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b4a55ba..f0ad313 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -41,15 +41,28 @@ + android:permission="android.permission.BIND_QUICK_SETTINGS_TILE" + android:roundIcon="@drawable/location"> + + + + + + + + diff --git a/app/src/main/java/dev/harsh/tradow/MainActivity.kt b/app/src/main/java/dev/harsh/tradow/MainActivity.kt index 3a2ba85..c3c8649 100644 --- a/app/src/main/java/dev/harsh/tradow/MainActivity.kt +++ b/app/src/main/java/dev/harsh/tradow/MainActivity.kt @@ -45,6 +45,7 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.core.content.ContextCompat +import androidx.core.content.edit import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController @@ -110,6 +111,7 @@ class MainActivity : ComponentActivity() { var pressedTime: Long = 0 BackHandler(enabled = true) { + sharedPref.edit(commit = true) {} if (pressedTime + 1800 > System.currentTimeMillis()) finish() else @@ -142,10 +144,17 @@ class MainActivity : ComponentActivity() { override fun onPause() { super.onPause() + sharedPref.edit(commit = true) {} + if (checkLocationPermission()) moveTaskToBack(true) } + override fun onDestroy() { + super.onDestroy() + sharedPref.edit(commit = true) {} + } + @Composable fun HomeScreen(forOpenBottomSheet: () -> Unit) { var hasLocationPermission = false @@ -179,7 +188,7 @@ class MainActivity : ComponentActivity() { } } - else -> this@MainActivity.showShortToast("Kindly choose a site to monitor!") + else -> this@MainActivity.showShortToast("Kindly choose a spot to track!") } } else { locationPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION) diff --git a/app/src/main/java/dev/harsh/tradow/widget/TradowWidget.kt b/app/src/main/java/dev/harsh/tradow/widget/TradowWidget.kt new file mode 100644 index 0000000..41e9039 --- /dev/null +++ b/app/src/main/java/dev/harsh/tradow/widget/TradowWidget.kt @@ -0,0 +1,116 @@ +package dev.harsh.tradow.widget + +import android.content.Context +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.glance.GlanceId +import androidx.glance.GlanceModifier +import androidx.glance.GlanceTheme +import androidx.glance.Image +import androidx.glance.ImageProvider +import androidx.glance.action.clickable +import androidx.glance.appwidget.GlanceAppWidget +import androidx.glance.appwidget.provideContent +import androidx.glance.background +import androidx.glance.layout.Alignment +import androidx.glance.layout.Box +import androidx.glance.layout.Row +import androidx.glance.layout.fillMaxWidth +import androidx.glance.layout.padding +import androidx.glance.state.GlanceStateDefinition +import androidx.glance.state.PreferencesGlanceStateDefinition +import androidx.glance.text.FontWeight +import androidx.glance.text.Text +import androidx.glance.text.TextStyle +import androidx.glance.unit.ColorProvider +import com.example.geofencing.R +import dev.harsh.tradow.model.Spot +import dev.harsh.tradow.util.SharedPreferencesHelper + +class TradowWidget : GlanceAppWidget() { + + /** GlanceStateDefinition - Telling GlanceState how to store-retrieve data. + - Once the object is created, the data is updating using the state directly. + * PreferencesGlanceStateDefinition - For creating a widget using datastore preference + */ + override val stateDefinition: GlanceStateDefinition<*> = PreferencesGlanceStateDefinition + private var activeSpot: Spot? = null + + override suspend fun provideGlance(context: Context, id: GlanceId) { + provideContent { + + activeSpot = SharedPreferencesHelper.getActiveSpot(context) + + LaunchedEffect(activeSpot) { + activeSpot = SharedPreferencesHelper.getActiveSpot(context) + } + + GlanceTheme { + WidgetCard(context, activeSpot) + } + } + } + + @Composable + fun WidgetCard(context: Context, spot: Spot?) { + Row( + modifier = GlanceModifier + .fillMaxWidth() + .padding(12.dp) + .background(Color.White), + horizontalAlignment = Alignment.CenterHorizontally, + verticalAlignment = Alignment.CenterVertically + ) { + if (spot != null) { + + Text( + text = spot.title, + modifier = GlanceModifier.padding(4.dp), + style = TextStyle( + fontWeight = FontWeight.Bold, + fontSize = 20.sp, + color = ColorProvider(Color.Green.copy(0.8F)) + ) + ) + + Box( + modifier = GlanceModifier + .padding(horizontal = 8.dp) + .clickable { + activeSpot = SharedPreferencesHelper.getActiveSpot(context) + } + ) { + Image( + provider = ImageProvider(R.drawable.refresh), contentDescription = "" + ) + } + + } else { + Row { + Text( + text = "Add/Select spot to continue", + style = TextStyle( + fontWeight = FontWeight.Bold, + fontSize = 16.sp + ) + ) + Box( + modifier = GlanceModifier + .clickable { + activeSpot = SharedPreferencesHelper.getActiveSpot(context) + } + ) { + Image( + provider = ImageProvider(R.drawable.location), contentDescription = "" + ) + } + } + } + + } + } + +} diff --git a/app/src/main/java/dev/harsh/tradow/widget/TradowWidgetReceiver.kt b/app/src/main/java/dev/harsh/tradow/widget/TradowWidgetReceiver.kt new file mode 100644 index 0000000..e4b8263 --- /dev/null +++ b/app/src/main/java/dev/harsh/tradow/widget/TradowWidgetReceiver.kt @@ -0,0 +1,9 @@ +package dev.harsh.tradow.widget + +import androidx.glance.appwidget.GlanceAppWidget +import androidx.glance.appwidget.GlanceAppWidgetReceiver + +class TradowWidgetReceiver: GlanceAppWidgetReceiver() { + override val glanceAppWidget: GlanceAppWidget + get() = TradowWidget() +} diff --git a/app/src/main/res/drawable/location.xml b/app/src/main/res/drawable/location.xml index 0103e62..e1e4332 100644 --- a/app/src/main/res/drawable/location.xml +++ b/app/src/main/res/drawable/location.xml @@ -3,10 +3,10 @@ android:height="32dp" android:viewportWidth="8.467" android:viewportHeight="8.467"> - + diff --git a/app/src/main/res/drawable/refresh.xml b/app/src/main/res/drawable/refresh.xml new file mode 100644 index 0000000..92f937d --- /dev/null +++ b/app/src/main/res/drawable/refresh.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/layout/preview_widget.xml b/app/src/main/res/layout/preview_widget.xml new file mode 100644 index 0000000..b116f47 --- /dev/null +++ b/app/src/main/res/layout/preview_widget.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/xml/app_widget_provider.xml b/app/src/main/res/xml/app_widget_provider.xml new file mode 100644 index 0000000..467e662 --- /dev/null +++ b/app/src/main/res/xml/app_widget_provider.xml @@ -0,0 +1,21 @@ + + + + diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 115a354..d551f30 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,6 +5,7 @@ activity-compose = "1.8.2" androidx-junit = "1.1.5" core-ktx = "1.12.0" espresso-core = "3.5.1" +glanceVersion = "1.1.0-alpha01" gson = "2.10" junit = "4.13.2" lifecycle-runtime-ktx = "2.7.0" @@ -21,6 +22,8 @@ accompanist-permissions = { module = "com.google.accompanist:accompanist-permiss androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "activity-compose" } androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "core-ktx" } androidx-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "espresso-core" } +androidx-glance = { module = "androidx.glance:glance", version.ref = "glanceVersion" } +androidx-glance-appwidget = { module = "androidx.glance:glance-appwidget", version.ref = "glanceVersion" } androidx-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-junit" } androidx-lifecycle-runtime-ktx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycle-runtime-ktx" } androidx-material-icons-extended = { module = "androidx.compose.material:material-icons-extended", version.ref = "material-icons-extended" }