This commit is contained in:
2026-04-10 15:31:07 +09:00
parent 964655af7f
commit 162d2b7563
18 changed files with 1151 additions and 195 deletions
@@ -28,6 +28,8 @@
android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS"
android:value="0" />
</service>
<receiver android:name=".tile.TileActionReceiver" android:exported="false" />
<service
android:name=".tile.MainTileService"
android:exported="true"
@@ -1,8 +1,14 @@
package bums.lunatic.launcher.tile
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import androidx.wear.protolayout.ActionBuilders
import androidx.wear.protolayout.ColorBuilders.argb
import androidx.wear.protolayout.DimensionBuilders.dp
import androidx.wear.protolayout.LayoutElementBuilders
import androidx.wear.protolayout.ModifiersBuilders
import androidx.wear.protolayout.ResourceBuilders
import androidx.wear.protolayout.TimelineBuilders
import androidx.wear.protolayout.material.Colors
@@ -14,6 +20,7 @@ import androidx.wear.tiles.TileBuilders
import androidx.wear.tiles.tooling.preview.Preview
import androidx.wear.tiles.tooling.preview.TilePreviewData
import androidx.wear.tooling.preview.devices.WearDevices
import com.google.android.gms.wearable.Wearable
import com.google.android.horologist.annotations.ExperimentalHorologistApi
import com.google.android.horologist.tiles.SuspendingTileService
@@ -64,22 +71,77 @@ private fun tile(
.build()
}
private fun tileLayout(
requestParams: RequestBuilders.TileRequest,
context: Context,
): LayoutElementBuilders.LayoutElement {
private fun tileLayout(requestParams: RequestBuilders.TileRequest, context: Context): LayoutElementBuilders.LayoutElement {
fun createNavButton(label: String, path: String,x : Float, y :Float): LayoutElementBuilders.LayoutElement {
// 리시버를 실행하기 위한 PendingIntent 생성
val intent = Intent(context, TileActionReceiver::class.java).apply {
putExtra("path", path)
}
val pendingIntent = PendingIntent.getBroadcast(
context, path.hashCode(), intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
return LayoutElementBuilders.Box.Builder()
.setModifiers(ModifiersBuilders.Modifiers.Builder()
.setClickable(ModifiersBuilders.Clickable.Builder()
.setOnClick(ActionBuilders.LaunchAction.Builder()
.setAndroidActivity(ActionBuilders.AndroidActivity.Builder()
.setPackageName(context.packageName)
.setClassName(TileActionReceiver::class.java.name) // 리시버 호출
.build())
.build())
.build())
.setTransformation(ModifiersBuilders.Transformation.Builder()
// 방향에 따라 x, y 좌표 조절 (상: 0,-45 / 하: 0,45 / 좌: -45,0 / 우: 45,0)
.setTranslationX(dp(x))
.setTranslationY(dp(y))
.build())
.setBackground(ModifiersBuilders.Background.Builder()
.setColor(argb(0xFF303030.toInt()))
.setCorner(ModifiersBuilders.Corner.Builder().setRadius(dp(15f)).build())
.build())
.build())
.setWidth(dp(56f)).setHeight(dp(56f))
.addContent(Text.Builder(context, label).build())
.build()
}
return PrimaryLayout.Builder(requestParams.deviceConfiguration)
.setResponsiveContentInsetEnabled(true)
.setContent(
Text.Builder(context, "Hello World!")
.setColor(argb(Colors.DEFAULT.onSurface))
.setTypography(Typography.TYPOGRAPHY_CAPTION1)
LayoutElementBuilders.Box.Builder()
// 상 (UP): X는 그대로, Y만 위로(-45dp)
.addContent(createNavButton("UP", "/gesture/up", 0f, -50f))
// 하 (DOWN): X는 그대로, Y만 아래로(+50dp)
.addContent(createNavButton("DOWN", "/gesture/down", 0f, 50f))
// 좌 (LEFT): X를 왼쪽으로(-50dp), Y는 그대로
.addContent(createNavButton("LEFT", "/gesture/left", -50f, 0f))
// 우 (RIGHT): X를 오른쪽으로(+50dp), Y는 그대로
.addContent(createNavButton("RIGHT", "/gesture/right", 50f, 0f))
.build()
).build()
}
@Preview(device = WearDevices.SMALL_ROUND)
@Preview(device = WearDevices.LARGE_ROUND)
fun tilePreview(context: Context) = TilePreviewData(::resources) {
tile(it, context)
}
class TileActionReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val path = intent.getStringExtra("path") ?: return
// 폰(런처)으로 메시지 전송
Wearable.getNodeClient(context).connectedNodes.addOnSuccessListener { nodes ->
for (node in nodes) {
Wearable.getMessageClient(context).sendMessage(node.id, path, null)
}
}
}
}