feat: Add Android example for configurable widgets#411
Conversation
|
To view this pull requests documentation preview, visit the following URL: docs.page/abausg/home_widget~411 Documentation is deployed and generated using docs.page. |
WalkthroughIntroduces documentation and a full Flutter example that implement configurable Android home widgets using a dedicated Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant Android as Android System
participant ConfigActivity as WidgetConfigurationActivity
participant Dart as Dart (configureMain)
participant HomeWidget as HomeWidget Plugin
participant Storage as Local Storage
participant Widget as Glance Widget
User->>Android: Initiate widget placement/configuration
Android->>ConfigActivity: Start activity with appWidgetId
ConfigActivity->>Dart: Launch Dart entrypoint configureMain()
Dart->>HomeWidget: initiallyLaunchedFromHomeWidgetConfigure()
HomeWidget-->>Dart: Return widgetId (or null)
alt widgetId present
Dart->>Dart: Show AndroidConfigurationPage(widgetId)
User->>Dart: Enter config & Tap Save
Dart->>HomeWidget: saveWidgetData(name.{id}, value)
Dart->>HomeWidget: saveWidgetData(punctuation.{id}, value)
HomeWidget->>Storage: Persist per-widget keys
Dart->>HomeWidget: updateWidget(qualifiedAndroidName)
HomeWidget->>Widget: Trigger refresh
Dart->>HomeWidget: finishHomeWidgetConfigure()
HomeWidget-->>ConfigActivity: Return RESULT_OK
ConfigActivity-->>Android: Close activity
else fallback
Dart->>Dart: Call main() (normal app flow)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
examples/configurable_widget/android/settings.gradle.kts (1)
4-7: Add an explicitlocal.propertiesexistence guard for clearer failure mode.Line 5 opens the file before validation, so missing-file failures are less actionable than they could be.
Proposed refinement
pluginManagement { val flutterSdkPath = run { val properties = java.util.Properties() - file("local.properties").inputStream().use { properties.load(it) } + val localProperties = file("local.properties") + require(localProperties.exists()) { "local.properties not found" } + localProperties.inputStream().use { properties.load(it) } val flutterSdkPath = properties.getProperty("flutter.sdk") require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } flutterSdkPath }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/configurable_widget/android/settings.gradle.kts` around lines 4 - 7, The code opens local.properties before checking, so missing-file errors are unclear; update the block around val properties, file("local.properties").inputStream(), and val flutterSdkPath to first check file("local.properties").exists() and throw or require with a clear message if missing, then load the properties only when the file exists and finally require(flutterSdkPath != null) with the existing message; this ensures a clear, explicit failure when local.properties is absent and preserves the flutterSdkPath null check.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@examples/configurable_widget/android/settings.gradle.kts`:
- Around line 4-7: The code opens local.properties before checking, so
missing-file errors are unclear; update the block around val properties,
file("local.properties").inputStream(), and val flutterSdkPath to first check
file("local.properties").exists() and throw or require with a clear message if
missing, then load the properties only when the file exists and finally
require(flutterSdkPath != null) with the existing message; this ensures a clear,
explicit failure when local.properties is absent and preserves the
flutterSdkPath null check.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: eb26b858-3e82-4af4-898e-cbf9e92d86fe
⛔ Files ignored due to path filters (5)
examples/configurable_widget/android/app/src/main/res/mipmap-hdpi/ic_launcher.pngis excluded by!**/*.pngexamples/configurable_widget/android/app/src/main/res/mipmap-mdpi/ic_launcher.pngis excluded by!**/*.pngexamples/configurable_widget/android/app/src/main/res/mipmap-xhdpi/ic_launcher.pngis excluded by!**/*.pngexamples/configurable_widget/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.pngis excluded by!**/*.pngexamples/configurable_widget/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.pngis excluded by!**/*.png
📒 Files selected for processing (22)
docs/features/configurable-widgets.mdxexamples/configurable_widget/.metadataexamples/configurable_widget/android/.gitignoreexamples/configurable_widget/android/app/build.gradle.ktsexamples/configurable_widget/android/app/src/debug/AndroidManifest.xmlexamples/configurable_widget/android/app/src/main/AndroidManifest.xmlexamples/configurable_widget/android/app/src/main/kotlin/es/antonborri/configurable_widget/ConfigurableWidgetHomeWidget.ktexamples/configurable_widget/android/app/src/main/kotlin/es/antonborri/configurable_widget/ConfigurableWidgetHomeWidgetReceiver.ktexamples/configurable_widget/android/app/src/main/kotlin/es/antonborri/configurable_widget/MainActivity.ktexamples/configurable_widget/android/app/src/main/kotlin/es/antonborri/configurable_widget/WidgetConfigurationActivity.ktexamples/configurable_widget/android/app/src/main/res/drawable-v21/launch_background.xmlexamples/configurable_widget/android/app/src/main/res/drawable/launch_background.xmlexamples/configurable_widget/android/app/src/main/res/values-night/styles.xmlexamples/configurable_widget/android/app/src/main/res/values/styles.xmlexamples/configurable_widget/android/app/src/main/res/xml/configurable_widget_home_widget.xmlexamples/configurable_widget/android/app/src/profile/AndroidManifest.xmlexamples/configurable_widget/android/build.gradle.ktsexamples/configurable_widget/android/gradle.propertiesexamples/configurable_widget/android/gradle/wrapper/gradle-wrapper.propertiesexamples/configurable_widget/android/settings.gradle.ktsexamples/configurable_widget/lib/android_configuration_page.dartexamples/configurable_widget/lib/main.dart
👮 Files not reviewed due to content moderation or server errors (5)
- examples/configurable_widget/lib/android_configuration_page.dart
- examples/configurable_widget/android/app/src/main/kotlin/es/antonborri/configurable_widget/ConfigurableWidgetHomeWidget.kt
- examples/configurable_widget/android/app/src/main/AndroidManifest.xml
- docs/features/configurable-widgets.mdx
- examples/configurable_widget/lib/main.dart
There was a problem hiding this comment.
🧹 Nitpick comments (1)
examples/configurable_widget/lib/main.dart (1)
92-112: Consider addingkIsWebguard for consistency.Unlike
configureMain()which guardsPlatformchecks with!kIsWeb, this method accessesPlatform.isAndroidandPlatform.isIOSdirectly. If the app were ever run on web, this would throw at runtime sincedart:io'sPlatformis unavailable there.While unlikely for a home widget example, adding a guard would be consistent with the pattern used elsewhere in this file.
♻️ Suggested guard
Future<void> _getInstalledWidgets() async { try { final installedWidgets = await HomeWidget.getInstalledWidgets(); final entries = <_InstalledWidgetEntry>[]; for (final w in installedWidgets) { Map<String, dynamic>? configuration; - if (Platform.isAndroid && w.androidWidgetId != null) { + if (!kIsWeb && Platform.isAndroid && w.androidWidgetId != null) { configuration = await _androidConfigurationFromStorage(w.androidWidgetId!); - } else if (Platform.isIOS && w.configuration != null) { + } else if (!kIsWeb && Platform.isIOS && w.configuration != null) { configuration = Map<String, dynamic>.from(w.configuration!); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/configurable_widget/lib/main.dart` around lines 92 - 112, The Platform.isAndroid / Platform.isIOS checks used while processing HomeWidget.getInstalledWidgets can throw on web; guard them with a kIsWeb check (e.g. only access Platform when !kIsWeb) so the configuration lookup via _androidConfigurationFromStorage and the Map copy from w.configuration are only executed on non-web. Add the package:flutter/foundation.dart import for kIsWeb if missing and update the conditional logic around Platform.isAndroid / Platform.isIOS to use !kIsWeb && Platform.isAndroid / !kIsWeb && Platform.isIOS before calling _androidConfigurationFromStorage or reading w.configuration, keeping the rest of the setState flow unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@examples/configurable_widget/lib/main.dart`:
- Around line 92-112: The Platform.isAndroid / Platform.isIOS checks used while
processing HomeWidget.getInstalledWidgets can throw on web; guard them with a
kIsWeb check (e.g. only access Platform when !kIsWeb) so the configuration
lookup via _androidConfigurationFromStorage and the Map copy from
w.configuration are only executed on non-web. Add the
package:flutter/foundation.dart import for kIsWeb if missing and update the
conditional logic around Platform.isAndroid / Platform.isIOS to use !kIsWeb &&
Platform.isAndroid / !kIsWeb && Platform.isIOS before calling
_androidConfigurationFromStorage or reading w.configuration, keeping the rest of
the setState flow unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: a1d2f208-fb70-4700-8948-233c982f33d2
📒 Files selected for processing (6)
examples/configurable_widget/android/app/build.gradle.ktsexamples/configurable_widget/android/app/src/main/kotlin/es/antonborri/configurable_widget/ConfigurableWidgetHomeWidget.ktexamples/configurable_widget/android/app/src/main/kotlin/es/antonborri/configurable_widget/ConfigurableWidgetHomeWidgetReceiver.ktexamples/configurable_widget/android/build.gradle.ktsexamples/configurable_widget/android/settings.gradle.ktsexamples/configurable_widget/lib/main.dart
✅ Files skipped from review due to trivial changes (5)
- examples/configurable_widget/android/app/src/main/kotlin/es/antonborri/configurable_widget/ConfigurableWidgetHomeWidgetReceiver.kt
- examples/configurable_widget/android/settings.gradle.kts
- examples/configurable_widget/android/app/build.gradle.kts
- examples/configurable_widget/android/build.gradle.kts
- examples/configurable_widget/android/app/src/main/kotlin/es/antonborri/configurable_widget/ConfigurableWidgetHomeWidget.kt
Description
Add an Android Example for Configurable Widgets following the work of #396
Checklist
exampleor documentation.Breaking Change?
Related Issues