230 lines
11 KiB
Kotlin
230 lines
11 KiB
Kotlin
package com.gh.base
|
|
|
|
import android.app.Notification
|
|
import android.app.NotificationChannel
|
|
import android.app.NotificationManager
|
|
import android.app.PendingIntent
|
|
import android.content.Context
|
|
import android.content.Intent
|
|
import android.os.Build
|
|
import android.os.Bundle
|
|
import android.preference.PreferenceManager
|
|
import android.text.TextUtils
|
|
import android.view.View
|
|
import androidx.core.app.NotificationCompat
|
|
import com.gh.common.notifier.Notifier
|
|
import com.gh.common.util.EntranceUtils
|
|
import com.gh.common.util.MtaHelper
|
|
import com.gh.common.util.StringUtils
|
|
import com.gh.common.util.toObject
|
|
import com.gh.gamecenter.R
|
|
import com.gh.gamecenter.entity.PushEntity
|
|
import com.gh.gamecenter.entity.PushMessageEntity
|
|
import com.gh.gamecenter.entity.PushMessageUnreadEntity
|
|
import com.gh.gamecenter.entity.PushNotificationEntity
|
|
import com.gh.gamecenter.manager.UserManager
|
|
import com.gh.gamecenter.message.MessageUnreadRepository
|
|
import com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity
|
|
import com.gh.gamecenter.receiver.UmengMessageReceiver
|
|
import com.gh.gamecenter.receiver.UmengMessageReceiver.Companion.TYPE_CLICK
|
|
import com.gh.gamecenter.receiver.UmengMessageReceiver.Companion.TYPE_REMOVE
|
|
import com.gh.gamecenter.retrofit.Response
|
|
import com.gh.gamecenter.retrofit.RetrofitManager
|
|
import com.google.gson.Gson
|
|
import com.umeng.message.UmengMessageService
|
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
|
import io.reactivex.schedulers.Schedulers
|
|
import okhttp3.MediaType
|
|
import okhttp3.RequestBody
|
|
import okhttp3.ResponseBody
|
|
import org.android.agoo.common.AgooConstants
|
|
import org.json.JSONObject
|
|
import retrofit2.HttpException
|
|
import java.util.*
|
|
|
|
class GHUmengNotificationService : UmengMessageService() {
|
|
|
|
companion object {
|
|
const val ACTION_UMENG = "com.gh.gamecenter.UMENG"
|
|
const val MESSAGE_FROM_SYSTEM = "message_from_system"
|
|
const val HALO_MESSAGE_DIALOG = "HALO_MESSAGE_DIALOG"
|
|
const val HALO_MESSAGE_CENTER = "HALO_MESSAGE_CENTER"
|
|
const val ANSWER = "answer"
|
|
const val FOLLOW_QUESTION = "follow_question"
|
|
const val NOTIFICATION_ID = 2015
|
|
const val DISPLAY_TYPE_NOTIFICATION = "notification"
|
|
const val DISPLAY_TYPE_CUSTOM = "custom"
|
|
const val MESSAGE_ID = "message_id"
|
|
const val NOTIFICATION_MESSAGE_ID = "notification_message_id" // 通知中心消息 ID
|
|
const val PUSH_ID = "push_id"
|
|
}
|
|
|
|
val notificationTags = arrayOf("GH_UMENG_TAG_1", "GH_UMENG_TAG_2", "GH_UMENG_TAG_3")
|
|
val gson = Gson()
|
|
|
|
override fun onMessage(context: Context, intent: Intent) {
|
|
val message = intent.getStringExtra(AgooConstants.MESSAGE_BODY)
|
|
val isMessageFromSystem = intent.getBooleanExtra(MESSAGE_FROM_SYSTEM, false)
|
|
|
|
try {
|
|
val pushData = message.toObject<PushEntity>()
|
|
pushData?.let { handlePushData(context, it, message, isMessageFromSystem) }
|
|
} catch (e: Exception) {
|
|
e.printStackTrace()
|
|
}
|
|
}
|
|
|
|
private fun handlePushData(context: Context, pushData: PushEntity, message: String, isMessageFromSystem: Boolean) {
|
|
val notificationManager = context.applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
|
|
|
if (pushData.displayType == DISPLAY_TYPE_NOTIFICATION) {
|
|
// 其它类型的透传信息
|
|
// 显示到通知栏
|
|
val msg = message.toObject<PushNotificationEntity>()
|
|
val data = msg?.extra?.data
|
|
|
|
// 系统推送(非自定义信息),直接处理跳转
|
|
if (isMessageFromSystem) {
|
|
val intent = Intent()
|
|
intent.setClass(context, UmengMessageReceiver::class.java)
|
|
intent.putExtra(EntranceUtils.KEY_DATA, data?.link)
|
|
intent.putExtra(EntranceUtils.KEY_TYPE, UmengMessageReceiver.DIRECT_ONLY)
|
|
intent.putExtra(EntranceUtils.KEY_MESSAGE, message)
|
|
intent.putExtra(NOTIFICATION_MESSAGE_ID, data?.messageId)
|
|
context.sendBroadcast(intent)
|
|
return
|
|
}
|
|
|
|
// 用户未登录的情况下不生成消息中心通知,避免用户掉登录了还收到跳转至消息中心的通知
|
|
if (data != null
|
|
&& data.link?.target == "system"
|
|
&& !UserManager.getInstance().isLoggedIn) {
|
|
return
|
|
}
|
|
|
|
val clickIntent = Intent()
|
|
val removeIntent = Intent()
|
|
|
|
clickIntent.setClass(context, UmengMessageReceiver::class.java)
|
|
clickIntent.putExtra(EntranceUtils.KEY_DATA, data?.link)
|
|
clickIntent.putExtra(EntranceUtils.KEY_MESSAGE, message)
|
|
clickIntent.putExtra(MESSAGE_ID, msg?.msgId)
|
|
clickIntent.putExtra(PUSH_ID, data?.pushId)
|
|
clickIntent.putExtra(NOTIFICATION_MESSAGE_ID, data?.messageId)
|
|
clickIntent.putExtra(EntranceUtils.KEY_TYPE, TYPE_CLICK)
|
|
|
|
removeIntent.setClass(context, UmengMessageReceiver::class.java)
|
|
removeIntent.putExtra(EntranceUtils.KEY_TYPE, TYPE_REMOVE)
|
|
removeIntent.putExtra(EntranceUtils.KEY_MESSAGE, message)
|
|
|
|
val clickPendingIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt(),
|
|
clickIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
|
|
|
val deletePendingIntent = PendingIntent.getBroadcast(context, System.currentTimeMillis().toInt() + 1,
|
|
removeIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
val channel = NotificationChannel("Halo_Push", "Halo_Push", NotificationManager.IMPORTANCE_DEFAULT)
|
|
notificationManager.createNotificationChannel(channel)
|
|
}
|
|
|
|
val notification = NotificationCompat.Builder(context, "Halo_Push")
|
|
.setSmallIcon(R.drawable.ic_notification)
|
|
.setTicker(pushData.body?.ticker)
|
|
.setContentTitle(pushData.body?.title)
|
|
.setContentText(pushData.body?.text)
|
|
.setContentIntent(clickPendingIntent)
|
|
.setDeleteIntent(deletePendingIntent)
|
|
.build()
|
|
notification.flags = notification.flags or Notification.FLAG_AUTO_CANCEL
|
|
|
|
notificationManager.notify(getNotificationTag(context), NOTIFICATION_ID, notification)
|
|
} else {
|
|
if (UserManager.getInstance().isLoggedIn
|
|
&& HALO_MESSAGE_DIALOG == pushData.body?.custom) {
|
|
// 回答了问题或者关注了问题的消息
|
|
val msg = gson.fromJson(message, PushMessageEntity::class.java)
|
|
val data = msg?.extra?.data
|
|
|
|
val type = if (ANSWER == data?.type) {
|
|
"回答了你的问题"
|
|
} else {
|
|
"回答了你关注的问题"
|
|
}
|
|
|
|
val userName = StringUtils.shrinkStringWithDot(data?.userEntity?.name, 8)
|
|
val displayText = userName + type
|
|
|
|
if (Notifier.isActivityValid(CurrentActivityHolder.getCurrentActivity()) &&
|
|
Notifier.shouldShowNotifier(data?.answer?.id + displayText)) {
|
|
Notifier.create(CurrentActivityHolder.getCurrentActivity())
|
|
.setText(displayText)
|
|
.setDuration(5000)
|
|
.setIcon(data?.userEntity?.icon)
|
|
.setOnClickListener(View.OnClickListener {
|
|
val bundle = Bundle()
|
|
bundle.putString(EntranceUtils.KEY_ANSWER_ID, data?.answer?.id)
|
|
bundle.putString(EntranceUtils.KEY_ENTRANCE, EntranceUtils.ENTRANCE_UMENG)
|
|
bundle.putString(EntranceUtils.KEY_TO, AnswerDetailActivity::class.java.name)
|
|
EntranceUtils.jumpActivity(context, bundle)
|
|
|
|
MtaHelper.onEvent("消息弹窗", type, "Does not contains any parameter.")
|
|
|
|
// 标记已读
|
|
val jsonObject = JSONObject()
|
|
jsonObject.put("type", type)
|
|
val body = RequestBody.create(MediaType.parse("application/json"), jsonObject.toString())
|
|
|
|
RetrofitManager.getInstance(application).api.postMessageRead(UserManager.getInstance().userId, data?.id, body)
|
|
.subscribeOn(Schedulers.io())
|
|
.observeOn(AndroidSchedulers.mainThread())
|
|
.subscribe(object : Response<ResponseBody>() {
|
|
override fun onResponse(response: ResponseBody?) {
|
|
super.onResponse(response)
|
|
MessageUnreadRepository.loadMessageUnreadData()
|
|
}
|
|
|
|
override fun onFailure(e: HttpException?) {
|
|
e?.printStackTrace()
|
|
}
|
|
})
|
|
Notifier.hide()
|
|
})
|
|
.show(false)
|
|
Notifier.tagNotifierAsShowed(data?.answer?.id + displayText)
|
|
}
|
|
} else if (HALO_MESSAGE_CENTER == pushData.body?.custom) {
|
|
// 消息中心逻辑
|
|
val msg = gson.fromJson(message, PushMessageUnreadEntity::class.java)
|
|
val data = msg?.extra?.data
|
|
data?.let { MessageUnreadRepository.loadMessageUnreadData() }
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 规则:最多三条消息,以旧换新
|
|
*
|
|
* @return NotificationTag
|
|
*/
|
|
private fun getNotificationTag(context: Context): String {
|
|
val sp = PreferenceManager.getDefaultSharedPreferences(context)
|
|
val edit = sp.edit()
|
|
|
|
val timeTagMap = HashMap<Long, String>()
|
|
for (tag in notificationTags) {
|
|
val time = sp.getLong(tag, 0)
|
|
if (time == 0L) {
|
|
edit.putLong(tag, System.currentTimeMillis()).apply()
|
|
return tag
|
|
} else {
|
|
timeTagMap[time] = tag
|
|
}
|
|
}
|
|
|
|
val minTime = Collections.min(timeTagMap.keys)
|
|
val tag = timeTagMap[minTime]
|
|
edit.putLong(tag, System.currentTimeMillis()).apply()
|
|
return if (TextUtils.isEmpty(tag)) notificationTags[0] else tag!!
|
|
}
|
|
} |