Created
March 18, 2024 08:12
-
-
Save terickson001/c8c00b76aaa11dbc0cc5bb0a6a407310 to your computer and use it in GitHub Desktop.
Basic Watch Face
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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