use NotificationManagerCompat.from(..).notify instead startForeground (experimental, not working)

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
Marcel Hibbe 2021-03-04 12:51:35 +01:00
Родитель 659681b543
Коммит ce75d9bf4c
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: C793F8B59F43CE7B
3 изменённых файлов: 96 добавлений и 15 удалений

Просмотреть файл

@ -32,6 +32,7 @@ import android.util.Base64
import android.util.Log
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat
import androidx.emoji.text.EmojiCompat
import androidx.work.Data
import androidx.work.OneTimeWorkRequest
@ -45,6 +46,7 @@ import com.nextcloud.talk.activities.MagicCallActivity
import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
import com.nextcloud.talk.controllers.CallController
import com.nextcloud.talk.events.CallNotificationClick
import com.nextcloud.talk.jobs.NotificationWorker
import com.nextcloud.talk.jobs.PushRegistrationWorker
@ -71,6 +73,7 @@ import okhttp3.OkHttpClient
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.webrtc.Logging
import retrofit2.Retrofit
import java.io.IOException
import java.net.CookieManager
@ -107,17 +110,20 @@ class MagicFirebaseMessagingService : FirebaseMessagingService() {
override fun onCreate() {
super.onCreate()
Logging.d(javaClass.simpleName, "onCreate")
sharedApplication!!.componentApplication.inject(this)
eventBus?.register(this)
}
@Subscribe(threadMode = ThreadMode.BACKGROUND)
fun onMessageEvent(event: CallNotificationClick) {
Logging.d(javaClass.simpleName, "onMessageEvent CallNotificationClick")
isServiceInForeground = false
stopForeground(true)
}
override fun onDestroy() {
Logging.d(javaClass.simpleName, "onDestroy")
isServiceInForeground = false
eventBus?.unregister(this)
stopForeground(true)
@ -126,6 +132,7 @@ class MagicFirebaseMessagingService : FirebaseMessagingService() {
}
override fun onNewToken(token: String) {
Logging.d(javaClass.simpleName, "onNewToken")
super.onNewToken(token)
sharedApplication!!.componentApplication.inject(this)
appPreferences!!.pushToken = token
@ -135,6 +142,7 @@ class MagicFirebaseMessagingService : FirebaseMessagingService() {
@SuppressLint("LongLogTag")
override fun onMessageReceived(remoteMessage: RemoteMessage) {
Logging.d(javaClass.simpleName, "onMessageReceived(RemoteMessage)")
sharedApplication!!.componentApplication.inject(this)
if (!remoteMessage.data["subject"].isNullOrEmpty() && !remoteMessage.data["signature"].isNullOrEmpty()) {
decryptMessage(remoteMessage.data["subject"]!!, remoteMessage.data["signature"]!!)
@ -142,6 +150,8 @@ class MagicFirebaseMessagingService : FirebaseMessagingService() {
}
private fun decryptMessage(subject: String, signature: String) {
Logging.d(javaClass.simpleName, "decryptMessage")
try {
val base64DecodedSubject = Base64.decode(subject, Base64.DEFAULT)
val base64DecodedSignature = Base64.decode(signature, Base64.DEFAULT)
@ -156,13 +166,19 @@ class MagicFirebaseMessagingService : FirebaseMessagingService() {
val decryptedSubject = cipher.doFinal(base64DecodedSubject)
decryptedPushMessage = LoganSquare.parse(String(decryptedSubject),
DecryptedPushMessage::class.java)
Logging.d(javaClass.simpleName, " decryptedPushMessage: " + decryptedPushMessage.toString())
decryptedPushMessage?.apply {
timestamp = System.currentTimeMillis()
if (delete) {
cancelExistingNotificationWithId(applicationContext, signatureVerification!!.userEntity, notificationId)
Logging.d(javaClass.simpleName, " delete=true")
NotificationUtils.cancelExistingNotificationWithId(applicationContext, signatureVerification!!.userEntity, notificationId)
} else if (deleteAll) {
cancelAllNotificationsForAccount(applicationContext, signatureVerification!!.userEntity)
Logging.d(javaClass.simpleName, " deleteAll=true")
NotificationUtils.cancelAllNotificationsForAccount(applicationContext, signatureVerification!!.userEntity)
} else if (type == "call") {
Logging.d(javaClass.simpleName, " type=call")
val fullScreenIntent = Intent(applicationContext, MagicCallActivity::class.java)
val bundle = Bundle()
bundle.putString(BundleKeys.KEY_ROOM_ID, decryptedPushMessage!!.id)
@ -189,12 +205,17 @@ class MagicFirebaseMessagingService : FirebaseMessagingService() {
}
}
val notificationChannelId = NotificationUtils.getNotificationChannelId(applicationContext.resources
.getString(R.string.nc_notification_channel_calls), applicationContext.resources
.getString(R.string.nc_notification_channel_calls_description), true,
NotificationManagerCompat.IMPORTANCE_HIGH, soundUri!!, audioAttributesBuilder.build(), null, false)
val notificationChannelId = NotificationUtils.getNotificationChannelId(
applicationContext.resources.getString(R.string.nc_notification_channel_calls),
applicationContext.resources.getString(R.string.nc_notification_channel_calls_description),
true,
NotificationManagerCompat.IMPORTANCE_HIGH,
soundUri!!,
audioAttributesBuilder.build(),
null,
false)
createNotificationChannel(applicationContext!!,
NotificationUtils.createNotificationChannel(applicationContext!!,
notificationChannelId, applicationContext.resources
.getString(R.string.nc_notification_channel_calls), applicationContext.resources
.getString(R.string.nc_notification_channel_calls_description), true,
@ -210,7 +231,10 @@ class MagicFirebaseMessagingService : FirebaseMessagingService() {
.setSubText(baseUrl)
.setShowWhen(true)
.setWhen(decryptedPushMessage!!.timestamp)
.setContentTitle(EmojiCompat.get().process(decryptedPushMessage!!.subject))
.setContentTitle("(notifId:" + notificationId.toString() + ") " + EmojiCompat.get()
.process
(decryptedPushMessage!!
.subject))
.setAutoCancel(true)
.setOngoing(true)
//.setTimeoutAfter(45000L)
@ -221,8 +245,28 @@ class MagicFirebaseMessagingService : FirebaseMessagingService() {
notification.flags = notification.flags or Notification.FLAG_INSISTENT
isServiceInForeground = true
checkIfCallIsActive(signatureVerification!!, decryptedPushMessage!!)
startForeground(decryptedPushMessage!!.timestamp.toInt(), notification)
Logging.d(javaClass.simpleName, " executing startForeground. " +
"timestamp=" + decryptedPushMessage!!.timestamp.toInt() + " notification=" + notification)
// startForeground(decryptedPushMessage!!.timestamp.toInt(), notification)
// TODO use NotificationManagerCompat.from(applicationContext).notify instead of
// startForeground works better to get Notifications also for first call (but not always).
// but the Notifications need to be deleted after accepting/declaring call. right now they still remain..
// it might be better to wait with Notification Handling when migration to master-broken
// is done. There the Notification Handling seems to be tidier (and more reliable?)
val notificationManager = NotificationManagerCompat.from(applicationContext)
notificationManager.notify(decryptedPushMessage!!.timestamp.toInt(), notification)
} else {
Logging.d(javaClass.simpleName, " else....(none of delete/deleteAll/call)")
val messageData = Data.Builder()
.putString(BundleKeys.KEY_NOTIFICATION_SUBJECT, subject)
.putString(BundleKeys.KEY_NOTIFICATION_SIGNATURE, signature)
@ -233,18 +277,21 @@ class MagicFirebaseMessagingService : FirebaseMessagingService() {
}
}
} catch (e1: NoSuchAlgorithmException) {
Log.d(NotificationWorker.TAG, "No proper algorithm to decrypt the message " + e1.localizedMessage)
Log.e(javaClass.simpleName, "No proper algorithm to decrypt the message " + e1)
} catch (e1: NoSuchPaddingException) {
Log.d(NotificationWorker.TAG, "No proper padding to decrypt the message " + e1.localizedMessage)
Log.e(javaClass.simpleName, "No proper padding to decrypt the message " + e1)
} catch (e1: InvalidKeyException) {
Log.d(NotificationWorker.TAG, "Invalid private key " + e1.localizedMessage)
Log.e(javaClass.simpleName, "Invalid private key " + e1)
}
} catch (exception: Exception) {
Log.d(NotificationWorker.TAG, "Something went very wrong " + exception.localizedMessage)
Log.e(javaClass.simpleName, "Something went very wrong " + exception)
}
}
private fun checkIfCallIsActive(signatureVerification: SignatureVerification, decryptedPushMessage: DecryptedPushMessage) {
Logging.d(TAG, "checkIfCallIsActive")
Logging.d(TAG, " isServiceInForeground:$isServiceInForeground")
val ncApi = retrofit!!.newBuilder().client(okHttpClient!!.newBuilder().cookieJar(JavaNetCookieJar(CookieManager())).build()).build().create(NcApi::class.java)
var hasParticipantsInCall = false
var inCallOnDifferentDevice = false
@ -262,6 +309,9 @@ class MagicFirebaseMessagingService : FirebaseMessagingService() {
override fun onNext(participantsOverall: ParticipantsOverall) {
val participantList: List<Participant> = participantsOverall.ocs.data
Logging.d(TAG, " participantList=$participantList")
hasParticipantsInCall = participantList.isNotEmpty()
if (!hasParticipantsInCall) {
for (participant in participantList) {
@ -282,9 +332,16 @@ class MagicFirebaseMessagingService : FirebaseMessagingService() {
}
}
override fun onError(e: Throwable) {}
override fun onError(e: Throwable) {
Logging.d(TAG, " checkIfCallIsActive-onError")
}
override fun onComplete() {
Logging.d(TAG, " checkIfCallIsActive-onComplete")
}
})
}
companion object {
private val TAG = "MagicFirebaseMessagingService"
}
}

Просмотреть файл

@ -338,7 +338,8 @@ public class CallNotificationController extends BaseController {
conversationNameTextView.setText(currentConversation.getDisplayName());
}
loadAvatar();
// TODO load avatar again
// loadAvatar();
checkIfAnyParticipantsRemainInRoom();
showAnswerControls();
}

Просмотреть файл

@ -33,6 +33,7 @@ import android.service.notification.StatusBarNotification
import com.nextcloud.talk.R
import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.utils.bundle.BundleKeys
import org.webrtc.Logging
import java.util.*
object NotificationUtils {
@ -117,6 +118,9 @@ object NotificationUtils {
}
fun cancelExistingNotificationWithId(context: Context?, conversationUser: UserEntity, notificationId: Long) {
Logging.d(javaClass.simpleName, "cancelExistingNotificationWithId. conversationUser.id:" +
conversationUser.id + " notificationId: " + notificationId)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && conversationUser.id != -1L &&
context != null) {
@ -124,9 +128,19 @@ object NotificationUtils {
val statusBarNotifications = notificationManager.activeNotifications
var notification: Notification?
Logging.d(javaClass.simpleName, "statusBarNotifications:" + statusBarNotifications.size)
for (statusBarNotification in statusBarNotifications) {
notification = statusBarNotification.notification
Logging.d(javaClass.simpleName, "notification.extras.getLong(BundleKeys.KEY_INTERNAL_USER_ID): " +
notification.extras.getLong(BundleKeys.KEY_INTERNAL_USER_ID))
Logging.d(javaClass.simpleName, "notification.extras.getLong(BundleKeys.KEY_NOTIFICATION_ID): " +
notification.extras.getLong(BundleKeys.KEY_NOTIFICATION_ID))
if (notification != null && !notification.extras.isEmpty) {
if (conversationUser.id == notification.extras.getLong(BundleKeys.KEY_INTERNAL_USER_ID) && notificationId == notification.extras.getLong(BundleKeys.KEY_NOTIFICATION_ID)) {
notificationManager.cancel(statusBarNotification.id)
@ -162,6 +176,9 @@ object NotificationUtils {
fun cancelExistingNotificationsForRoom(context: Context?, conversationUser: UserEntity,
roomTokenOrId: String) {
Logging.d(javaClass.simpleName, "cancelExistingNotificationsForRoom. conversationUser.id:" +
conversationUser.id + " roomTokenOrId: " + roomTokenOrId)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && conversationUser.id != -1L &&
context != null) {
@ -169,9 +186,15 @@ object NotificationUtils {
val statusBarNotifications = notificationManager.activeNotifications
var notification: Notification?
Logging.d(javaClass.simpleName, "statusBarNotifications:" + statusBarNotifications.size)
for (statusBarNotification in statusBarNotifications) {
notification = statusBarNotification.notification
Logging.d(javaClass.simpleName, "notification.extras.getLong(BundleKeys.KEY_INTERNAL_USER_ID): " +
notification.extras.getLong(BundleKeys.KEY_INTERNAL_USER_ID))
if (notification != null && !notification.extras.isEmpty) {
if (conversationUser.id == notification.extras.getLong(BundleKeys.KEY_INTERNAL_USER_ID) && roomTokenOrId == statusBarNotification.notification.extras.getString(BundleKeys.KEY_ROOM_TOKEN)) {
notificationManager.cancel(statusBarNotification.id)