From 409982ad71a01ef5acd8d61676a511a3abbae7b9 Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Mon, 26 Sep 2022 19:28:51 +0300 Subject: [PATCH] android: Two more notifications when contact connected or connection request received (#1129) * Two more notifications when contact connected or connection request received * Large image in notification * Do not show contact's icon when it't not permitted * Sound and vibrate for notification * No large icon in other cases * Small change --- apps/android/app/src/main/AndroidManifest.xml | 6 ++ .../java/chat/simplex/app/model/NtfManager.kt | 85 +++++++++++++++++-- .../java/chat/simplex/app/model/SimpleXAPI.kt | 5 +- .../app/src/main/res/values-de/strings.xml | 2 + .../app/src/main/res/values-ru/strings.xml | 2 + .../app/src/main/res/values/strings.xml | 2 + 6 files changed, 90 insertions(+), 12 deletions(-) diff --git a/apps/android/app/src/main/AndroidManifest.xml b/apps/android/app/src/main/AndroidManifest.xml index 3f04b64fcb..bbf247909e 100644 --- a/apps/android/app/src/main/AndroidManifest.xml +++ b/apps/android/app/src/main/AndroidManifest.xml @@ -103,6 +103,12 @@ android:resource="@xml/file_paths" /> + + + = emptyList()) { Log.d(TAG, "notifyMessageReceived $chatId") val now = Clock.System.now().toEpochMilliseconds() val recentNotification = (now - prevNtfTime.getOrDefault(chatId, 0) < msgNtfTimeoutMs) @@ -79,18 +103,36 @@ class NtfManager(val context: Context, private val appPreferences: AppPreference val previewMode = appPreferences.notificationPreviewMode.get() val title = if (previewMode == NotificationPreviewMode.HIDDEN.name) generalGetString(R.string.notification_preview_somebody) else displayName val content = if (previewMode != NotificationPreviewMode.MESSAGE.name) generalGetString(R.string.notification_preview_new_message) else msgText - val notification = NotificationCompat.Builder(context, MessageChannel) + val largeIcon = when { + actions.isEmpty() -> null + image == null || previewMode == NotificationPreviewMode.HIDDEN.name -> BitmapFactory.decodeResource(context.resources, R.drawable.icon) + else -> base64ToBitmap(image) + } + val builder = NotificationCompat.Builder(context, MessageChannel) .setContentTitle(title) .setContentText(content) .setPriority(NotificationCompat.PRIORITY_HIGH) .setGroup(MessageGroup) .setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN) .setSmallIcon(R.drawable.ntf_icon) + .setLargeIcon(largeIcon) .setColor(0x88FFFF) .setAutoCancel(true) + .setVibrate(if (actions.isEmpty()) null else longArrayOf(0, 250, 250, 250)) .setContentIntent(chatPendingIntent(OpenChatAction, chatId)) - .setSilent(recentNotification) - .build() + .setSilent(if (actions.isEmpty()) recentNotification else false) + + for (action in actions) { + val flags = PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE + val actionIntent = Intent(SimplexApp.context, NtfActionReceiver::class.java) + actionIntent.action = action.name + actionIntent.putExtra(ChatIdKey, chatId) + val actionPendingIntent: PendingIntent = PendingIntent.getBroadcast(SimplexApp.context, 0, actionIntent, flags) + val actionButton = when (action) { + NotificationAction.ACCEPT_CONTACT_REQUEST -> generalGetString(R.string.accept) + } + builder.addAction(0, actionButton, actionPendingIntent) + } val summary = NotificationCompat.Builder(context, MessageChannel) .setSmallIcon(R.drawable.ntf_icon) @@ -103,7 +145,7 @@ class NtfManager(val context: Context, private val appPreferences: AppPreference with(NotificationManagerCompat.from(context)) { // using cInfo.id only shows one notification per chat and updates it when the message arrives - notify(chatId.hashCode(), notification) + notify(chatId.hashCode(), builder.build()) notify(0, summary) } } @@ -141,6 +183,10 @@ class NtfManager(val context: Context, private val appPreferences: AppPreference generalGetString(R.string.notification_preview_somebody) else invitation.contact.displayName + val largeIcon = if (image == null || previewMode == NotificationPreviewMode.HIDDEN.name) + BitmapFactory.decodeResource(context.resources, R.drawable.icon) + else + base64ToBitmap(image) ntfBuilder = ntfBuilder .setContentTitle(title) @@ -148,7 +194,7 @@ class NtfManager(val context: Context, private val appPreferences: AppPreference .setPriority(NotificationCompat.PRIORITY_HIGH) .setCategory(NotificationCompat.CATEGORY_CALL) .setSmallIcon(R.drawable.ntf_icon) - .setLargeIcon(if (image == null) BitmapFactory.decodeResource(context.resources, R.drawable.icon) else base64ToBitmap(image)) + .setLargeIcon(largeIcon) .setColor(0x88FFFF) .setAutoCancel(true) with(NotificationManagerCompat.from(context)) { @@ -183,10 +229,31 @@ class NtfManager(val context: Context, private val appPreferences: AppPreference var intent = Intent(context, MainActivity::class.java) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP) .setAction(intentAction) - if (chatId != null) intent = intent.putExtra("chatId", chatId) + if (chatId != null) intent = intent.putExtra(ChatIdKey, chatId) return TaskStackBuilder.create(context).run { addNextIntentWithParentStack(intent) getPendingIntent(uniqueInt, PendingIntent.FLAG_IMMUTABLE) } } + + /** + * Processes every action specified by [NotificationCompat.Builder.addAction] that comes with [NotificationAction] + * and [ChatInfo.id] as [ChatIdKey] in extra + * */ + class NtfActionReceiver: BroadcastReceiver() { + override fun onReceive(context: Context?, intent: Intent?) { + val chatId = intent?.getStringExtra(ChatIdKey) ?: return + val cInfo = SimplexApp.context.chatModel.getChat(chatId)?.chatInfo + when (intent.action) { + NotificationAction.ACCEPT_CONTACT_REQUEST.name -> { + if (cInfo !is ChatInfo.ContactRequest) return + acceptContactRequest(cInfo, SimplexApp.context.chatModel) + SimplexApp.context.chatModel.controller.ntfManager.cancelNotificationsForChat(chatId) + } + else -> { + Log.e(TAG, "Unknown action. Make sure you provide action from NotificationAction enum") + } + } + } + } } diff --git a/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt b/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt index dd4aacf5b2..7b44743f8e 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/model/SimpleXAPI.kt @@ -6,7 +6,6 @@ import android.app.ActivityManager.RunningAppProcessInfo import android.app.Application import android.content.* import android.net.Uri -import android.os.Build import android.os.PowerManager import android.provider.Settings import android.util.Log @@ -849,7 +848,7 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a chatModel.updateContact(r.contact) chatModel.removeChat(r.contact.activeConn.id) chatModel.updateNetworkStatus(r.contact.id, Chat.NetworkStatus.Connected()) -// NtfManager.shared.notifyContactConnected(contact) + ntfManager.notifyContactConnected(r.contact) } is CR.ContactConnecting -> { chatModel.updateContact(r.contact) @@ -859,7 +858,7 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a val contactRequest = r.contactRequest val cInfo = ChatInfo.ContactRequest(contactRequest) chatModel.addChat(Chat(chatInfo = cInfo, chatItems = listOf())) -// NtfManager.shared.notifyContactRequest(contactRequest) + ntfManager.notifyContactRequestReceived(cInfo) } is CR.ContactUpdated -> { val cInfo = ChatInfo.Direct(r.toContact) diff --git a/apps/android/app/src/main/res/values-de/strings.xml b/apps/android/app/src/main/res/values-de/strings.xml index 3af728c470..16f753a348 100644 --- a/apps/android/app/src/main/res/values-de/strings.xml +++ b/apps/android/app/src/main/res/values-de/strings.xml @@ -112,6 +112,8 @@ Kontakt und Nachricht verbergen Kontakt verbergen: neue Nachricht + New contact request + Сonnected SimpleX Sperre diff --git a/apps/android/app/src/main/res/values-ru/strings.xml b/apps/android/app/src/main/res/values-ru/strings.xml index b6f16e84fe..4a7ba2adea 100644 --- a/apps/android/app/src/main/res/values-ru/strings.xml +++ b/apps/android/app/src/main/res/values-ru/strings.xml @@ -112,6 +112,8 @@ Скрывать контакт и сообщение Контакт скрыт: новое сообщение + Новый запрос на соединение + Соединен(а) Блокировка SimpleX diff --git a/apps/android/app/src/main/res/values/strings.xml b/apps/android/app/src/main/res/values/strings.xml index 91bbc8d46b..3ec7a3e4c1 100644 --- a/apps/android/app/src/main/res/values/strings.xml +++ b/apps/android/app/src/main/res/values/strings.xml @@ -112,6 +112,8 @@ Hide contact and message Contact hidden: new message + New contact request + Connected SimpleX Lock