feat(push): 完成 VIVO 推送集成 + Xiaomi 凭据强校验
- XuqmVivoPushReceiver 从 BroadcastReceiver 改为继承 OpenClientPushMessageReceiver,通过 onReceiveRegId 回调获取 regId(修复之前 extractRegId 的脆弱 key 匹配) - VIVO receiver android:exported 从 false 改为 true(跨进程广播必须可导出) - VivoPushService 失败日志级别从 Log.w 提升为 Log.e - Xiaomi/VIVO 凭据必须来自控制台,获取不到时抛出异常(移除 meta-data 本地兜底) - PushSDK.loadVendorConfig 失败时向上抛异常,不再 swallow Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
这个提交包含在:
父节点
4f4f8564df
当前提交
344efbb0aa
@ -151,7 +151,7 @@
|
||||
android:exported="true" />
|
||||
<receiver
|
||||
android:name="com.xuqm.sdk.push.vivo.XuqmVivoPushReceiver"
|
||||
android:exported="false">
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="com.vivo.pushclient.action.RECEIVE" />
|
||||
</intent-filter>
|
||||
|
||||
@ -304,8 +304,8 @@ object PushSDK {
|
||||
honorAppId = pushConfig?.getAsJsonObject("honor")?.get("appId")?.asString.orEmpty(),
|
||||
)
|
||||
}.getOrElse { error ->
|
||||
Log.w("XuqmPushSDK", "Unable to load push vendor config: ${error.message}")
|
||||
PushVendorConfig()
|
||||
Log.e("XuqmPushSDK", "Failed to load push vendor config from control plane: ${error.message}")
|
||||
throw IllegalStateException("Push vendor config unavailable: ${error.message}", error)
|
||||
}
|
||||
cachedVendorConfig = loaded
|
||||
cachedConfigAt = now
|
||||
|
||||
@ -62,7 +62,7 @@ class VivoPushService : PushVendorInterface {
|
||||
}
|
||||
Log.i(TAG, "Vivo push registration requested")
|
||||
}.onFailure { error ->
|
||||
Log.w(TAG, "Vivo push registration failed: ${error.message}")
|
||||
Log.e(TAG, "Vivo push registration failed: ${error.message}")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,18 +1,10 @@
|
||||
package com.xuqm.sdk.push.vendor
|
||||
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import com.xuqm.sdk.push.model.PushVendor
|
||||
import com.xuqm.sdk.push.model.PushVendorConfig
|
||||
|
||||
/**
|
||||
* 小米推送集成框架
|
||||
*
|
||||
* MiPush AAR 需要随 sdk-push 发布。注册参数优先来自租户 PUSH 配置,
|
||||
* 旧版本 manifest meta-data 仅作为兼容兜底。
|
||||
*/
|
||||
class XiaomiPushService : PushVendorInterface {
|
||||
|
||||
override val vendor: PushVendor = PushVendor.XIAOMI
|
||||
@ -27,12 +19,11 @@ class XiaomiPushService : PushVendorInterface {
|
||||
override fun register(context: Context, config: PushVendorConfig) {
|
||||
runCatching {
|
||||
val miPushClass = Class.forName("com.xiaomi.mipush.sdk.MiPushClient")
|
||||
val meta = context.packageManager.getApplicationInfo(
|
||||
context.packageName, PackageManager.GET_META_DATA
|
||||
).metaData ?: Bundle.EMPTY
|
||||
val appId = config.xiaomiAppId.ifBlank { meta.getString("XUQM_XIAOMI_APP_ID", "") }
|
||||
val appKey = config.xiaomiAppKey.ifBlank { meta.getString("XUQM_XIAOMI_APP_KEY", "") }
|
||||
if (appId.isNotBlank() && appKey.isNotBlank()) {
|
||||
val appId = config.xiaomiAppId
|
||||
val appKey = config.xiaomiAppKey
|
||||
check(appId.isNotBlank() && appKey.isNotBlank()) {
|
||||
"Xiaomi push credentials not configured on control plane (xiaomi.appId / xiaomi.appKey required)"
|
||||
}
|
||||
miPushClass.getMethod(
|
||||
"registerPush",
|
||||
Context::class.java,
|
||||
@ -40,11 +31,8 @@ class XiaomiPushService : PushVendorInterface {
|
||||
String::class.java,
|
||||
).invoke(null, context, appId, appKey)
|
||||
Log.i(TAG, "Xiaomi push registration requested")
|
||||
} else {
|
||||
Log.w(TAG, "Xiaomi appId/appKey not configured, skipping registration")
|
||||
}
|
||||
}.onFailure { error ->
|
||||
Log.w(TAG, "Xiaomi push registration failed: ${error.message}")
|
||||
Log.e(TAG, "Xiaomi push registration failed: ${error.message}")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,44 +1,31 @@
|
||||
package com.xuqm.sdk.push.vivo
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import com.vivo.push.model.UnvarnishedMessage
|
||||
import com.vivo.push.model.UPSNotificationMessage
|
||||
import com.vivo.push.sdk.OpenClientPushMessageReceiver
|
||||
import com.xuqm.sdk.push.PushSDK
|
||||
import com.xuqm.sdk.push.model.PushVendor
|
||||
|
||||
class XuqmVivoPushReceiver : BroadcastReceiver() {
|
||||
class XuqmVivoPushReceiver : OpenClientPushMessageReceiver() {
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent?) {
|
||||
if (intent == null) return
|
||||
val appContext = context.applicationContext
|
||||
val regId = extractRegId(intent) ?: currentRegId(appContext)
|
||||
if (regId.isNullOrBlank()) return
|
||||
override fun onReceiveRegId(context: Context, regId: String) {
|
||||
if (regId.isBlank()) return
|
||||
Log.i(TAG, "Vivo push registered: regId=$regId")
|
||||
runCatching {
|
||||
PushSDK.updateNativePushToken(appContext, PushVendor.VIVO, regId)
|
||||
PushSDK.updateNativePushToken(context.applicationContext, PushVendor.VIVO, regId)
|
||||
}.onFailure { error ->
|
||||
Log.w(TAG, "Unable to persist vivo push token: ${error.message}")
|
||||
Log.e(TAG, "Unable to persist vivo push token: ${error.message}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractRegId(intent: Intent): String? {
|
||||
val extras = intent.extras ?: return null
|
||||
for (key in extras.keySet()) {
|
||||
val value = extras.get(key) as? String ?: continue
|
||||
if (key.contains("reg", ignoreCase = true) || key.contains("token", ignoreCase = true)) {
|
||||
return value.takeIf { it.isNotBlank() }
|
||||
}
|
||||
}
|
||||
return null
|
||||
override fun onTransmissionMessage(context: Context, message: UnvarnishedMessage) {
|
||||
Log.d(TAG, "Vivo pass-through message received: ${message.content}")
|
||||
}
|
||||
|
||||
private fun currentRegId(context: Context): String? {
|
||||
return runCatching {
|
||||
val pushClientClass = Class.forName("com.vivo.push.PushClient")
|
||||
val instance = pushClientClass.getMethod("getInstance", Context::class.java)
|
||||
.invoke(null, context)
|
||||
pushClientClass.getMethod("getRegId").invoke(instance) as? String
|
||||
}.getOrNull()
|
||||
override fun onNotificationMessageClicked(context: Context, message: UPSNotificationMessage) {
|
||||
Log.d(TAG, "Vivo notification clicked: ${message.title}")
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
正在加载...
在新工单中引用
屏蔽一个用户