file cancel job; update android
This commit is contained in:
parent
7957efee5e
commit
4ca42faee9
@ -30,11 +30,11 @@ class MainActivity : FlutterActivity() {
|
|||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.M)
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
||||||
|
super.configureFlutterEngine(flutterEngine)
|
||||||
Log.d(logTag, "MainActivity configureFlutterEngine,bind to main service")
|
Log.d(logTag, "MainActivity configureFlutterEngine,bind to main service")
|
||||||
Intent(this, MainService::class.java).also {
|
Intent(this, MainService::class.java).also {
|
||||||
bindService(it, serviceConnection, Context.BIND_AUTO_CREATE)
|
bindService(it, serviceConnection, Context.BIND_AUTO_CREATE)
|
||||||
}
|
}
|
||||||
super.configureFlutterEngine(flutterEngine) // 必要 否则无法正确初始化flutter
|
|
||||||
checkPermissions(this)
|
checkPermissions(this)
|
||||||
updateMachineInfo()
|
updateMachineInfo()
|
||||||
flutterMethodChannel = MethodChannel(
|
flutterMethodChannel = MethodChannel(
|
||||||
@ -180,7 +180,6 @@ class MainActivity : FlutterActivity() {
|
|||||||
w /= scale
|
w /= scale
|
||||||
h /= scale
|
h /= scale
|
||||||
}
|
}
|
||||||
Log.d(logTag, "Real size - width:$w,height:$h")
|
|
||||||
|
|
||||||
INFO.screenWidth = w
|
INFO.screenWidth = w
|
||||||
INFO.screenHeight = h
|
INFO.screenHeight = h
|
||||||
@ -188,6 +187,7 @@ class MainActivity : FlutterActivity() {
|
|||||||
INFO.username = "test"
|
INFO.username = "test"
|
||||||
INFO.hostname = "hostname"
|
INFO.hostname = "hostname"
|
||||||
// TODO username hostname
|
// TODO username hostname
|
||||||
|
Log.d(logTag, "INIT INFO:$INFO")
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Log.e(logTag, "Got Screen Size Fail!")
|
Log.e(logTag, "Got Screen Size Fail!")
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* video_service and audio_service
|
* Capture screen,get video and audio,send to rust.
|
||||||
|
* Handle notification
|
||||||
*/
|
*/
|
||||||
package com.carriez.flutter_hbb
|
package com.carriez.flutter_hbb
|
||||||
|
|
||||||
@ -96,7 +97,7 @@ class MainService : Service() {
|
|||||||
when (name) {
|
when (name) {
|
||||||
"try_start_without_auth" -> {
|
"try_start_without_auth" -> {
|
||||||
// TODO notify
|
// TODO notify
|
||||||
|
loginRequestActionNotification("test","name","id")
|
||||||
}
|
}
|
||||||
"start_capture" -> {
|
"start_capture" -> {
|
||||||
Log.d(logTag, "from rust:start_capture")
|
Log.d(logTag, "from rust:start_capture")
|
||||||
@ -118,8 +119,7 @@ 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 ready()
|
// private external fun sendVp9(data: ByteArray)
|
||||||
private external fun sendVp9(data: ByteArray)
|
|
||||||
|
|
||||||
private val logTag = "LOG_SERVICE"
|
private val logTag = "LOG_SERVICE"
|
||||||
private val useVP9 = false
|
private val useVP9 = false
|
||||||
@ -157,7 +157,7 @@ class MainService : Service() {
|
|||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
initNotification()
|
initNotification()
|
||||||
startServer() // 开启了rust服务但是没有设置可以接收连接 如果不开启 首次启动没法获得服务ID
|
startServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBind(intent: Intent): IBinder {
|
override fun onBind(intent: Intent): IBinder {
|
||||||
@ -188,15 +188,14 @@ class MainService : Service() {
|
|||||||
checkMediaPermission()
|
checkMediaPermission()
|
||||||
surface = createSurface()
|
surface = createSurface()
|
||||||
init(this)
|
init(this)
|
||||||
ready()
|
|
||||||
_isReady = true
|
_isReady = true
|
||||||
} ?: let {
|
} ?: let {
|
||||||
Log.d(logTag, "获取mMediaProjection失败!")
|
Log.d(logTag, "获取mMediaProjection失败!")
|
||||||
}
|
}
|
||||||
} else if (intent?.action == ACTION_LOGIN_REQ_NOTIFY) {
|
// } else if (intent?.action == ACTION_LOGIN_REQ_NOTIFY) {
|
||||||
// TODO notify 重新适配多连接的情况
|
// 暂时不开启通知从通知栏确认登录
|
||||||
val notifyLoginRes = intent.getBooleanExtra(EXTRA_LOGIN_REQ_NOTIFY, false)
|
// val notifyLoginRes = intent.getBooleanExtra(EXTRA_LOGIN_REQ_NOTIFY, false)
|
||||||
Log.d(logTag, "从通知栏点击了:$notifyLoginRes")
|
// Log.d(logTag, "从通知栏点击了:$notifyLoginRes")
|
||||||
}
|
}
|
||||||
return super.onStartCommand(intent, flags, startId)
|
return super.onStartCommand(intent, flags, startId)
|
||||||
}
|
}
|
||||||
@ -208,6 +207,7 @@ class MainService : Service() {
|
|||||||
// TODO
|
// TODO
|
||||||
null
|
null
|
||||||
} else {
|
} else {
|
||||||
|
Log.d(logTag,"ImageReader.newInstance:INFO:$INFO")
|
||||||
imageReader =
|
imageReader =
|
||||||
ImageReader.newInstance(
|
ImageReader.newInstance(
|
||||||
INFO.screenWidth,
|
INFO.screenWidth,
|
||||||
@ -361,7 +361,7 @@ class MainService : Service() {
|
|||||||
// TODO 优化内存使用方式
|
// TODO 优化内存使用方式
|
||||||
val byteArray = ByteArray(buf.limit())
|
val byteArray = ByteArray(buf.limit())
|
||||||
buf.get(byteArray)
|
buf.get(byteArray)
|
||||||
sendVp9(byteArray)
|
// sendVp9(byteArray)
|
||||||
codec.releaseOutputBuffer(index, false)
|
codec.releaseOutputBuffer(index, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -466,7 +466,7 @@ class MainService : Service() {
|
|||||||
val channelName = "RustDesk Service"
|
val channelName = "RustDesk Service"
|
||||||
val channel = NotificationChannel(
|
val channel = NotificationChannel(
|
||||||
channelId,
|
channelId,
|
||||||
channelName, NotificationManager.IMPORTANCE_DEFAULT
|
channelName, NotificationManager.IMPORTANCE_HIGH
|
||||||
).apply {
|
).apply {
|
||||||
description = "RustDesk Service Channel"
|
description = "RustDesk Service Channel"
|
||||||
}
|
}
|
||||||
@ -494,6 +494,8 @@ class MainService : Service() {
|
|||||||
val notification = notificationBuilder
|
val notification = notificationBuilder
|
||||||
.setOngoing(true)
|
.setOngoing(true)
|
||||||
.setSmallIcon(R.mipmap.ic_launcher)
|
.setSmallIcon(R.mipmap.ic_launcher)
|
||||||
|
.setDefaults(Notification.DEFAULT_ALL)
|
||||||
|
.setAutoCancel(true)
|
||||||
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
|
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
|
||||||
.setContentTitle(DEFAULT_NOTIFY_TITLE)
|
.setContentTitle(DEFAULT_NOTIFY_TITLE)
|
||||||
.setContentText(DEFAULT_NOTIFY_TEXT)
|
.setContentText(DEFAULT_NOTIFY_TEXT)
|
||||||
@ -502,18 +504,25 @@ class MainService : Service() {
|
|||||||
.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即可
|
||||||
startForeground(NOTIFY_ID, notification)
|
startForeground(NOTIFY_ID, notification)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loginRequestActionNotification(type: String, name: String, id: String) {
|
private fun loginRequestActionNotification(type: String, name: String, id: String) {
|
||||||
|
// notificationBuilder 第一次使用时状态已保存,再次生成时只需要调整需要修改的部分
|
||||||
val notification = notificationBuilder
|
val notification = notificationBuilder
|
||||||
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||||
.setContentTitle("收到${type}连接请求")
|
.setContentTitle("收到${type}连接请求")
|
||||||
.setContentText("来自:$name-$id 是否接受")
|
.setContentText("来自:$name-$id")
|
||||||
.setStyle(MediaStyle().setShowActionsInCompactView(0, 1))
|
|
||||||
.addAction(R.drawable.check_blue, "check", genLoginRequestPendingIntent(true))
|
// 暂时不开启通知栏接受请求,防止用户误操作
|
||||||
.addAction(R.drawable.close_red, "close", genLoginRequestPendingIntent(false))
|
// .setStyle(MediaStyle().setShowActionsInCompactView(0, 1))
|
||||||
|
// .addAction(R.drawable.check_blue, "check", genLoginRequestPendingIntent(true))
|
||||||
|
// .addAction(R.drawable.close_red, "close", genLoginRequestPendingIntent(false))
|
||||||
.build()
|
.build()
|
||||||
notificationManager.notify(NOTIFY_ID, notification)
|
// TODO 为每个login req定义id ,notify id 不能是0 可以定义为client id + 100,如101,102,103
|
||||||
|
// 登录成功 取消notify时可以直接使用
|
||||||
|
notificationManager.notify(NOTIFY_ID + 1, notification)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun genLoginRequestPendingIntent(res: Boolean): PendingIntent {
|
private fun genLoginRequestPendingIntent(res: Boolean): PendingIntent {
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
# RustDesk 安卓端被控文档记录
|
# RustDesk 安卓端被控文档记录
|
||||||
|
|
||||||
|
### 开发环境注意
|
||||||
|
|
||||||
|
- AS IDE Android 启动service时的闪退问题,开发安卓使用到service时,在Android IDE模式下用AS重新启动app前,如果已启动Service,需要确保已开启的app已经完全关闭,否则可能会出现下次启动service时闪退的怪问题。
|
||||||
|
- 如果IDE时Flutter模式无此问题,flutter模式每次编译开启app的时间较长,推测flutter每次编译会重新安装一次apk包,而Android有热编译机制,启动Service时候,可能会带来闪退bug。
|
||||||
|
|
||||||
### 1.获取屏幕录像
|
### 1.获取屏幕录像
|
||||||
|
|
||||||
##### 原理 流程
|
##### 原理 流程
|
||||||
@ -31,7 +36,7 @@ MediaProjectionManager -> MediaProjection
|
|||||||
- **注意**:安卓捕获到的数据是RGBA格式,暂无BRGA的输出,在rust端需要调用libyuv中相应的rgbatoi420方法
|
- **注意**:安卓捕获到的数据是RGBA格式,暂无BRGA的输出,在rust端需要调用libyuv中相应的rgbatoi420方法
|
||||||
- 捕获到的数据存入一个bytearray,等待rust端调用获取
|
- 捕获到的数据存入一个bytearray,等待rust端调用获取
|
||||||
|
|
||||||
#####方案B 捕获原始数据传入rust进行编码 !等待完善!
|
#####方案B 使用内置vp9编码器直接获取编码后的数据 传入rust进行编码 !暂不启用,等待完善!
|
||||||
- **自带的编码器无法直接控制流量,默认情况输出的帧率比较高,会造成网络堵塞延迟**
|
- **自带的编码器无法直接控制流量,默认情况输出的帧率比较高,会造成网络堵塞延迟**
|
||||||
- 获取编码后的buf
|
- 获取编码后的buf
|
||||||
- 通过MediaCodec回调获取到可用的数据
|
- 通过MediaCodec回调获取到可用的数据
|
||||||
@ -241,19 +246,13 @@ Config::set_option("stop_service","Y")
|
|||||||
Config::set_option("stop_service","")
|
Config::set_option("stop_service","")
|
||||||
|
|
||||||
|
|
||||||
### TODO
|
|
||||||
完善CM 当前连接的状态 控制音频和输入等开关 断开连接等功能
|
|
||||||
横屏模式
|
|
||||||
首次登录不显示id密码
|
|
||||||
安卓前后分离的问题 通过IPC或者广播解耦
|
|
||||||
|
|
||||||
### 关于安卓的service和进程
|
### 关于安卓的service和进程
|
||||||
实际测试 安卓7和安卓11表现不同 同一个apk下若有多个activity或service
|
实际测试 安卓7和安卓11表现不同 同一个apk下若有多个activity或service
|
||||||
安卓7 关闭activity后所有的服务都会强制关闭 可能是锤子手机特有
|
安卓7 关闭activity后所有的服务都会强制关闭 可能是部分安卓厂商ROM手机特有
|
||||||
|
|
||||||
安卓8.1 和7类似 且安卓8.1和7录屏权限比较宽松 只需要获取一次 不需要每次播放都要获取录屏权限
|
安卓8.1 和7类似 且安卓8.1和7录屏权限比较宽松 只需要获取一次 不需要每次播放都要获取录屏权限
|
||||||
|
|
||||||
*安卓7/8.1关闭activity 后就关闭service 可能是锤子OS的特质
|
*安卓7/8.1关闭activity 后就关闭service 可能是部分安卓厂商ROM手机特有
|
||||||
|
|
||||||
理论上 非bind启动的service可以脱离activity运行 就像三星安卓11上测试的情况
|
理论上 非bind启动的service可以脱离activity运行 就像三星安卓11上测试的情况
|
||||||
|
|
||||||
@ -291,6 +290,14 @@ https://developer.android.com/about/versions/oreo/background?hl=zh-cn#services
|
|||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
|
### 安卓通知
|
||||||
|
- 注册前台服务startForegroundService 首次注册需要在5s内正确设置前台服务的通知栏显示内容。
|
||||||
|
- MainService初始化时注册一个notificationManager,后续除了上条“前台服务依赖的通知内容”外的正常通知,都可以使用notificationManager来激活。
|
||||||
|
- notificationManager.notify(id,notification) 用于普通的激活通知,注意 第一个id如果存在是更新之前的通知,更新通知不会有震动提示,如需新通知也发出震动提示用另一个id。
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
|
||||||
### 开机自启动
|
### 开机自启动
|
||||||
利用接收RECEIVE_BOOT_COMPLETED的系统广播
|
利用接收RECEIVE_BOOT_COMPLETED的系统广播
|
||||||
- 权限:
|
- 权限:
|
||||||
|
@ -328,6 +328,7 @@ class FileModel extends ChangeNotifier {
|
|||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
_selectMode = false;
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,7 +408,9 @@ class FileModel extends ChangeNotifier {
|
|||||||
FFI.setByName("create_dir", jsonEncode(msg));
|
FFI.setByName("create_dir", jsonEncode(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
cancelJob(int id) {}
|
cancelJob(int id) {
|
||||||
|
FFI.setByName("cancel_job",id.toString());
|
||||||
|
}
|
||||||
|
|
||||||
changeSortStyle(SortBy sort) {
|
changeSortStyle(SortBy sort) {
|
||||||
_sortStyle = sort;
|
_sortStyle = sort;
|
||||||
|
@ -261,11 +261,14 @@ class ServerModel with ChangeNotifier {
|
|||||||
void onClientRemove(Map<String, dynamic> evt) {
|
void onClientRemove(Map<String, dynamic> evt) {
|
||||||
try {
|
try {
|
||||||
final id = int.parse(evt['id'] as String);
|
final id = int.parse(evt['id'] as String);
|
||||||
_clients.remove(id);
|
if(_clients.containsKey(id)){
|
||||||
|
_clients.remove(id);
|
||||||
|
}else{
|
||||||
|
// reset the login dialog, to-do,it will close any showing dialog
|
||||||
|
DialogManager.reset();
|
||||||
|
}
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// singleWhere fail ,reset the login dialog
|
|
||||||
DialogManager.reset();
|
|
||||||
debugPrint("onClientRemove failed,error:$e");
|
debugPrint("onClientRemove failed,error:$e");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -333,15 +333,6 @@ class _FileManagerPageState extends State<FileManagerPage> {
|
|||||||
],
|
],
|
||||||
));
|
));
|
||||||
|
|
||||||
Widget emptyPage() {
|
|
||||||
return Column(
|
|
||||||
children: [
|
|
||||||
headTools(),
|
|
||||||
Expanded(child: Center(child: Text("Empty Directory")))
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget listTail() {
|
Widget listTail() {
|
||||||
return Container(
|
return Container(
|
||||||
height: 100,
|
height: 100,
|
||||||
@ -411,7 +402,7 @@ class _FileManagerPageState extends State<FileManagerPage> {
|
|||||||
title: translate("Waiting"),
|
title: translate("Waiting"),
|
||||||
text:
|
text:
|
||||||
"${translate("Speed")}: ${readableFileSize(model.jobProgress.speed)}/s",
|
"${translate("Speed")}: ${readableFileSize(model.jobProgress.speed)}/s",
|
||||||
onCanceled: null,
|
onCanceled: model.cancelJob(model.jobProgress.id),
|
||||||
);
|
);
|
||||||
case JobState.done:
|
case JobState.done:
|
||||||
return BottomSheetBody(
|
return BottomSheetBody(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user