From 4ea44095df41b257e0db8823a517c3d06e99c6aa Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 2 Feb 2021 10:47:54 +0800 Subject: [PATCH 01/12] 1.1.40 trying to squash native crash in mb via testlab. --- app/build.gradle | 4 ++-- .../com/geeksville/mesh/ui/MapFragment.kt | 21 ++++++++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 112bb7572..fc08675b3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -31,8 +31,8 @@ android { applicationId "com.geeksville.mesh" minSdkVersion 21 // The oldest emulator image I have tried is 22 (though 21 probably works) targetSdkVersion 29 - versionCode 20139 // format is Mmmss (where M is 1+the numeric major number - versionName "1.1.39" + versionCode 20140 // format is Mmmss (where M is 1+the numeric major number + versionName "1.1.40" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" // per https://developer.android.com/studio/write/vector-asset-studio diff --git a/app/src/main/java/com/geeksville/mesh/ui/MapFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/MapFragment.kt index 21d5a650c..7a694e408 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/MapFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/MapFragment.kt @@ -136,7 +136,7 @@ class MapFragment : ScreenFragment("Map"), Logging { * Mapbox native code can crash painfully if you ever call a mapbox view function while the view is not actively being show */ private val isViewVisible: Boolean - get() = view != null && isResumed + get() = view != null && isResumed && (mapView?.isDestroyed != false) override fun onViewCreated(viewIn: View, savedInstanceState: Bundle?) { super.onViewCreated(viewIn, savedInstanceState) @@ -145,9 +145,9 @@ class MapFragment : ScreenFragment("Map"), Logging { if ((requireContext().applicationContext as GeeksvilleApplication).isAnalyticsAllowed) { val vIn = viewIn.findViewById(R.id.mapView) mapView = vIn - vIn.onCreate(savedInstanceState) - mapView?.let { v -> + v.onCreate(savedInstanceState) + // Each time the pane is shown start fetching new map info (we do this here instead of // onCreate because getMapAsync can die in native code if the view goes away) v.getMapAsync { map -> @@ -205,14 +205,25 @@ class MapFragment : ScreenFragment("Map"), Logging { } override fun onDestroyView() { - mapView?.onDestroy() super.onDestroyView() + mapView?.onDestroy() } override fun onSaveInstanceState(outState: Bundle) { - mapView?.onSaveInstanceState(outState) + mapView?.let { + if (!it.isDestroyed) + it.onSaveInstanceState(outState) + } super.onSaveInstanceState(outState) } + + override fun onLowMemory() { + mapView?.let { + if (!it.isDestroyed) + it.onLowMemory() + } + super.onLowMemory() + } } From 8d04a71fc4f0ccb4075ded4517450126d56aac11 Mon Sep 17 00:00:00 2001 From: Vadim Furman Date: Tue, 2 Feb 2021 18:39:41 -0800 Subject: [PATCH 02/12] Fix radio button enabled/disabled state to match device connected/not-connected state --- .../geeksville/mesh/ui/SettingsFragment.kt | 102 ++++++++++-------- 1 file changed, 55 insertions(+), 47 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt index 78f772151..bfb7f82f2 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt @@ -660,6 +660,55 @@ class SettingsFragment : ScreenFragment("Settings"), Logging { binding.scanProgressBar.visibility = visible binding.deviceRadioGroup.visibility = visible } + private fun updateDevicesButtons( devices: MutableMap?) { + // Remove the old radio buttons and repopulate + binding.deviceRadioGroup.removeAllViews() + + if(devices == null) return + + val adapter = scanModel.bluetoothAdapter + var hasShownOurDevice = false + devices.values.forEach { device -> + if (device.address == scanModel.selectedNotNull) + hasShownOurDevice = true + addDeviceButton(device, true) + } + + // The device the user is already paired with is offline currently, still show it + // it in the list, but greyed out + if (!hasShownOurDevice) { + // Note: we pull this into a tempvar, because otherwise some other thread can change selectedAddress after our null check + // and before use + val bleAddr = scanModel.selectedBluetooth + + if (bleAddr != null && adapter != null && adapter.isEnabled) { + val bDevice = + adapter.getRemoteDevice(bleAddr) + if (bDevice.name != null) { // ignore nodes that node have a name, that means we've lost them since they appeared + val curDevice = BTScanModel.DeviceListEntry( + bDevice.name, + scanModel.selectedAddress!!, + bDevice.bondState == BOND_BONDED + ) + addDeviceButton(curDevice, model.isConnected.value == MeshService.ConnectionState.CONNECTED) + } + } else if (scanModel.selectedUSB != null) { + // Must be a USB device, show a placeholder disabled entry + val curDevice = BTScanModel.DeviceListEntry( + scanModel.selectedUSB!!, + scanModel.selectedAddress!!, + false + ) + addDeviceButton(curDevice, false) + } + } + + val hasBonded = + RadioInterfaceService.getBondedDeviceAddress(requireContext()) != null + + // get rid of the warning text once at least one device is paired + binding.warningNotPaired.visibility = if (hasBonded) View.GONE else View.VISIBLE + } /// Setup the GUI to do a classic (pre SDK 26 BLE scan) private fun initClassicScan() { @@ -681,54 +730,13 @@ class SettingsFragment : ScreenFragment("Settings"), Logging { } }) - scanModel.devices.observe(viewLifecycleOwner, Observer { devices -> - // Remove the old radio buttons and repopulate - binding.deviceRadioGroup.removeAllViews() + scanModel.devices.observe( + viewLifecycleOwner, + Observer { devices -> updateDevicesButtons(devices) }) - val adapter = scanModel.bluetoothAdapter - - var hasShownOurDevice = false - devices.values.forEach { device -> - if (device.address == scanModel.selectedNotNull) - hasShownOurDevice = true - addDeviceButton(device, true) - } - - // The device the user is already paired with is offline currently, still show it - // it in the list, but greyed out - if (!hasShownOurDevice) { - // Note: we pull this into a tempvar, because otherwise some other thread can change selectedAddress after our null check - // and before use - val bleAddr = scanModel.selectedBluetooth - - if (bleAddr != null && adapter != null && adapter.isEnabled) { - val bDevice = - adapter.getRemoteDevice(bleAddr) - if (bDevice.name != null) { // ignore nodes that node have a name, that means we've lost them since they appeared - val curDevice = BTScanModel.DeviceListEntry( - bDevice.name, - scanModel.selectedAddress!!, - bDevice.bondState == BOND_BONDED - ) - addDeviceButton(curDevice, false) - } - } else if (scanModel.selectedUSB != null) { - // Must be a USB device, show a placeholder disabled entry - val curDevice = BTScanModel.DeviceListEntry( - scanModel.selectedUSB!!, - scanModel.selectedAddress!!, - false - ) - addDeviceButton(curDevice, false) - } - } - - val hasBonded = - RadioInterfaceService.getBondedDeviceAddress(requireContext()) != null - - // get rid of the warning text once at least one device is paired - binding.warningNotPaired.visibility = if (hasBonded) View.GONE else View.VISIBLE - }) + model.isConnected.observe( + viewLifecycleOwner, + { updateDevicesButtons(scanModel.devices.value) }) } /// Start running the modern scan, once it has one result we enable the From ac8fd1344d955953e56e0f46126c696e2f2af4c3 Mon Sep 17 00:00:00 2001 From: Vadim Furman Date: Tue, 2 Feb 2021 19:01:11 -0800 Subject: [PATCH 03/12] Updated comment --- app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt index bfb7f82f2..fdf4ce85c 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/SettingsFragment.kt @@ -674,8 +674,9 @@ class SettingsFragment : ScreenFragment("Settings"), Logging { addDeviceButton(device, true) } - // The device the user is already paired with is offline currently, still show it - // it in the list, but greyed out + // The selected device is not in the scan; it is either offline, or it doesn't advertise + // itself (most BLE devices don't advertise when connected). + // Show it in the list, greyed out based on connection status. if (!hasShownOurDevice) { // Note: we pull this into a tempvar, because otherwise some other thread can change selectedAddress after our null check // and before use From 55fd7c7330159eca39c600992aed1747aa656ab8 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Thu, 4 Feb 2021 08:20:43 +0800 Subject: [PATCH 04/12] make a guaranteed non vector version of icon for older androids --- .../com/geeksville/mesh/service/MeshServiceNotifications.kt | 2 +- app/src/main/res/drawable-hdpi/app_icon_novect.png | 1 + app/src/main/res/drawable-mdpi/app_icon_novect.png | 1 + app/src/main/res/drawable-xhdpi/app_icon_novect.png | 1 + app/src/main/res/drawable-xxhdpi/app_icon_novect.png | 1 + 5 files changed, 5 insertions(+), 1 deletion(-) create mode 120000 app/src/main/res/drawable-hdpi/app_icon_novect.png create mode 120000 app/src/main/res/drawable-mdpi/app_icon_novect.png create mode 120000 app/src/main/res/drawable-xhdpi/app_icon_novect.png create mode 120000 app/src/main/res/drawable-xxhdpi/app_icon_novect.png diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotifications.kt b/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotifications.kt index ddf55a306..207ea93a1 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotifications.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotifications.kt @@ -73,7 +73,7 @@ class MeshServiceNotifications( val builder = NotificationCompat.Builder(context, channelId).setOngoing(true) .setPriority(NotificationCompat.PRIORITY_MIN) .setCategory(category) - .setSmallIcon(R.drawable.app_icon) + .setSmallIcon(if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) R.drawable.app_icon_novect else R.drawable.app_icon) // vector form icons don't work reliably on older androids .setContentTitle(summaryString) // leave this off for now so our notification looks smaller .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) .setContentIntent(openAppIntent) diff --git a/app/src/main/res/drawable-hdpi/app_icon_novect.png b/app/src/main/res/drawable-hdpi/app_icon_novect.png new file mode 120000 index 000000000..ef5958e92 --- /dev/null +++ b/app/src/main/res/drawable-hdpi/app_icon_novect.png @@ -0,0 +1 @@ +app_icon.png \ No newline at end of file diff --git a/app/src/main/res/drawable-mdpi/app_icon_novect.png b/app/src/main/res/drawable-mdpi/app_icon_novect.png new file mode 120000 index 000000000..ef5958e92 --- /dev/null +++ b/app/src/main/res/drawable-mdpi/app_icon_novect.png @@ -0,0 +1 @@ +app_icon.png \ No newline at end of file diff --git a/app/src/main/res/drawable-xhdpi/app_icon_novect.png b/app/src/main/res/drawable-xhdpi/app_icon_novect.png new file mode 120000 index 000000000..ef5958e92 --- /dev/null +++ b/app/src/main/res/drawable-xhdpi/app_icon_novect.png @@ -0,0 +1 @@ +app_icon.png \ No newline at end of file diff --git a/app/src/main/res/drawable-xxhdpi/app_icon_novect.png b/app/src/main/res/drawable-xxhdpi/app_icon_novect.png new file mode 120000 index 000000000..ef5958e92 --- /dev/null +++ b/app/src/main/res/drawable-xxhdpi/app_icon_novect.png @@ -0,0 +1 @@ +app_icon.png \ No newline at end of file From e919104bbb758372a2252e5eceda2c687467ba96 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Thu, 4 Feb 2021 08:21:01 +0800 Subject: [PATCH 05/12] update jvm --- .idea/compiler.xml | 2 +- .idea/misc.xml | 2 +- .idea/vcs.xml | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 0f4a1a9c8..38982c38b 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -1,7 +1,7 @@ - + diff --git a/.idea/misc.xml b/.idea/misc.xml index d5d35ec44..b3c4f59b4 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index e8f81507d..bc2dfb5ae 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -3,6 +3,7 @@ + From a209d3b585a3397d073a4beb782cb733fd7a8ac6 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Thu, 4 Feb 2021 09:20:19 +0800 Subject: [PATCH 06/12] update to latest kotlin --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 5c61f9d69..cfef6d972 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.4.21' + ext.kotlin_version = '1.4.30' ext.coroutines_version = "1.3.9" repositories { From 3db5be760d44c6272463e866bfcf95234de27a94 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Thu, 4 Feb 2021 09:25:06 +0800 Subject: [PATCH 07/12] 1.1.41 --- .idea/compiler.xml | 2 +- .idea/misc.xml | 2 +- app/build.gradle | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 38982c38b..0f4a1a9c8 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -1,7 +1,7 @@ - + diff --git a/.idea/misc.xml b/.idea/misc.xml index b3c4f59b4..d5d35ec44 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + diff --git a/app/build.gradle b/app/build.gradle index fc08675b3..fb75ed47a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -31,8 +31,8 @@ android { applicationId "com.geeksville.mesh" minSdkVersion 21 // The oldest emulator image I have tried is 22 (though 21 probably works) targetSdkVersion 29 - versionCode 20140 // format is Mmmss (where M is 1+the numeric major number - versionName "1.1.40" + versionCode 20141 // format is Mmmss (where M is 1+the numeric major number + versionName "1.1.41" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" // per https://developer.android.com/studio/write/vector-asset-studio From 65e553f3d1286d1a43a8d39d062e074e1f4e67d3 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Thu, 4 Feb 2021 11:24:55 +0800 Subject: [PATCH 08/12] update kotlin version --- geeksville-androidlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geeksville-androidlib b/geeksville-androidlib index f3812d848..d7c3fa8ab 160000 --- a/geeksville-androidlib +++ b/geeksville-androidlib @@ -1 +1 @@ -Subproject commit f3812d8484c571f62c72d1509a1e02357fda5b8e +Subproject commit d7c3fa8ab6a47169e5dc8761d03d24588c3dd845 From 97d2ecbd0f3fe5070fbb51d6e9e41daee36f544b Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Thu, 4 Feb 2021 23:07:16 +0800 Subject: [PATCH 09/12] fix autobug: don't let users try to update firmware over USB --- app/src/main/java/com/geeksville/mesh/service/MeshService.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 47e05df48..677704698 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -1085,6 +1085,9 @@ class MeshService : Service(), Logging { setFirmwareUpdateFilename(myInfo) + val a = RadioInterfaceService.getBondedDeviceAddress(this) + val isBluetoothInterface = a != null && a.startsWith("x") + val mi = with(myInfo) { MyNodeInfo( myNodeNum, @@ -1093,7 +1096,7 @@ class MeshService : Service(), Logging { hwModel, firmwareVersion, firmwareUpdateFilename != null, - SoftwareUpdateService.shouldUpdate( + isBluetoothInterface && SoftwareUpdateService.shouldUpdate( this@MeshService, DeviceVersion(firmwareVersion) ), From d11e7674f6a6dfa4db87b7fe3f16497fab174b63 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Thu, 4 Feb 2021 23:39:44 +0800 Subject: [PATCH 10/12] fix autobug: don't spam crashlytics when we expect position sending to fail --- app/src/main/java/com/geeksville/mesh/service/MeshService.kt | 4 +++- .../java/com/geeksville/mesh/service/RadioInterfaceService.kt | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) 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 677704698..5090fe03f 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -73,7 +73,9 @@ class MeshService : Service(), Logging { class IdNotFoundException(id: String) : Exception("ID not found $id") class NodeNumNotFoundException(id: Int) : Exception("NodeNum not found $id") - class IsUpdatingException() : Exception("Operation prohibited during firmware update") + + /** We treat software update as similar to loss of comms to the regular bluetooth service (so things like sendPosition for background GPS ignores the problem */ + class IsUpdatingException() : RadioNotConnectedException("Operation prohibited during firmware update") /** * Talk to our running service and try to set a new device address. And then immediately diff --git a/app/src/main/java/com/geeksville/mesh/service/RadioInterfaceService.kt b/app/src/main/java/com/geeksville/mesh/service/RadioInterfaceService.kt index c24e5aa87..78890c334 100644 --- a/app/src/main/java/com/geeksville/mesh/service/RadioInterfaceService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/RadioInterfaceService.kt @@ -22,7 +22,7 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.cancel -class RadioNotConnectedException(message: String = "Not connected to radio") : +open class RadioNotConnectedException(message: String = "Not connected to radio") : BLEException(message) From 2c3b73ae88d86bcb6e1cfd6986dd009cb89e051b Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Fri, 5 Feb 2021 09:31:25 +0800 Subject: [PATCH 11/12] fix(?) for cyanogen problem with custom statusbar icons --- .../geeksville/mesh/service/MeshService.kt | 3 ++ .../mesh/service/MeshServiceNotifications.kt | 46 ++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) 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 5090fe03f..b8a4ff2f4 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -344,6 +344,9 @@ class MeshService : Service(), Logging { radio.close() saveSettings() + stopForeground(true) // Make sure we aren't using the notification first + serviceNotifications.close() + super.onDestroy() serviceJob.cancel() } diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotifications.kt b/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotifications.kt index 207ea93a1..1217c4699 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotifications.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotifications.kt @@ -6,27 +6,40 @@ import android.app.NotificationManager import android.app.PendingIntent import android.content.Context import android.content.Intent +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.Canvas import android.graphics.Color import android.os.Build import androidx.annotation.RequiresApi import androidx.core.app.NotificationCompat +import androidx.core.content.ContextCompat +import androidx.core.graphics.drawable.DrawableCompat import com.geeksville.mesh.DataPacket import com.geeksville.mesh.MainActivity import com.geeksville.mesh.R import com.geeksville.mesh.android.notificationManager import com.geeksville.mesh.utf8 +import java.io.Closeable + class MeshServiceNotifications( private val context: Context -) { +) : Closeable +{ private val notificationManager: NotificationManager get() = context.notificationManager val notifyId = 101 + private var largeIcon: Bitmap? = null @RequiresApi(Build.VERSION_CODES.O) private fun createNotificationChannel(): String { val channelId = "my_service" val channelName = context.getString(R.string.meshtastic_service_notifications) - val channel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH).apply { + val channel = NotificationChannel( + channelId, + channelName, + NotificationManager.IMPORTANCE_HIGH + ).apply { lightColor = Color.BLUE importance = NotificationManager.IMPORTANCE_NONE lockscreenVisibility = Notification.VISIBILITY_PRIVATE @@ -61,6 +74,25 @@ class MeshServiceNotifications( PendingIntent.getActivity(context, 0, Intent(context, MainActivity::class.java), 0) } + /** + * Generate a bitmap from a vector drawable (even on old builds) + * https://stackoverflow.com/questions/33696488/getting-bitmap-from-vector-drawable + */ + fun getBitmapFromVectorDrawable(drawableId: Int): Bitmap { + var drawable = ContextCompat.getDrawable(context, drawableId)!! + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + drawable = DrawableCompat.wrap(drawable).mutate() + } + val bitmap = Bitmap.createBitmap( + drawable.intrinsicWidth, + drawable.intrinsicHeight, Bitmap.Config.ARGB_8888 + ) + val canvas = Canvas(bitmap) + drawable.setBounds(0, 0, canvas.width, canvas.height) + drawable.draw(canvas) + return bitmap + } + /** * Generate a new version of our notification - reflecting current app state */ @@ -69,11 +101,16 @@ class MeshServiceNotifications( summaryString: String, senderName: String ): Notification { + // We delay making this bitmap until we know we need it + if(largeIcon == null) + largeIcon = getBitmapFromVectorDrawable(R.mipmap.ic_launcher2) + val category = if (recentReceivedText != null) Notification.CATEGORY_SERVICE else Notification.CATEGORY_MESSAGE val builder = NotificationCompat.Builder(context, channelId).setOngoing(true) .setPriority(NotificationCompat.PRIORITY_MIN) .setCategory(category) .setSmallIcon(if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) R.drawable.app_icon_novect else R.drawable.app_icon) // vector form icons don't work reliably on older androids + .setLargeIcon(largeIcon) // we must include a large icon because of a bug in cyanogenmod https://github.com/open-keychain/open-keychain/issues/1356#issue-89493995 .setContentTitle(summaryString) // leave this off for now so our notification looks smaller .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) .setContentIntent(openAppIntent) @@ -93,4 +130,9 @@ class MeshServiceNotifications( return builder.build() } + + override fun close() { + largeIcon?.recycle() + largeIcon = null + } } From 48d870a035b3809502ebd4af75f18b31f02962f9 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Fri, 5 Feb 2021 09:31:58 +0800 Subject: [PATCH 12/12] 1.1.42 --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index fb75ed47a..589fa3613 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -31,8 +31,8 @@ android { applicationId "com.geeksville.mesh" minSdkVersion 21 // The oldest emulator image I have tried is 22 (though 21 probably works) targetSdkVersion 29 - versionCode 20141 // format is Mmmss (where M is 1+the numeric major number - versionName "1.1.41" + versionCode 20142 // format is Mmmss (where M is 1+the numeric major number + versionName "1.1.42" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" // per https://developer.android.com/studio/write/vector-asset-studio