From f4dad37914f35cc26d3698bb1e7ba13b79ddeb1d Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Fri, 28 Feb 2020 13:53:16 -0800 Subject: [PATCH] WIP in airplane - make notifications more useful --- TODO.md | 10 +- .../geeksville/mesh/service/MeshService.kt | 105 +++++++++++------- 2 files changed, 72 insertions(+), 43 deletions(-) diff --git a/TODO.md b/TODO.md index a22cfaa5..7bc4d8c1 100644 --- a/TODO.md +++ b/TODO.md @@ -1,8 +1,9 @@ # High priority Work items for soon alpha builds -* change info() log strings to debug() -* have the foreground service's notification show a summary of network status, add (individually maskable) notifications for received texts or new positions +* fix notification setSmallIcon parameter +* have the foreground service's notification show a summary of network status "connected/disconnected, 5 of 6 nodes, nearest: kevin 5km", +* have notification (individually maskable) notifications for received texts - use file:///home/kevinh/packages/android-sdk-linux/docs/reference/android/support/v4/app/NotificationCompat.BigTextStyle.html * show offline nodes as greyed out * show time since last contact on the node info card * show pointer arrow on the outside of the user icons, always pointing towoards them @@ -54,6 +55,8 @@ Do this "Signal app compatible" release relatively soon after the alpha release # Medium priority Things for the betaish period. +* Use setLargeIcon to show user icons in the notification: file:///home/kevinh/packages/android-sdk-linux/docs/design/patterns/notifications.html +* Our notification about messages should use VISIBLITY_PRIVATE + setPublicVersion per file:///home/kevinh/packages/android-sdk-linux/docs/guide/topics/ui/notifiers/notifications.html * let users save old channels * make sw update work while node is connected to mesh - the problem is there are _two_ instances of SafeBluetooth at that moment and therefore we violate undocumented android mutex rules at the BluetoothDevice level. Either make SafeBluetooth lock at the device level or (not as good) make SafeBluetooth a singleton. @@ -153,4 +156,5 @@ Don't leave device discoverable. Don't let unpaired users do things with device * add screenshots and text to play store entry * if no radio is selected, launch app on the radio select screen * connect to bluetooth device automatically using minimum power - start looking at phone boot -* tell various vendors & post in forums \ No newline at end of file +* tell various vendors & post in forums +* change info() log strings to debug() diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt index 6eaa9859..38d1e5ed 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -1,10 +1,7 @@ package com.geeksville.mesh.service import android.annotation.SuppressLint -import android.app.Notification -import android.app.NotificationChannel -import android.app.NotificationManager -import android.app.Service +import android.app.* import android.content.BroadcastReceiver import android.content.Context import android.content.Intent @@ -273,52 +270,78 @@ class MeshService : Service(), Logging { return channelId } - private fun startForeground() { + private val notifyId = 101 + val notificationManager: NotificationManager by lazy() { + getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + } - // val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager - val channelId = - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - createNotificationChannel() - } else { - // If earlier version channel ID is not used - // https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context) - "" - } + val channelId = + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + createNotificationChannel() + } else { + // If earlier version channel ID is not used + // https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context) + "" + } - val notificationBuilder = NotificationCompat.Builder(this, channelId) - val notification = notificationBuilder.setOngoing(true) + var mainAppIntent = Intent(this, MainActivity::class.java) + val openAppIntent = PendingIntent.getActivity(this, 0, mainAppIntent, 0) + val notificationBuilder = NotificationCompat.Builder(this, channelId) + + val summaryString + get() = if (!isConnected) + "No radio connected" + else + "Connected $numOnlineNodes / $numNodes online" + + override fun toString() = summaryString + + /** + * Generate a new version of our notification - reflecting current app state + */ + private fun createNotification(): Notification { + val recentMessage = "FIXME a recent text message" + + val shortContent = "FIXME Include nearest node or text message info" + + val builder = notificationBuilder.setOngoing(true) .setPriority(PRIORITY_MIN) - .setCategory(Notification.CATEGORY_SERVICE) + .setCategory(if (recentMessage != null) Notification.CATEGORY_SERVICE else Notification.CATEGORY_MESSAGE) .setSmallIcon(android.R.drawable.stat_sys_data_bluetooth) - //.setContentTitle("Meshtastic") // leave this off for now so our notification looks smaller - //.setContentText("Listening for mesh...") - .build() - startForeground(101, notification) + .setContentTitle("Meshtastic: $summaryString") // leave this off for now so our notification looks smaller + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + .setContentIntent(openAppIntent) + + if(shortContent != null) + builder.setContentText(shortContent) + + if (recentMessage != null) + builder.setStyle( + NotificationCompat.BigTextStyle() + .bigText(recentMessage) + ) + + return builder.build() + } + + /** + * Update our notification with latest data + */ + private fun updateNotification() { + notificationManager.notify(notifyId, createNotification()) + } + + /** + * tell android not to kill us + */ + private fun startForeground() { + startForeground(notifyId, createNotification()) } override fun onCreate() { super.onCreate() info("Creating mesh service") - - /* - // This intent will be used if the user clicks on the item in the status bar - val notificationIntent = Intent(this, MainActivity::class.java) - val pendingIntent = PendingIntent.getActivity( - this, 0, - notificationIntent, 0 - ) - - val notification: Notification = NotificationCompat.Builder(this) - .setSmallIcon(android.R.drawable.stat_sys_data_bluetooth) - .setContentTitle("Meshtastic") - .setContentText("Listening for mesh...") - .setContentIntent(pendingIntent).build() - - // We are required to call this within a few seconds of create - startForeground(1337, notification) - - */ startForeground() // we listen for messages from the radio receiver _before_ trying to create the service @@ -654,6 +677,8 @@ class MeshService : Service(), Logging { DataPair("num_online", numOnlineNodes) ) } + + updateNotification() } /**