LoginSignup
3
1

More than 1 year has passed since last update.

【Android Wear】Watch Faceの作成

Last updated at Posted at 2022-09-27

はじめに

xmlを用いたWatch Faceの作成方法について紹介。
Android StudioのNew Project→Watch Faceでのプロジェクト作成だと、非推奨クラス(CanvasWatchFaceService)を使用することになるので1から作成した(2022/09/27時点)。

作成方法

依存関係の宣言

build.gradle(:app)ファイルにWatchFace用の依存関係を追加

build.gradle
dependencies {
	implementation 'androidx.wear.watchface:watchface:1.1.1'
}

レイアウトの作成

WatchFaceに表示するレイアウトの作成

custom_watch_face.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	xmlns:app="http://schemas.android.com/apk/res-auto"
	xmlns:tools="http://schemas.android.com/tools"
	android:layout_width="match_parent"
	android:background="#FF000000"
	android:layout_height="match_parent">

	<TextView
		android:id="@+id/time"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:textSize="52sp"
		android:textColor="#FFFFFFFF"
		app:layout_constraintBottom_toBottomOf="parent"
		app:layout_constraintEnd_toEndOf="parent"
		app:layout_constraintStart_toStartOf="parent"
		app:layout_constraintTop_toTopOf="parent"
		tools:text="12:34"/>
</androidx.constraintlayout.widget.ConstraintLayout>

Rendererクラスの作成

XMLのレイアウトを描画する処理を記述

CustomWatchFaceRenderer.kt
class CustomWatchFaceRenderer(
	context: Context,
	surfaceHolder: SurfaceHolder,
	currentUserStyleRepository: CurrentUserStyleRepository,
	watchState: WatchState
) : Renderer.CanvasRenderer2<Renderer.SharedAssets>(
	surfaceHolder,
	currentUserStyleRepository,
	watchState,
	CanvasType.HARDWARE,
	16L,
	false
) {
	private val binding = CustomWatchFaceBinding.inflate(LayoutInflater.from(context))

	override suspend fun createSharedAssets() = object : SharedAssets {
		override fun onDestroy() {}
	}

	override fun renderHighlightLayer(canvas: Canvas, bounds: Rect, zonedDateTime: ZonedDateTime, sharedAssets: SharedAssets) {}

	override fun render(canvas: Canvas, bounds: Rect, zonedDateTime: ZonedDateTime, sharedAssets: SharedAssets) {
		if (renderParameters.watchFaceLayers.contains(WatchFaceLayer.COMPLICATIONS_OVERLAY)) {
			binding.root.measure(
				View.MeasureSpec.makeMeasureSpec(bounds.width(), View.MeasureSpec.EXACTLY),
				View.MeasureSpec.makeMeasureSpec(bounds.height(), View.MeasureSpec.EXACTLY)
			)
			binding.root.layout(0, 0, bounds.width(), bounds.height())
			binding.time.text = String.format("%02d:%02d", zonedDateTime.hour, zonedDateTime.minute)
			binding.root.draw(canvas)
		}
	}
}

WatchFaceServiceの作成

先ほど作成したRendererクラスを使ってWatchFaceServiceを作成

CustomWatchFaceService.kt
class CustomWatchFaceService : WatchFaceService() {
	override suspend fun createWatchFace(surfaceHolder: SurfaceHolder, watchState: WatchState, complicationSlotsManager: ComplicationSlotsManager, currentUserStyleRepository: CurrentUserStyleRepository) =
		WatchFace(WatchFaceType.DIGITAL, CustomWatchFaceRenderer(applicationContext, surfaceHolder, currentUserStyleRepository, watchState))
}

Wallpaperの作成

res/xml/watch_face.xmlの作成

watch_face.xml
<?xml version="1.0" encoding="UTF-8"?>
<wallpaper/>

プレビュー画像の配置

res/drawable/preview.pngを配置

マニフェストファイルの変更

WatchFace一覧に先ほど作成したWatchFaceを表示させる。
パーミッションにWAKE_LOCKを追加
WatchFaceServiceにCustomWatchFaceServiceを指定

AndroidManifest.xml
<manifest ...>

	<uses-permission android:name="android.permission.WAKE_LOCK"/>
	...

	<application ...>
		...

		<service
			android:name=".CustomWatchFaceService"
			android:label="Custom Watch Face"
			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"/>
			<meta-data
				android:name="com.google.android.wearable.watchface.preview_circular"
				android:resource="@drawable/preview"/>

			<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>

参考サイト

処理関連:

依存関係関連:

サンプルコード:

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1