From 0173c4032f7fad8e00eea7d2f340732e9f40948b Mon Sep 17 00:00:00 2001 From: ashnohe Date: Tue, 7 Oct 2025 16:26:35 -0700 Subject: [PATCH 1/3] add widgets metrics api snippet --- compose/snippets/build.gradle.kts | 4 +- .../compose/snippets/glance/GlanceMetrics.kt | 75 +++++++++++++++++++ gradle/libs.versions.toml | 2 +- 3 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 compose/snippets/src/main/java/com/example/compose/snippets/glance/GlanceMetrics.kt diff --git a/compose/snippets/build.gradle.kts b/compose/snippets/build.gradle.kts index 2ae85583..7a5062f6 100644 --- a/compose/snippets/build.gradle.kts +++ b/compose/snippets/build.gradle.kts @@ -25,7 +25,9 @@ plugins { } android { - compileSdk = libs.versions.compileSdk.get().toInt() + compileSdk { + version = release(libs.versions.compileSdk.get().toInt()) + {minorApiLevel = 1}} // Android 16 QPR 2 namespace = "com.example.compose.snippets" defaultConfig { diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/glance/GlanceMetrics.kt b/compose/snippets/src/main/java/com/example/compose/snippets/glance/GlanceMetrics.kt new file mode 100644 index 00000000..e0a28e1a --- /dev/null +++ b/compose/snippets/src/main/java/com/example/compose/snippets/glance/GlanceMetrics.kt @@ -0,0 +1,75 @@ +package com.example.compose.snippets.glance + +import android.appwidget.AppWidgetManager +import android.content.Context +import android.util.Log + +private const val TAG = "WidgetMetrics" + +class GlanceMetrics { + + // [START android_compose_glance_metrics] + fun getWidgetEngagementMetrics(context: Context){ + val manager = AppWidgetManager.getInstance(context) + + val endTime = System.currentTimeMillis() + val startTime = endTime - (24 * 60 * 60 * 1000) // a day ago + + val events = manager.queryAppWidgetEvents(startTime, endTime) + + if (events.isEmpty()) { + Log.d(TAG, "No events found for the given time range.") + } + + val metrics = hashMapOf( + "clicks" to 0L, + "scrolls" to 0L, + "totalImpressionLength" to 0L + ) + + for (event in events){ + + Log.d(TAG, "Event Start: ${event.start}") + Log.d(TAG, "Event End: ${event.end}") + + val widgetId = event.appWidgetId + + // Tap actions + val clickedIds = event.clickedIds + if (clickedIds?.isNotEmpty() == true) { + metrics["clicks"] = metrics.getValue("clicks") + clickedIds.size + // Log or analyze which components were clicked. + for (id in clickedIds) { + Log.d(TAG,"Widget $widgetId: Tap event on component with ID $id") + } + } + + // Scroll events + val scrolledIds = event.scrolledIds + if (scrolledIds?.isNotEmpty() == true) { + metrics["scrolls"] = metrics.getValue("scrolls") + scrolledIds.size + // Log or analyze which lists were scrolled. + for (id in scrolledIds) { + Log.d(TAG, "Widget $widgetId: Scroll event in list with ID/tag $id") + } + } + + // Impressions + metrics["totalImpressionLength"] = metrics.getValue("totalImpressionLength") + event.visibleDuration.toMillis() + Log.d(TAG, + "Widget $widgetId: Impression event with duration " + event.visibleDuration.toMillis() + "ms" + ) + + + // Position + val position = event.position + if (position != null) { + Log.d(TAG, + "Widget $widgetId: left=${position.left}, right=${position.right}, top=${position.top}, bottom=${position.bottom}" + ) + } + } + Log.d("WidgetMetrics", "Metrics: $metrics") + } + // [END android_compose_glance_metrics] +} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0d03a91a..5b9e919b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -35,7 +35,7 @@ androidxHiltNavigationCompose = "1.3.0" appcompat = "1.7.1" coil = "2.7.0" # @keep -compileSdk = "36" +compileSdk = "36" # gradle.kts for Module :compose:snippets uses Android 16 QPR 2 compose-latest = "1.9.2" composeUiTooling = "1.5.2" coreSplashscreen = "1.0.1" From 69dcd215953d19e3b19891447e43f7a724411616 Mon Sep 17 00:00:00 2001 From: ashnohe <83780687+ashnohe@users.noreply.github.com> Date: Tue, 7 Oct 2025 23:30:05 +0000 Subject: [PATCH 2/3] Apply Spotless --- .../compose/snippets/glance/GlanceMetrics.kt | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/glance/GlanceMetrics.kt b/compose/snippets/src/main/java/com/example/compose/snippets/glance/GlanceMetrics.kt index e0a28e1a..c9cb3414 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/glance/GlanceMetrics.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/glance/GlanceMetrics.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.example.compose.snippets.glance import android.appwidget.AppWidgetManager @@ -9,7 +25,7 @@ private const val TAG = "WidgetMetrics" class GlanceMetrics { // [START android_compose_glance_metrics] - fun getWidgetEngagementMetrics(context: Context){ + fun getWidgetEngagementMetrics(context: Context) { val manager = AppWidgetManager.getInstance(context) val endTime = System.currentTimeMillis() @@ -27,7 +43,7 @@ class GlanceMetrics { "totalImpressionLength" to 0L ) - for (event in events){ + for (event in events) { Log.d(TAG, "Event Start: ${event.start}") Log.d(TAG, "Event End: ${event.end}") @@ -40,7 +56,7 @@ class GlanceMetrics { metrics["clicks"] = metrics.getValue("clicks") + clickedIds.size // Log or analyze which components were clicked. for (id in clickedIds) { - Log.d(TAG,"Widget $widgetId: Tap event on component with ID $id") + Log.d(TAG, "Widget $widgetId: Tap event on component with ID $id") } } @@ -56,15 +72,16 @@ class GlanceMetrics { // Impressions metrics["totalImpressionLength"] = metrics.getValue("totalImpressionLength") + event.visibleDuration.toMillis() - Log.d(TAG, + Log.d( + TAG, "Widget $widgetId: Impression event with duration " + event.visibleDuration.toMillis() + "ms" ) - // Position val position = event.position if (position != null) { - Log.d(TAG, + Log.d( + TAG, "Widget $widgetId: left=${position.left}, right=${position.right}, top=${position.top}, bottom=${position.bottom}" ) } @@ -72,4 +89,4 @@ class GlanceMetrics { Log.d("WidgetMetrics", "Metrics: $metrics") } // [END android_compose_glance_metrics] -} \ No newline at end of file +} From 3e1660cdb6096fa388da5ea2fc0fdf02d7b7dce7 Mon Sep 17 00:00:00 2001 From: ashnohe Date: Wed, 8 Oct 2025 11:53:02 -0700 Subject: [PATCH 3/3] update android_compose_glance_metrics to use RequiresApi Baklava --- .../java/com/example/compose/snippets/glance/GlanceMetrics.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/glance/GlanceMetrics.kt b/compose/snippets/src/main/java/com/example/compose/snippets/glance/GlanceMetrics.kt index c9cb3414..3541cceb 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/glance/GlanceMetrics.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/glance/GlanceMetrics.kt @@ -18,13 +18,16 @@ package com.example.compose.snippets.glance import android.appwidget.AppWidgetManager import android.content.Context +import android.os.Build import android.util.Log +import androidx.annotation.RequiresApi private const val TAG = "WidgetMetrics" class GlanceMetrics { // [START android_compose_glance_metrics] + @RequiresApi(Build.VERSION_CODES_FULL.BAKLAVA_1) fun getWidgetEngagementMetrics(context: Context) { val manager = AppWidgetManager.getInstance(context)