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

如何让WearableListenerService在Android 13(API 33)中正常工作?

适配API 33的WearOS消息接收解决方案

针对WearableListenerService在API 33中失效的问题,以下是两种可行的修复方案:

方案一:将WearableListenerService转为前台服务

API 33强化了后台服务启动限制,WearableListenerService作为后台服务会被系统限制运行,转为前台服务可保证其存活并正常接收消息。

1. 修改WearService代码

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
import com.google.android.gms.wearable.MessageEvent
import com.google.android.gms.wearable.WearableListenerService

class WearService : WearableListenerService() {

    private val TAG = "GAC-WEARS"
    private val NOTIFICATION_ID = 1001
    private val CHANNEL_ID = "WearServiceChannel"

    override fun onCreate() {
        super.onCreate()
        createNotificationChannel()
        // 启动前台服务,满足API33后台服务运行要求
        startForeground(NOTIFICATION_ID, buildForegroundNotification())
        App.d(TAG, "ON CREATE")
    }

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID,
                "Wear消息服务",
                NotificationManager.IMPORTANCE_LOW
            ).apply {
                description = "处理WearOS设备发来的消息"
            }
            val notificationManager = getSystemService(NotificationManager::class.java)
            notificationManager.createNotificationChannel(channel)
        }
    }

    private fun buildForegroundNotification(): Notification {
        // 点击通知打开APP主界面
        val launchIntent = packageManager.getLaunchIntentForPackage(packageName)
        val pendingIntent = PendingIntent.getActivity(
            this,
            0,
            launchIntent,
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
        )

        return NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("Wear连接中")
            .setContentText("正在监听WearOS消息")
            .setSmallIcon(R.drawable.wear)
            .setContentIntent(pendingIntent)
            .setPriority(NotificationCompat.PRIORITY_LOW)
            .build()
    }

    override fun onMessageReceived(messageEvent: MessageEvent) {
        App.d(TAG, "RCV ${String(messageEvent.data)}")
        val root = App.app?.myAct
        val model = root?.model

        if (App.NO_WEAR) {
            return
        }

        if (messageEvent.path == RootActivity.BROADCAST_PATH) {
            val message = String(messageEvent.data)

            if (model?.connected?.value != null && model?.connected?.value != R.drawable.wear) {
                if (message.startsWith("start")) {
                    (application as App).showToast("无法连接Wear:已连接其他手表", App.MTYPE.ERROR)
                }
                return
            }
            App.d(TAG, message)

            root?.handler?.post {
                root.onNotify(RootActivity.NOTIFICATIONS.Ping, R.drawable.wear)
            }

            if (message.startsWith("start")) {
                root?.handler?.post {
                    root.onNotify(RootActivity.NOTIFICATIONS.Ping, R.drawable.wear)
                }
            } else {
                val messageIntent = Intent().apply {
                    action = Intent.ACTION_SEND
                    putExtra("message", message)
                    putExtra("device", App.DEV_WEAR)
                }
                LocalBroadcastManager.getInstance(this).sendBroadcast(messageIntent)
            }
        } else {
            super.onMessageReceived(messageEvent)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        stopForeground(STOP_FOREGROUND_REMOVE)
    }
}

2. 更新Manifest配置

添加前台服务权限,并修改服务声明:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="com.google.android.wearable.permission.RECEIVE_WEARABLE_MESSAGES" />

<service
    android:name=".WearService"
    android:permission="com.google.android.wearable.permission.BIND_LISTENER_SERVICE"
    android:foregroundServiceType="dataSync">
    <intent-filter>
        <action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
        <data
            android:host="*"
            android:pathPrefix="/${RootActivity.BROADCAST_PATH}"
            android:scheme="wear" />
    </intent-filter>
</service>

方案二:改用WearableMessageClient监听消息

放弃WearableListenerService,直接在Activity中通过WearableMessageClient注册监听,避开后台服务限制,兼容性更好。

代码示例(在RootActivity中实现)

import com.google.android.gms.wearable.Wearable
import com.google.android.gms.wearable.MessageEvent
import com.google.android.gms.wearable.WearableListener

class RootActivity : AppCompatActivity() {
    private lateinit var messageClient: com.google.android.gms.wearable.WearableMessageClient
    private var messageListener: WearableListener? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 初始化Wear消息客户端
        messageClient = Wearable.getMessageClient(this)
    }

    override fun onResume() {
        super.onResume()
        // 注册消息监听
        messageListener = object : WearableListener() {
            override fun onMessageReceived(messageEvent: MessageEvent) {
                handleWearMessage(messageEvent)
            }
        }
        messageClient.addListener(messageListener!!)
    }

    override fun onPause() {
        super.onPause()
        // 移除监听,避免内存泄漏
        messageClient.removeListener(messageListener!!)
    }

    private fun handleWearMessage(messageEvent: MessageEvent) {
        App.d("GAC-WEARS", "RCV ${String(messageEvent.data)}")
        val model = this.model

        if (App.NO_WEAR) {
            return
        }

        if (messageEvent.path == BROADCAST_PATH) {
            val message = String(messageEvent.data)

            if (model?.connected?.value != null && model?.connected?.value != R.drawable.wear) {
                if (message.startsWith("start")) {
                    (application as App).showToast("无法连接Wear:已连接其他手表", App.MTYPE.ERROR)
                }
                return
            }
            App.d("GAC-WEARS", message)

            handler.post {
                onNotify(NOTIFICATIONS.Ping, R.drawable.wear)
            }

            if (message.startsWith("start")) {
                handler.post {
                    onNotify(NOTIFICATIONS.Ping, R.drawable.wear)
                }
            } else {
                val messageIntent = Intent().apply {
                    action = Intent.ACTION_SEND
                    putExtra("message", message)
                    putExtra("device", App.DEV_WEAR)
                }
                LocalBroadcastManager.getInstance(this).sendBroadcast(messageIntent)
            }
        }
    }

    // 原有Activity代码...
}

注意事项

  • 确保依赖的Google Play Services Wear版本为18.1.0及以上,在build.gradle中更新:
    implementation 'com.google.android.gms:play-services-wearable:18.1.0'
    
  • 前台服务的通知设置为低优先级,避免打扰用户;若不需要显示通知,可优先考虑方案二。

内容的提问来源于stack exchange,提问作者Oleg Gryb

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 22:49:50