A Hands-On Workshop with Jetpack Compose Glance & Gemini -
Activity Instructions & Code Snippets
Slides
Widgets Are So Hot Right Now! - Google Slides
Widget Fever Workshop - Google Slides
Preparation work
- Create your Developer Profile
- Download Android Studio
- Any recent version is fine - stable one is Otter
Activity 1 - Set up
- Clone the sample project MotivateMe using git and checkout the
mainbranch - Open it in Android Studio
- Sync MotivateMe and run it on an emulator (any emulator is fine)
- Feel free to update the sample data!
Activity 2 - Hello Widget!
- Add the glance dependencies to the app module
build.gradlefile (you can uncomment what has been provided)Click to see example code
- Sync the project
- Create a simple
GlanceAppWidgetthat displays some text. You can do this inQuoteWidget.kt.
Tip: Also update MainActivity to update QuoteWidget on every launch using
QuoteWidget().updateAll(this@MainActivity)
Click to see example code
Click to see example code - imports
Create a simple
GlanceAppWidgetReceiverthat just has an override forglanceAppWidget, set it to yourQuoteWidget. You can do this inQuoteWidgetReceiver.ktClick to see example code
Click to see example code - imports
Update the
AndroidManifest.xmlto include areceiverthat:- Sets
android:nameto your.widget.QuoteWidgetReceiver - Has
android:exported="true" - Has an intent filter of
android:name="android.appwidget.action.APPWIDGET_UPDATE" - Has a
meta-dataobject forandroid.appwidget.providerwith the resource of@xml/quote_widget_info(a basicquote_widget_info.xmlhas been provided)Click to see example code
- Sets
Run your app on your emulator
Long press on your home screen to add your new widget!
Activity 3 - Basic configuration
- Modify
QuoteWidgetto change the text or text colour, run your app again to see the change on the widget. See while the app is deploying that the app icon is displayed on the widget. - Modify
QuoteWidgetto add aclickablemodifier withactionStartActivity(intent)to open theMainActivityon click of the widget. Run the app and try it out.
Click to see example code
- Modify the
quote_widget_info.xmlto add aninitialLayoutwith the default loading layout@layout/glance_default_loading_layout. Run the app and see the loading layout is now a spinner.Click to see example code
- Modify the
quote_widget_info.xmlto add anandroid:targetCellWidth="4"andandroid:targetCellHeight="1". Also addandroid:resizeMode="horizontal|vertical"to allow your widget to resize. Run the app and see the default size is now a horizontal rectangle. Try resizing it.Click to see example code
Activity 4 - Set theme & update UI
- Update
QuoteWidgetto include a background modifier to theBoxinQuoteWidgetContentso it is easier to see the against the wallpaperRun the app and see the colour changeClick to see example code
Note: you may need to remove and re-add the widget.
- Uncomment the code provided in
MotivateMeGlanceColorScheme.ktClick to see example code
Click to see example code - imports
- Add a
GlanceThemeimplementation inMotivateMeGlanceTheme.ktthat uses the colours fromMotivateMeGlanceColorScheme
Click to see example code
Click to see example code - imports
Don’t forget the preview!
- Replace
GlanceThemewithMotivateMeGlanceThemeinQuoteWidget. Update the background and the text to use the themed colours: Background =GlanceTheme.colors.widgetBackgroundText =GlanceTheme.colors.primaryClick to see example code
Run the app and see the colour changeClick to see example code - imports
Note: you may need to remove and re-add the widget
- Change the emulator settings from dark to light theme and see the widget colours respond
Activity 5 - Set sample data
- Modify
QuoteWidgetto set thedisplayTextvariable from the staticsampleDataas:
val displayText = sampleData.first().quotes.first().text
Click to see example code
- Run the app, see how the text reflows as the widget changes size & shape.
- What happens when the text is too long for the space?
Activity 6 - Add widget configuration & data state
- Update
QuoteWidgetto add thestringPreferencesKeyvalues for thetopicandquotestatesClick to see example code
Click to see example code - imports
- Update
QuoteWidgetConfigurationActivityto set the widget topic & quote as text state valuesClick to see example code
Click to see example code - imports
- Modify
quote_widget_info.xmlto addandroid:widgetFeatures="reconfigurable"andandroid:configure="dev.motivateme.widget.QuoteWidgetConfigurationActivity"to allow the widget to be configuredClick to see example code
- Update
QuoteWidgetto read the state and use that value in the widgetClick to see example code
Click to see example code - imports
- Modify
QuoteWidgetto add a button to the widget UI that will randomly select a quote to show.- Useful reference - User Interaction - Run ActionCallback
Click to see example code
Click to see example code - imports
- Useful reference - User Interaction - Run ActionCallback
Activity 7 - Add Firebase AI Logic SDK (Gemini)
Firebase AI Logic SDK Documentation
- Open Firebase Console and create a Firebase project & download a
google-services.jsonfile. Add thegoogle-services.jsonfile to your project directory. - Add Google Services Plugin in
libs.versions.toml - Add Firebase AI Logic SDK in
libs.versions.toml - Add Google Services Plugin in project level
build.gradle.kts - Add Google Services Plugin in app level
build.gradle.kts - Add Firebase AI Logic SDK in
build.gradle.ktsClick to see example code
- Create
GeminiInterfaceto initialise the generative modelClick to see example code
Click to see example code - imports
- Create a method to call a prompt and generate some motivational quotes
Click to see example code
Click to see example code - imports
- Have a go changing the prompts, can you make the motivational quotes more punny?
Activity 8 - Add on demand data refresh using CoroutineWorker
- Create
QuoteWidgetWorkerClick to see example code
- Modify
QuoteWidgetWorkerto fetch new values from the Gemini SDKClick to see example code
Click to see example code - imports
- Modify
QuoteWidgetrefresh button to enqueue the workerClick to see example code
Click to see example code - imports
Extensions
Activity 9 (Extension) - Add periodic data refresh using CoroutineWorker
- Modify
QuoteWidgetWorkerto add a method to enqueue periodic work - Modify
QuoteWidgetWorkerto add a method to cancel periodic work - Modify
QuoteWidgetReceiverto enqueue work inonUpdateand cancel inonDeletedClick to see example code
Click to see example code - imports
Activity 10 (Extension) - Polishing the final result
- Modify the
quote_widget_info.xmlto add anandroid:description="@string/widget_description"Click to see example code
- Take a screenshot of your widget, trim the size & remove background using any image editor and import it into the app as a drawable with the name
quote_widget_preview.png
Tip: I set a white background on my emulator, then take a screenshot and use photopea.com to crop the image and remove the background
- Modify the
quote_widget_info.xmlto add anandroid:previewImage="@drawable/quote_widget_preview".Click to see example code
- Modify
QuoteWidgetto add an error layout if the composition failsClick to see example code
- Run the app and see the widget selection looks much more inviting
Activity 11 (Extension) - Update the GlanceTheme to use the device theme
- Update the
MotivateMeGlanceThemeto use the device theme- Useful reference - Implement a Glance theme
Click to see example code
- Useful reference - Implement a Glance theme
Activity 12 (Extension) - Respond to the wallpaper
- Update
MotivateMeGlanceThemeto monitor the wallpaper usingWallpaperManager.OnColorsChangedListener& pass aBooleanto the content composable if it should use dark text - Update
QuoteWidgetto enable a transparent background & respond to the wallpaper- Useful reference - WallpaperManager
Click to see example code
- Useful reference - WallpaperManager
Tip: To monitor the wallpaper colours, you will need to increase the minimum sdk to 27
Activity 13 (Extension) - Fine tune Gemini
- Update the Gemini SDK prompt to get it to remove any quote characters from the output
- Can you get a better motivational quote? What other things would you like to display on your home screen?