update android server notification
This commit is contained in:
		
							parent
							
								
									4ca42faee9
								
							
						
					
					
						commit
						d66939244e
					
				| @ -15,6 +15,7 @@ import androidx.annotation.RequiresApi | |||||||
| import io.flutter.embedding.android.FlutterActivity | import io.flutter.embedding.android.FlutterActivity | ||||||
| import io.flutter.embedding.engine.FlutterEngine | import io.flutter.embedding.engine.FlutterEngine | ||||||
| import io.flutter.plugin.common.MethodChannel | import io.flutter.plugin.common.MethodChannel | ||||||
|  | import java.lang.Exception | ||||||
| 
 | 
 | ||||||
| const val MEDIA_REQUEST_CODE = 42 | const val MEDIA_REQUEST_CODE = 42 | ||||||
| 
 | 
 | ||||||
| @ -97,6 +98,13 @@ class MainActivity : FlutterActivity() { | |||||||
|                             mapOf("name" to "input", "value" to InputService.isOpen.toString()) |                             mapOf("name" to "input", "value" to InputService.isOpen.toString()) | ||||||
|                         ) |                         ) | ||||||
|                     } |                     } | ||||||
|  |                     "cancel_notification" -> { | ||||||
|  |                         try { | ||||||
|  |                             val id = call.arguments as Int | ||||||
|  |                             Log.d(logTag,"cancel_notification id:$id") | ||||||
|  |                             mainService?.cancelNotification(id) | ||||||
|  |                         }finally { } | ||||||
|  |                     } | ||||||
|                     else -> {} |                     else -> {} | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -30,7 +30,8 @@ import androidx.core.app.NotificationCompat | |||||||
| import androidx.core.content.ContextCompat | import androidx.core.content.ContextCompat | ||||||
| import java.util.concurrent.Executors | import java.util.concurrent.Executors | ||||||
| import kotlin.concurrent.thread | import kotlin.concurrent.thread | ||||||
| import androidx.media.app.NotificationCompat.MediaStyle | import org.json.JSONException | ||||||
|  | import org.json.JSONObject | ||||||
| 
 | 
 | ||||||
| const val EXTRA_MP_DATA = "mp_intent" | const val EXTRA_MP_DATA = "mp_intent" | ||||||
| const val INIT_SERVICE = "init_service" | const val INIT_SERVICE = "init_service" | ||||||
| @ -38,8 +39,9 @@ const val ACTION_LOGIN_REQ_NOTIFY = "ACTION_LOGIN_REQ_NOTIFY" | |||||||
| const val EXTRA_LOGIN_REQ_NOTIFY = "EXTRA_LOGIN_REQ_NOTIFY" | const val EXTRA_LOGIN_REQ_NOTIFY = "EXTRA_LOGIN_REQ_NOTIFY" | ||||||
| 
 | 
 | ||||||
| const val DEFAULT_NOTIFY_TITLE = "RustDesk" | const val DEFAULT_NOTIFY_TITLE = "RustDesk" | ||||||
| const val DEFAULT_NOTIFY_TEXT = "Service is listening" | const val DEFAULT_NOTIFY_TEXT = "Service is running" | ||||||
| const val NOTIFY_ID = 11 | const val DEFAULT_NOTIFY_ID = 1 | ||||||
|  | const val NOTIFY_ID_OFFSET = 100 // 为每个客户端ID增加这个偏移量,而得到通知栏ID,避免使用0且防止和默认ID冲突 | ||||||
| 
 | 
 | ||||||
| const val NOTIFY_TYPE_START_CAPTURE = "NOTIFY_TYPE_START_CAPTURE" | const val NOTIFY_TYPE_START_CAPTURE = "NOTIFY_TYPE_START_CAPTURE" | ||||||
| 
 | 
 | ||||||
