Skip to content

Instantly share code, notes, and snippets.

@terickson001
Created March 18, 2024 08:12
Show Gist options
  • Save terickson001/c8c00b76aaa11dbc0cc5bb0a6a407310 to your computer and use it in GitHub Desktop.
Save terickson001/c8c00b76aaa11dbc0cc5bb0a6a407310 to your computer and use it in GitHub Desktop.
Basic Watch Face
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-feature android:name="android.hardware.type.watch" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.permission.PROVIDE_BACKGROUND" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@android:style/Theme.DeviceDefault">
<uses-library
android:name="com.google.android.wearable"
android:required="true" />
<!--
Set to true if your app is Standalone, that is, it does not require the handheld
app to run.
-->
<meta-data
android:name="com.google.android.wearable.standalone"
android:value="true" />
<activity
android:name=".presentation.MainActivity"
android:exported="true"
android:taskAffinity=""
android:theme="@style/MainActivityTheme.Starting">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".BarcodeWatchFaceService"
android:directBootAware="true"
android:label="@string/barcode_name"
android:permission="android.permission.BIND_WALLPAPER"
android:exported="true">
<meta-data
android:name="android.service.wallpaper"
android:resource="@xml/watch_face" />
<meta-data
android:name="com.google.android.wearable.watchface.preview"
android:resource="@drawable/preview_circular" />
<meta-data
android:name="com.google.android.wearable.watchface.preview_circular"
android:resource="@drawable/preview_circular" />
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
<category
android:name=
"com.google.android.wearable.watchface.category.WATCH_FACE" />
</intent-filter>
</service>
</application>
</manifest>
package com.example.barcode
import android.util.Log
import android.view.SurfaceHolder
import androidx.wear.watchface.CanvasType
import androidx.wear.watchface.ComplicationSlotsManager
import androidx.wear.watchface.WatchFace
import androidx.wear.watchface.WatchFaceService
import androidx.wear.watchface.WatchFaceType
import androidx.wear.watchface.WatchState
import androidx.wear.watchface.style.CurrentUserStyleRepository
import androidx.wear.watchface.style.UserStyleSchema
class BarcodeWatchFaceService : WatchFaceService() {
override fun createUserStyleSchema(): UserStyleSchema {
return super.createUserStyleSchema()
}
override fun createComplicationSlotsManager(currentUserStyleRepository: CurrentUserStyleRepository): ComplicationSlotsManager {
return super.createComplicationSlotsManager(currentUserStyleRepository)
}
override suspend fun createWatchFace(
surfaceHolder: SurfaceHolder,
watchState: WatchState,
complicationSlotsManager: ComplicationSlotsManager,
currentUserStyleRepository: CurrentUserStyleRepository
): WatchFace {
Log.d(TAG, "createWatchFace()")
val renderer = BarcodeCanvasRenderer(
context = applicationContext,
surfaceHolder = surfaceHolder,
watchState = watchState,
complicationSlotsManager = complicationSlotsManager,
currentUserStyleRepository = currentUserStyleRepository,
canvasType = CanvasType.HARDWARE
);
return WatchFace(
watchFaceType = WatchFaceType.ANALOG,
renderer = renderer
);
}
companion object {
const val TAG = "BarcodeWatchFaceService"
}
}
package com.example.barcode
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Rect
import android.util.Log
import android.view.SurfaceHolder
import androidx.wear.watchface.ComplicationSlotsManager
import androidx.wear.watchface.Renderer
import androidx.wear.watchface.WatchState
import androidx.wear.watchface.style.CurrentUserStyleRepository
import com.google.zxing.BarcodeFormat
import com.google.zxing.qrcode.QRCodeWriter
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.cancel
import java.time.ZonedDateTime
private const val FRAME_PERIOD_MS_DEFAULT: Long = 16L
private const val BARCODE_TEXT: String = "Hello, World"
class BarcodeCanvasRenderer(
private val context: Context,
surfaceHolder: SurfaceHolder,
watchState: WatchState,
private val complicationSlotsManager: ComplicationSlotsManager,
currentUserStyleRepository: CurrentUserStyleRepository,
canvasType: Int
): Renderer.CanvasRenderer2<BarcodeCanvasRenderer.BarcodeSharedAssets>(
surfaceHolder,
currentUserStyleRepository,
watchState,
canvasType,
FRAME_PERIOD_MS_DEFAULT,
clearWithBackgroundTintBeforeRenderingHighlightLayer = false
) {
class BarcodeSharedAssets : SharedAssets {
override fun onDestroy() {
}
}
private fun createQR(content: String, width: Int, height: Int): Bitmap {
Log.d(TAG, "createQR()")
val writer = QRCodeWriter()
val bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height)
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565)
for (x in 0 until width) {
for (y in 0 until height) {
bitmap.setPixel(x, y, if (bitMatrix.get(x,y)) Color.BLACK else Color.WHITE)
}
}
return bitmap
}
private val scope: CoroutineScope =
CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
override suspend fun createSharedAssets(): BarcodeSharedAssets {
Log.d(TAG, "createSharedAssets()")
return BarcodeSharedAssets()
}
override fun renderHighlightLayer(
canvas: Canvas,
bounds: Rect,
zonedDateTime: ZonedDateTime,
sharedAssets: BarcodeSharedAssets
) {
Log.d(TAG, "renderHighlightLayer()")
canvas.drawColor(Color.BLUE)
}
override fun onDestroy() {
Log.d(TAG, "onDestroy()")
scope.cancel("BarcodeCanvasRenderer scope clear() request")
super.onDestroy()
}
override fun render(
canvas: Canvas,
bounds: Rect,
zonedDateTime: ZonedDateTime,
sharedAssets: BarcodeSharedAssets
) {
//val qr_bitmap: Bitmap = createQR(BARCODE_TEXT, canvas.width, canvas.height)
//canvas.drawBitmap(qr_bitmap, 0f, 0f, Paint())
Log.d(TAG, "render()")
canvas.drawColor(Color.RED)
Log.d(TAG, "renderFinished")
}
companion object {
private const val TAG = "BarcodeCanvasRenderer"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment