Nizam
05/24/2024, 8:53 AMNizam
05/24/2024, 8:55 AM<receiver
android:name="ai.blox100.widgetReceiver.UsageResizableWidgetReceiver4x2"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/usage_most_used_apps_widget_info" />
</receiver>
@AndroidEntryPoint
class UsageResizableWidgetReceiver4x2 : GlanceAppWidgetReceiver() {
@Inject
lateinit var logUserEvent: LogAnalyticsUserProperty
@Inject
lateinit var logAnalyticsEvent: LogAnalyticsEvent
override val glanceAppWidget: GlanceAppWidget = UsageResizableWidget()
override fun onDeleted(context: Context, appWidgetIds: IntArray) {
super.onDeleted(context, appWidgetIds)
val props = JSONObject()
props.put("source", "big_widget")
props.put("action", "removed")
logUserEvent(AnalyticsEvent.USER_PROPERTY_WIDGET_STATUS_BIG, "removed", props)
}
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray,
) {
super.onUpdate(context, appWidgetManager, appWidgetIds)
val props = JSONObject()
props.put("source", "big_widget")
props.put("action", "added")
logUserEvent(AnalyticsEvent.USER_PROPERTY_WIDGET_STATUS_BIG, "added", props)
}
override fun onReceive(context: Context, intent: Intent) {
super.onReceive(context, intent)
if (intent.action == StringConstants.ACTION_WIDGET_PINNED) {
Log.d("widgetPromo", "Widget pinned successfully!")
val props = JSONObject()
props.put("source", "big_widget")
props.put("action", "success")
logAnalyticsEvent(AnalyticsEvent.WIDGET_ADD_STATUS, props)
// Handle the widget being successfully pinned
Toast.makeText(context, "Widget pinned successfully in Home screen!", Toast.LENGTH_SHORT).show()
}
}
}
class UsageResizableWidget : GlanceAppWidget() {
companion object {
private val SMALL_SQUARE = DpSize(130.dp, 120.dp)
private val HORIZONTAL_RECTANGLE = DpSize(230.dp, 120.dp)
}
override val sizeMode = SizeMode.Responsive(
setOf(
SMALL_SQUARE,
HORIZONTAL_RECTANGLE,
),
)
@EntryPoint
@InstallIn(SingletonComponent::class)
interface UsageWithMostUsedAppsWidgetProviderEntryPoint {
fun usageWidgetRepository(): UsageWidgetRepository
}
override var stateDefinition: GlanceStateDefinition<*> = PreferencesGlanceStateDefinition
override suspend fun provideGlance(context: Context, id: GlanceId) {
Log.d("GlanceUsageWithMostUsedAppsWidget", "provideGlance: called")
val appContext = context.applicationContext ?: throw IllegalStateException()
val usageWidgetEntryPoint =
EntryPointAccessors.fromApplication(
appContext,
UsageWithMostUsedAppsWidgetProviderEntryPoint::class.java,
)
val usageWidgetRepository = usageWidgetEntryPoint.usageWidgetRepository()
// set value
val usageData = withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
Log.d("GlanceUsageWithMostUsedAppsWidget", "getUsageData: called")
usageWidgetRepository.getUsageData()
}
Toast.makeText(
context,
"got usage data",
Toast.LENGTH_SHORT,
).show()
// display value
provideContent {
val prefs = currentState<Preferences>()
val usageWidgetData = prefs[usageWidgetKey] ?: usageWidgetDataToJson(usageData)
Toast.makeText(
context,
"provideContent: usageData",
Toast.LENGTH_SHORT,
).show()
val data = jsonToUsageWidgetData(usageWidgetData)
Log.d("GlanceUsageWithMostUsedAppsWidget", "data: $data")
val size = LocalSize.current
if (data != null) {
val usageScreenTimeString = DateTimeUtil.getHumanReadableString(
appUsageInMinutes = data.totalPhoneUsageInMillis.toMinutes(),
smallFormat = true,
highlight = true,
)
Toast.makeText(
context,
"data not null",
Toast.LENGTH_SHORT,
).show()
val mostUsedApps = data.mostUsedApps
Log.d(
"GlanceUsageWithMostUsedAppsWidget",
"UsageTime: $usageScreenTimeString, mostUsedApps: ${data.mostUsedApps}",
)
Row(
modifier = GlanceModifier
.fillMaxWidth()
.background(neutral5)
.cornerRadiusCompat(R.drawable.rounded_background, 16.dp, neutral5)
.padding(20.dp)
.clickable(
onClick = actionStartActivity<HomePageActivity>(
actionParametersOf(openAppUsageScreenKey to true),
),
),
horizontalAlignment = Alignment.Horizontal.Start,
verticalAlignment = Alignment.Vertical.CenterVertically,
) {
Column(
modifier = GlanceModifier.width(124.dp),
) {
Box(
modifier = GlanceModifier
.cornerRadius(56.dp)
.padding(10.dp)
.background(primary_green_dark),
) {
Image(
provider = ImageProvider(resId = R.drawable.logo_big),
contentDescription = null,
modifier = GlanceModifier.size(14.dp),
)
}
Spacer(modifier = GlanceModifier.height(12.dp))
GlanceTextWithVariableColors(
textSegments = glanceParseAndHighlightText(
text = usageScreenTimeString,
normalColor = neutral100,
highlightColor = neutral100,
normalStyle = glanceHeadlineSmallBold,
highlightStyle = glanceDisplaySmallBold,
),
)
Spacer(modifier = GlanceModifier.height(2.dp))
GlanceText(
text = "Today's Usage",
color = primary_green,
textStyle = glanceBodyXs,
)
}
Spacer(modifier = GlanceModifier.defaultWeight())
if (size.width >= HORIZONTAL_RECTANGLE.width) {
Column(
modifier = GlanceModifier,
verticalAlignment = Alignment.CenterVertically,
) {
if (mostUsedApps.isNotEmpty()) {
mostUsedApps.forEach { item ->
AppUsageRow(appUsageData = item, context = context)
if (item != mostUsedApps.last()) {
Spacer(modifier = GlanceModifier.height(14.dp))
}
}
}
}
}
Spacer(modifier = GlanceModifier.defaultWeight())
}
} else {
Toast.makeText(
context,
"data null",
Toast.LENGTH_SHORT,
).show()
}
}
}
}
Nizam
05/24/2024, 8:55 AMKimon
05/24/2024, 2:47 PMNizam
05/24/2024, 3:08 PMGlanceAppWidgetManager(context = context).getGlanceIds(UsageResizableWidget::class.java)
.forEach { glanceId ->
Log.d("GlanceWidgetUpdate", "GlanceId usageWithMostUsed $glanceId")
updateAppWidgetState(context, glanceId) { prefs ->
prefs[usageWidgetKey] = usageData
}
UsageResizableWidget().update(context, glanceId)
}
Nizam
05/27/2024, 4:20 PMKimon
05/27/2024, 4:23 PMNizam
05/27/2024, 4:26 PMNizam
10/15/2024, 9:03 AMWojciech Krystyniak
01/21/2025, 1:07 PMNizam
01/21/2025, 6:02 PMWojciech Krystyniak
01/21/2025, 7:23 PM