| @ -96,17 +98,42 @@ class MainService : Service() { | |||||||
|     fun rustSetByName(name: String, arg1: String, arg2: String) { |     fun rustSetByName(name: String, arg1: String, arg2: String) { | ||||||
|         when (name) { |         when (name) { | ||||||
|             "try_start_without_auth" -> { |             "try_start_without_auth" -> { | ||||||
|                 // TODO notify |                 try { | ||||||
|                 loginRequestActionNotification("test","name","id") |                     val jsonObject = JSONObject(arg1) | ||||||
|             } |                     val id = jsonObject["id"] as Int | ||||||
|             "start_capture" -> { |                     val username = jsonObject["name"] as String | ||||||
|                 Log.d(logTag, "from rust:start_capture") |                     val peerId = jsonObject["peer_id"] as String | ||||||
|                 if (isStart) { |                     val type = if (jsonObject["is_file_transfer"] as Boolean){ | ||||||
|                     Log.d(logTag, "正在录制") |                         translate("File Connection") | ||||||
|                     return |                     }else{ | ||||||
|  |                         translate("Screen Connection") | ||||||
|  |                     } | ||||||
|  |                     loginRequestNotification(id,type,username,peerId) | ||||||
|  |                 }catch (e:JSONException){ | ||||||
|  |                     e.printStackTrace() | ||||||
|                 } |                 } | ||||||
|                 startCapture() |             } | ||||||
|                 // TODO notify |             "on_client_authorized" -> { | ||||||
|  |                 Log.d(logTag, "from rust:on_client_authorized") | ||||||
|  |                 try { | ||||||
|  |                     val jsonObject = JSONObject(arg1) | ||||||
|  |                     val id = jsonObject["id"] as Int | ||||||
|  |                     val username = jsonObject["name"] as String | ||||||
|  |                     val peerId = jsonObject["peer_id"] as String | ||||||
|  |                     val isFileTransfer = jsonObject["is_file_transfer"] as Boolean | ||||||
|  |                     val type = if (isFileTransfer){ | ||||||
|  |                         translate("File Connection") | ||||||
|  |                     }else{ | ||||||
|  |                         translate("Screen Connection") | ||||||
|  |                     } | ||||||
|  |                     if(!isFileTransfer && !isStart){ | ||||||
|  |                         startCapture() | ||||||
|  |                     } | ||||||
|  |                     onClientAuthorizedNotification(id,type,username,peerId) | ||||||
|  |                 }catch (e:JSONException){ | ||||||
|  |                     e.printStackTrace() | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|             } |             } | ||||||
|             "stop_capture" -> { |             "stop_capture" -> { | ||||||
|                 Log.d(logTag, "from rust:stop_capture") |                 Log.d(logTag, "from rust:stop_capture") | ||||||
| @ -119,8 +146,14 @@ class MainService : Service() { | |||||||
|     // jvm call rust |     // jvm call rust | ||||||
|     private external fun init(ctx: Context) |     private external fun init(ctx: Context) | ||||||
|     private external fun startServer() |     private external fun startServer() | ||||||
|  |     private external fun translateLocale(localeName:String,input: String) : String | ||||||
|     // private external fun sendVp9(data: ByteArray) |     // private external fun sendVp9(data: ByteArray) | ||||||
| 
 | 
 | ||||||
|  |     private fun translate(input:String):String{ | ||||||
|  |         Log.d(logTag,"translate:$LOCAL_NAME") | ||||||
|  |         return translateLocale(LOCAL_NAME,input) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     private val logTag = "LOG_SERVICE" |     private val logTag = "LOG_SERVICE" | ||||||
|     private val useVP9 = false |     private val useVP9 = false | ||||||
|     private val binder = LocalBinder() |     private val binder = LocalBinder() | ||||||
| @ -498,31 +531,54 @@ class MainService : Service() { | |||||||
|             .setAutoCancel(true) |             .setAutoCancel(true) | ||||||
|             .setPriority(NotificationCompat.PRIORITY_DEFAULT) |             .setPriority(NotificationCompat.PRIORITY_DEFAULT) | ||||||
|             .setContentTitle(DEFAULT_NOTIFY_TITLE) |             .setContentTitle(DEFAULT_NOTIFY_TITLE) | ||||||
|             .setContentText(DEFAULT_NOTIFY_TEXT) |             .setContentText(translate(DEFAULT_NOTIFY_TEXT) + '!') | ||||||
|             .setOnlyAlertOnce(true) |             .setOnlyAlertOnce(true) | ||||||
|             .setContentIntent(pendingIntent) |             .setContentIntent(pendingIntent) | ||||||
|             .setColor(ContextCompat.getColor(this, R.color.primary)) |             .setColor(ContextCompat.getColor(this, R.color.primary)) | ||||||
|             .setWhen(System.currentTimeMillis()) |             .setWhen(System.currentTimeMillis()) | ||||||
|             .build() |             .build() | ||||||
|         // 这里满足前台服务首次启动时5s内设定好通知内容,这里使用startForeground,后续普通调用使用notificationManager即可 |         // 这里满足前台服务首次启动时5s内设定好通知内容,这里使用startForeground,后续普通调用使用notificationManager即可 | ||||||
|         startForeground(NOTIFY_ID, notification) |         startForeground(DEFAULT_NOTIFY_ID, notification) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private fun loginRequestActionNotification(type: String, name: String, id: String) { |     private fun loginRequestNotification(clientID:Int, type: String, username: String, peerId: String) { | ||||||
|         // notificationBuilder 第一次使用时状态已保存,再次生成时只需要调整需要修改的部分 |         // notificationBuilder 第一次使用时状态已保存,再次生成时只需要调整需要修改的部分 | ||||||
|  |         cancelNotification(clientID) | ||||||
|         val notification = notificationBuilder |         val notification = notificationBuilder | ||||||
|  |             .setOngoing(false) | ||||||
|             .setPriority(NotificationCompat.PRIORITY_HIGH) |             .setPriority(NotificationCompat.PRIORITY_HIGH) | ||||||
|             .setContentTitle("收到${type}连接请求") |             .setContentTitle(translate("Do you accept?")) | ||||||
|             .setContentText("来自:$name-$id") |             .setContentText("$type:$username-$peerId") | ||||||
| 
 |             // 暂时不开启通知栏接受请求 | ||||||
|             // 暂时不开启通知栏接受请求,防止用户误操作 |             // .setStyle(MediaStyle().setShowActionsInCompactView(0, 1)) | ||||||
| //            .setStyle(MediaStyle().setShowActionsInCompactView(0, 1)) |             // .addAction(R.drawable.check_blue, "check", genLoginRequestPendingIntent(true)) | ||||||
| //            .addAction(R.drawable.check_blue, "check", genLoginRequestPendingIntent(true)) |             // .addAction(R.drawable.close_red, "close", genLoginRequestPendingIntent(false)) | ||||||
| //            .addAction(R.drawable.close_red, "close", genLoginRequestPendingIntent(false)) |  | ||||||
|             .build() |             .build() | ||||||
|         // TODO 为每个login req定义id ,notify id 不能是0 可以定义为client id + 100,如101,102,103 |         notificationManager.notify(getClientNotifyID(clientID), notification) | ||||||
|         // 登录成功 取消notify时可以直接使用 |     } | ||||||
|         notificationManager.notify(NOTIFY_ID + 1, notification) | 
 | ||||||
|  |     private fun onClientAuthorizedNotification(clientID: Int, type: String, username: String, peerId: String) { | ||||||
|  |         cancelNotification(clientID) | ||||||
|  |         val notification = notificationBuilder | ||||||
|  |             .setOngoing(false) | ||||||
|  |             .setPriority(NotificationCompat.PRIORITY_HIGH) | ||||||
|  |             .setContentTitle("$type ${translate("Established")}") | ||||||
|  |             .setContentText("$username - $peerId") | ||||||
|  |             .build() | ||||||
|  |         notificationManager.notify(getClientNotifyID(clientID), notification) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private fun getClientNotifyID(clientID:Int):Int{ | ||||||
|  |         return clientID + NOTIFY_ID_OFFSET | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 关闭通知的情况 | ||||||
|  |      * 1.UI端接受或拒绝 | ||||||
|  |      * 2.peer端通过密码建立了连接(在onClientAuthorizedNotification中已处理) 和 peer端手动取消了连接 | ||||||
|  |      */ | ||||||
|  |     fun cancelNotification(clientID:Int){ | ||||||
|  |         notificationManager.cancel(getClientNotifyID(clientID)) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private fun genLoginRequestPendingIntent(res: Boolean): PendingIntent { |     private fun genLoginRequestPendingIntent(res: Boolean): PendingIntent { | ||||||
| @ -539,13 +595,13 @@ class MainService : Service() { | |||||||
| 
 | 
 | ||||||
|     private fun setTextNotification(_title: String?, _text: String?) { |     private fun setTextNotification(_title: String?, _text: String?) { | ||||||
|         val title = _title ?: DEFAULT_NOTIFY_TITLE |         val title = _title ?: DEFAULT_NOTIFY_TITLE | ||||||
|         val text = _text ?: DEFAULT_NOTIFY_TEXT |         val text = _text ?: translate(DEFAULT_NOTIFY_TEXT) + '!' | ||||||
|         val notification = notificationBuilder |         val notification = notificationBuilder | ||||||
|             .clearActions() |             .clearActions() | ||||||
|             .setStyle(null) |             .setStyle(null) | ||||||
|             .setContentTitle(title) |             .setContentTitle(title) | ||||||
|             .setContentText(text) |             .setContentText(text) | ||||||
|             .build() |             .build() | ||||||
|         notificationManager.notify(NOTIFY_ID, notification) |         notificationManager.notify(DEFAULT_NOTIFY_ID, notification) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| package com.carriez.flutter_hbb | package com.carriez.flutter_hbb | ||||||
| 
 | 
 | ||||||
|  | import android.annotation.SuppressLint | ||||||
| import android.app.* | import android.app.* | ||||||
| import android.app.PendingIntent.FLAG_UPDATE_CURRENT | import android.app.PendingIntent.FLAG_UPDATE_CURRENT | ||||||
| import android.content.Context | import android.content.Context | ||||||
| @ -13,6 +14,10 @@ import androidx.annotation.RequiresApi | |||||||
| import androidx.core.app.NotificationCompat | import androidx.core.app.NotificationCompat | ||||||
| import com.hjq.permissions.Permission | import com.hjq.permissions.Permission | ||||||
| import com.hjq.permissions.XXPermissions | import com.hjq.permissions.XXPermissions | ||||||
|  | import java.util.* | ||||||
|  | 
 | ||||||
|  | @SuppressLint("ConstantLocale") | ||||||
|  | val LOCAL_NAME = Locale.getDefault().toString() | ||||||
| 
 | 
 | ||||||
| val INFO = Info("", "", 0, 0) | val INFO = Info("", "", 0, 0) | ||||||
| 
 | 
 | ||||||
| @ -85,4 +90,4 @@ fun checkPermissions(context: Context) { | |||||||
|                 Log.d("loglog", "获取存储权限成功:$permissions") |                 Log.d("loglog", "获取存储权限成功:$permissions") | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| } | } | ||||||
|  | |||||||
| @ -849,8 +849,8 @@ class FFI { | |||||||
|     PlatformFFI.setMethodCallHandler(callback); |     PlatformFFI.setMethodCallHandler(callback); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   static Future<bool> invokeMethod(String method) async { |   static Future<bool> invokeMethod(String method,[ dynamic arguments ]) async { | ||||||
|     return await PlatformFFI.invokeMethod(method); |     return await PlatformFFI.invokeMethod(method, arguments); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -123,8 +123,8 @@ class PlatformFFI { | |||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   static invokeMethod(String method) async { |   static invokeMethod(String method,[ dynamic arguments ]) async { | ||||||
|     return await toAndroidChannel.invokeMethod(method); |     return await toAndroidChannel.invokeMethod(method,arguments); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -81,7 +81,12 @@ class ServerModel with ChangeNotifier { | |||||||
|   toggleService() async { |   toggleService() async { | ||||||
|     if(_isStart){ |     if(_isStart){ | ||||||
|       final res = await DialogManager.show<bool>((setState, close) => CustomAlertDialog( |       final res = await DialogManager.show<bool>((setState, close) => CustomAlertDialog( | ||||||
|         title: Text(translate("Warning")), |         title: Row(children: [ | ||||||
|  |           Icon(Icons.warning_amber_sharp, | ||||||
|  |               color: Colors.redAccent, size: 28), | ||||||
|  |           SizedBox(width: 10), | ||||||
|  |           Text(translate("Warning")), | ||||||
|  |         ]), | ||||||
|         content: Text(translate("android_stop_service_tip")), |         content: Text(translate("android_stop_service_tip")), | ||||||
|         actions: [ |         actions: [ | ||||||
|           TextButton(onPressed: ()=>close(), child: Text(translate("Cancel"))), |           TextButton(onPressed: ()=>close(), child: Text(translate("Cancel"))), | ||||||
| @ -93,7 +98,12 @@ class ServerModel with ChangeNotifier { | |||||||
|       } |       } | ||||||
|     }else{ |     }else{ | ||||||
|       final res = await DialogManager.show<bool>((setState, close) => CustomAlertDialog( |       final res = await DialogManager.show<bool>((setState, close) => CustomAlertDialog( | ||||||
|         title: Text(translate("Warning")), |         title: Row(children: [ | ||||||
|  |           Icon(Icons.warning_amber_sharp, | ||||||
|  |               color: Colors.redAccent, size: 28), | ||||||
|  |           SizedBox(width: 10), | ||||||
|  |           Text(translate("Warning")), | ||||||
|  |         ]), | ||||||
|         content: Text(translate("android_service_will_start_tip")), |         content: Text(translate("android_service_will_start_tip")), | ||||||
|         actions: [ |         actions: [ | ||||||
|           TextButton(onPressed: ()=>close(), child: Text(translate("Cancel"))), |           TextButton(onPressed: ()=>close(), child: Text(translate("Cancel"))), | ||||||
| @ -208,7 +218,12 @@ class ServerModel with ChangeNotifier { | |||||||
|       final Map<String, dynamic> response = Map(); |       final Map<String, dynamic> response = Map(); | ||||||
|       response["id"] = client.id; |       response["id"] = client.id; | ||||||
|       DialogManager.show((setState, close) => CustomAlertDialog( |       DialogManager.show((setState, close) => CustomAlertDialog( | ||||||
|               title: Text(translate(client.isFileTransfer?"File Connection":"Screen Connection")), |               title: Row( | ||||||
|  |                   mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||||
|  |                   children: [ | ||||||
|  |                 Text(translate(client.isFileTransfer?"File Connection":"Screen Connection")), | ||||||
|  |                 IconButton(onPressed: close, icon: Icon(Icons.close)) | ||||||
|  |               ]), | ||||||
|               content: Column( |               content: Column( | ||||||
|                 mainAxisSize: MainAxisSize.min, |                 mainAxisSize: MainAxisSize.min, | ||||||
|                 mainAxisAlignment: MainAxisAlignment.center, |                 mainAxisAlignment: MainAxisAlignment.center, | ||||||
| @ -226,6 +241,7 @@ class ServerModel with ChangeNotifier { | |||||||
|                     onPressed: () { |                     onPressed: () { | ||||||
|                       response["res"] = false; |                       response["res"] = false; | ||||||
|                       FFI.setByName("login_res", jsonEncode(response)); |                       FFI.setByName("login_res", jsonEncode(response)); | ||||||
|  |                       FFI.invokeMethod("cancel_notification",client.id); | ||||||
|                       close(); |                       close(); | ||||||
|                     }), |                     }), | ||||||
|                 ElevatedButton( |                 ElevatedButton( | ||||||
| @ -234,10 +250,9 @@ class ServerModel with ChangeNotifier { | |||||||
|                       response["res"] = true; |                       response["res"] = true; | ||||||
|                       FFI.setByName("login_res", jsonEncode(response)); |                       FFI.setByName("login_res", jsonEncode(response)); | ||||||
|                       if (!client.isFileTransfer) { |                       if (!client.isFileTransfer) { | ||||||
|                         bool res = await FFI.invokeMethod( |                         FFI.invokeMethod("start_capture"); | ||||||
|                             "start_capture"); // to Android service |  | ||||||
|                         debugPrint("_toAndroidStartCapture:$res"); |  | ||||||
|                       } |                       } | ||||||
|  |                       FFI.invokeMethod("cancel_notification",client.id); | ||||||
|                       _clients[client.id] = client; |                       _clients[client.id] = client; | ||||||
|                       notifyListeners(); |                       notifyListeners(); | ||||||
|                       close(); |                       close(); | ||||||
| @ -251,6 +266,8 @@ class ServerModel with ChangeNotifier { | |||||||
|   void onClientAuthorized(Map<String, dynamic> evt) { |   void onClientAuthorized(Map<String, dynamic> evt) { | ||||||
|     try{ |     try{ | ||||||
|       final client = Client.fromJson(jsonDecode(evt['client'])); |       final client = Client.fromJson(jsonDecode(evt['client'])); | ||||||
|  |       // reset the login dialog, to-do,it will close any showing dialog | ||||||
|  |       DialogManager.reset(); | ||||||
|       _clients[client.id] = client; |       _clients[client.id] = client; | ||||||
|       notifyListeners(); |       notifyListeners(); | ||||||
|     }catch(e){ |     }catch(e){ | ||||||
| @ -266,6 +283,7 @@ class ServerModel with ChangeNotifier { | |||||||
|       }else{ |       }else{ | ||||||
|         // reset the login dialog, to-do,it will close any showing dialog |         // reset the login dialog, to-do,it will close any showing dialog | ||||||
|         DialogManager.reset(); |         DialogManager.reset(); | ||||||
|  |         FFI.invokeMethod("cancel_notification",id); | ||||||
|       } |       } | ||||||
|       notifyListeners(); |       notifyListeners(); | ||||||
|     } catch (e) { |     } catch (e) { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user