From aef317a140651ef491db99eca66b2db0413b6aa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?lollipopkit=F0=9F=8F=B3=EF=B8=8F=E2=80=8D=E2=9A=A7?= =?UTF-8?q?=EF=B8=8F?= <10864310+lollipopkit@users.noreply.github.com> Date: Tue, 24 Sep 2024 22:01:35 +0800 Subject: [PATCH] opt.: dismiss notification if no ssh conn (#592) --- .../tech/lolli/toolbox/ForegroundService.kt | 42 ++++++++++++++----- .../kotlin/tech/lolli/toolbox/MainActivity.kt | 5 +++ lib/core/channel/bg_run.dart | 4 ++ lib/main.dart | 5 --- lib/view/page/ssh/page.dart | 19 ++++++++- 5 files changed, 59 insertions(+), 16 deletions(-) diff --git a/android/app/src/main/kotlin/tech/lolli/toolbox/ForegroundService.kt b/android/app/src/main/kotlin/tech/lolli/toolbox/ForegroundService.kt index ccff8c40f..66a5452d0 100644 --- a/android/app/src/main/kotlin/tech/lolli/toolbox/ForegroundService.kt +++ b/android/app/src/main/kotlin/tech/lolli/toolbox/ForegroundService.kt @@ -14,12 +14,17 @@ class ForegroundService : Service() { } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { - val notification = createNotification() - startForeground(1, notification) - - // Exec your code here - - return START_STICKY + when (intent?.action) { + "ACTION_STOP_FOREGROUND" -> { + stopForegroundService() + return START_NOT_STICKY + } + else -> { + val notification = createNotification() + startForeground(1, notification) + return START_STICKY + } + } } override fun onBind(intent: Intent): IBinder? { @@ -47,20 +52,37 @@ class ForegroundService : Service() { PendingIntent.FLAG_IMMUTABLE ) + val deleteIntent = Intent(this, ForegroundService::class.java).apply { + action = "ACTION_STOP_FOREGROUND" + } + val deletePendingIntent = PendingIntent.getService( + this, + 0, + deleteIntent, + PendingIntent.FLAG_IMMUTABLE + ) + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { Notification.Builder(this, chanId) - .setContentTitle("App is running") - .setContentText("Click to open the app") + .setContentTitle("Server Box") + .setContentText("Open the app") .setSmallIcon(R.mipmap.ic_launcher) .setContentIntent(pendingIntent) + .addAction(android.R.drawable.ic_delete, "Stop", deletePendingIntent) .build() } else { Notification.Builder(this) - .setContentTitle("App is running") - .setContentText("Click to open the app") + .setContentTitle("Server Box") + .setContentText("Open the app") .setSmallIcon(R.mipmap.ic_launcher) .setContentIntent(pendingIntent) + .addAction(android.R.drawable.ic_delete, "Stop", deletePendingIntent) .build() } } + + fun stopForegroundService() { + stopForeground(true) + stopSelf() + } } \ No newline at end of file diff --git a/android/app/src/main/kotlin/tech/lolli/toolbox/MainActivity.kt b/android/app/src/main/kotlin/tech/lolli/toolbox/MainActivity.kt index 9bc17d377..b0af63cc8 100644 --- a/android/app/src/main/kotlin/tech/lolli/toolbox/MainActivity.kt +++ b/android/app/src/main/kotlin/tech/lolli/toolbox/MainActivity.kt @@ -31,6 +31,11 @@ class MainActivity: FlutterFragmentActivity() { startService(serviceIntent) } } + "stopService" -> { + val serviceIntent = Intent(this@MainActivity, ForegroundService::class.java) + stopService(serviceIntent) + result.success(null) + } else -> { result.notImplemented() } diff --git a/lib/core/channel/bg_run.dart b/lib/core/channel/bg_run.dart index b300ca2a5..05e237463 100644 --- a/lib/core/channel/bg_run.dart +++ b/lib/core/channel/bg_run.dart @@ -11,4 +11,8 @@ abstract final class BgRunMC { static void startService() { _channel.invokeMethod('startService'); } + + static void stopService() { + _channel.invokeMethod('stopService'); + } } diff --git a/lib/main.dart b/lib/main.dart index 2e9a3141d..815cf9238 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -9,7 +9,6 @@ import 'package:flutter_displaymode/flutter_displaymode.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:logging/logging.dart'; import 'package:server_box/app.dart'; -import 'package:server_box/core/channel/bg_run.dart'; import 'package:server_box/core/sync.dart'; import 'package:server_box/data/model/app/menu/server_func.dart'; import 'package:server_box/data/model/app/net_view.dart'; @@ -111,10 +110,6 @@ void _doPlatformRelated() async { if (isAndroid) { // try switch to highest refresh rate FlutterDisplayMode.setHighRefreshRate(); - if (Stores.setting.bgRun.fetch()) { - Loggers.app.info('Start foreground service'); - BgRunMC.startService(); - } } final serversCount = Stores.server.box.keys.length; diff --git a/lib/view/page/ssh/page.dart b/lib/view/page/ssh/page.dart index 1beb730e9..7d189d5c8 100644 --- a/lib/view/page/ssh/page.dart +++ b/lib/view/page/ssh/page.dart @@ -6,6 +6,7 @@ import 'package:fl_lib/fl_lib.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; +import 'package:server_box/core/channel/bg_run.dart'; import 'package:server_box/core/extension/context/locale.dart'; import 'package:server_box/core/utils/ssh_auth.dart'; import 'package:server_box/core/utils/server.dart'; @@ -70,13 +71,22 @@ class SSHPageState extends State late SSHClient? _client = widget.spi.server?.value.client; Timer? _discontinuityTimer; + /// Used for (de)activate the wake lock and forground service + static var _sshConnCount = 0; + @override void dispose() { super.dispose(); _virtKeyLongPressTimer?.cancel(); _terminalController.dispose(); _discontinuityTimer?.cancel(); - WakelockPlus.disable(); + + if (--_sshConnCount <= 0) { + WakelockPlus.disable(); + if (isAndroid) { + BgRunMC.stopService(); + } + } } @override @@ -85,6 +95,13 @@ class SSHPageState extends State _initStoredCfg(); _initVirtKeys(); _setupDiscontinuityTimer(); + + if (++_sshConnCount == 1) { + WakelockPlus.enable(); + if (isAndroid) { + BgRunMC.startService(); + } + } } @override