You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Wear OS开发:如何实现手表离线时仍可触发的跨设备提醒?

解决方案:手表本地独立提醒 + 在线同步手机

你的核心需求是手表离线(手机关机)时仍能触发提醒,同时配对手机在线时也能同步触发,之前依赖手机在线插入日历的方案显然不满足需求。下面是可行的实现思路:

1. 手表端实现本地独立提醒

Wear OS 无法直接通过 CalendarContract 插入本地日历事件(手表日历默认同步手机端,无本地写入权限),需用本地定时任务框架实现独立提醒,推荐用 WorkManager(兼容低版本,支持后台执行):

用 WorkManager 实现单次提醒

// 手表端代码
import android.content.Context
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.Worker
import androidx.work.WorkerParameters
import androidx.work.workDataOf
import java.util.concurrent.TimeUnit

// 提醒触发时的执行器
class WearReminderWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
    override fun doWork(): Result {
        val title = inputData.getString("title") ?: "待办提醒"
        showWearNotification(title)
        return Result.success()
    }

    private fun showWearNotification(title: String) {
        // 构建Wear OS专属通知,支持手表交互
        val notification = NotificationCompat.Builder(applicationContext, "WEAR_REMINDER_CHANNEL")
            .setContentTitle(title)
            .setSmallIcon(R.drawable.ic_reminder)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setCategory(NotificationCompat.CATEGORY_ALARM)
            .build()
        
        NotificationManagerCompat.from(applicationContext).notify(
            (System.currentTimeMillis() % 10000).toInt(),
            notification
        )
    }
}

// 调度手表本地提醒的方法
fun scheduleWearReminder(context: Context, title: String, triggerTime: Long) {
    val delayMillis = triggerTime - System.currentTimeMillis()
    if (delayMillis <= 0) return

    val workRequest = OneTimeWorkRequestBuilder<WearReminderWorker>()
        .setInitialDelay(delayMillis, TimeUnit.MILLISECONDS)
        .setInputData(workDataOf("title" to title))
        .build()

    WorkManager.getInstance(context).enqueue(workRequest)
}

手表端权限配置

在Manifest中添加必要权限:

<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.WAKE_LOCK" /> <!-- 可选,确保提醒唤醒手表屏幕 -->

2. 在线时同步提醒到手机

当手表与手机连接时,将提醒数据同步到手机,手机端接收后创建本地提醒,确保手机开机后也能触发:

手表端发送同步消息(用MessageClient更高效)

// 手表端代码
import com.google.android.gms.wearable.MessageClient
import com.google.android.gms.wearable.Wearable

fun syncReminderToPhone(context: Context, title: String, triggerTime: Long) {
    // 空nodeId表示发送到所有配对设备
    Wearable.getMessageClient(context).sendMessage(
        "",
        "/sync_reminder",
        "$title|$triggerTime".toByteArray()
    )
}

手机端接收并创建本地提醒

实现 WearableListenerService 接收消息,用 AlarmManager 设置精确闹钟:

// 手机端代码
import android.app.AlarmManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import com.google.android.gms.wearable.MessageEvent
import com.google.android.gms.wearable.WearableListenerService

class ReminderSyncService : WearableListenerService() {
    override fun onMessageReceived(messageEvent: MessageEvent) {
        super.onMessageReceived(messageEvent)
        if (messageEvent.path == "/sync_reminder") {
            val data = String(messageEvent.data).split("|")
            val title = data[0]
            val triggerTime = data[1].toLong()
            schedulePhoneReminder(this, title, triggerTime)
        }
    }

    private fun schedulePhoneReminder(context: Context, title: String, triggerTime: Long) {
        val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        val intent = Intent(context, PhoneReminderReceiver::class.java).apply {
            putExtra("title", title)
        }
        val pendingIntent = PendingIntent.getBroadcast(
            context,
            (triggerTime % 10000).toInt(),
            intent,
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
        )

        // 设置精确闹钟,支持待机时触发
        alarmManager.setExactAndAllowWhileIdle(
            AlarmManager.RTC_WAKEUP,
            triggerTime,
            pendingIntent
        )
    }
}

// 手机端提醒触发接收器
class PhoneReminderReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        val title = intent.getStringExtra("title") ?: "同步提醒"
        val notification = NotificationCompat.Builder(context, "PHONE_REMINDER_CHANNEL")
            .setContentTitle(title)
            .setSmallIcon(R.drawable.ic_notification)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .build()
        
        NotificationManagerCompat.from(context).notify(
            (System.currentTimeMillis() % 10000).toInt(),
            notification
        )
    }
}

手机端Manifest配置

<service
    android:name=".ReminderSyncService"
    android:exported="true">
    <intent-filter>
        <action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
        <data
            android:host="*"
            android:pathPrefix="/sync_reminder"
            android:scheme="wear" />
    </intent-filter>
</service>

<receiver android:name=".PhoneReminderReceiver" />

3. 针对你之前无效方案的说明

  • WearableCalendarContract:该Contract为只读接口,仅用于查询同步到手表的日历数据,不支持插入/修改操作,抛出异常是正常行为。
  • 手表端直接用CalendarContract:手表端的CalendarProvider仅同步手机端数据,无本地写入权限,即使调用insert不抛异常,数据也不会生效。
  • 调用手机提醒APP的API:Android无公开系统API直接调用第三方提醒APP,仅能通过隐式Intent打开APP的添加页面,无法自动创建提醒。

最终执行流程

  1. 用户在手表APP创建提醒时,先调用 scheduleWearReminder 安排手表本地提醒。
  2. 检查手表与手机的连接状态,若在线则调用 syncReminderToPhone 同步数据到手机。
  3. 手表离线时,本地WorkManager到点触发提醒;手机在线时接收同步数据创建闹钟,开机后到点触发。

内容的提问来源于stack exchange,提问作者John Poust

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 23:30:12