From 2789674a2d7b4a56d5e972c417a05c4fd9277dce Mon Sep 17 00:00:00 2001 From: cxf <2417125293@qq.com> Date: Sat, 25 Apr 2026 15:36:59 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=91=E5=8F=B0=E5=81=8F?= =?UTF-8?q?=E8=88=AA=E5=90=91=E4=B8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 6 +- .../aros/apron/activity/ConnectionActivity.kt | 4 +- .../com/aros/apron/activity/MainActivity.kt | 228 +- .../java/com/aros/apron/base/BaseManager.java | 5 + .../com/aros/apron/callback/MqttCallBack.java | 109 +- .../java/com/aros/apron/entity/Movement.java | 26 +- .../aros/apron/entity/Synchronizedstatus.java | 39 + .../manager/AlternateLandingManager.java | 1 + .../com/aros/apron/manager/CameraManager.java | 2224 +++++++++-------- .../aros/apron/manager/DockCloseManager.java | 14 + .../com/aros/apron/manager/FlightManager.java | 108 +- .../manager/FlightTaskProgressManager.java | 7 +- .../com/aros/apron/manager/GimbalManager.java | 44 +- .../com/aros/apron/manager/MediaManager.java | 52 +- .../aros/apron/manager/MissionV3Manager.java | 216 +- .../apron/manager/PayloadWidgetManager.java | 12 +- .../apron/manager/PayloadlightManager.java | 295 +++ .../aros/apron/manager/PerceptionManager.java | 22 +- .../aros/apron/manager/SpeakerManager.java | 52 +- .../com/aros/apron/manager/StickManager.java | 132 +- .../com/aros/apron/manager/StreamManager.java | 251 +- .../apron/manager/TakeOffToPointManager.java | 1 + .../java/com/aros/apron/mix/Aprondown.java | 2 +- .../java/com/aros/apron/mix/Aprongim.java | 6 +- .../aros/apron/tools/ApronArucoDetect.java | 62 +- .../apron/tools/ApronArucoDetectPort.java | 62 +- .../com/aros/apron/tools/DroneHelper.java | 33 +- .../com/aros/apron/tools/PreferenceUtils.java | 10 + .../aros/apron/tools/SimplePortScanner.java | 84 +- .../main/res/layout-land/activity_main.xml | 13 +- app/src/main/res/layout/activity_main.xml | 12 +- 31 files changed, 2653 insertions(+), 1479 deletions(-) create mode 100644 app/src/main/java/com/aros/apron/manager/PayloadlightManager.java diff --git a/app/build.gradle b/app/build.gradle index 06576545..f16d44e6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -193,9 +193,9 @@ dependencies { implementation 'com.commonsware.cwac:saferoom.x:1.3.0' - implementation 'com.dji:dji-sdk-v5-aircraft:5.17.0' - compileOnly 'com.dji:dji-sdk-v5-aircraft-provided:5.17.0' - implementation 'com.dji:dji-sdk-v5-networkImp:5.17.0' + implementation 'com.dji:dji-sdk-v5-aircraft:5.16.0' + compileOnly 'com.dji:dji-sdk-v5-aircraft-provided:5.16.0' + implementation 'com.dji:dji-sdk-v5-networkImp:5.16.0' // implementation 'com.shd:dji-uxsdk:5.9.1' diff --git a/app/src/main/java/com/aros/apron/activity/ConnectionActivity.kt b/app/src/main/java/com/aros/apron/activity/ConnectionActivity.kt index f413dbfd..00a9f4fb 100644 --- a/app/src/main/java/com/aros/apron/activity/ConnectionActivity.kt +++ b/app/src/main/java/com/aros/apron/activity/ConnectionActivity.kt @@ -90,8 +90,8 @@ open class ConnectionActivity : BaseActivity() { } if (TextUtils.isEmpty(PreferenceUtils.getInstance().mqttServerUri)){ PreferenceUtils.getInstance().mqttServerUri = - //"tcp://192.168.20.90:2883" - "tcp://broker.emqx.io" + "tcp://192.168.20.90:2883" + // "tcp://broker.emqx.io" } if (TextUtils.isEmpty(PreferenceUtils.getInstance().mqttUserName)){ diff --git a/app/src/main/java/com/aros/apron/activity/MainActivity.kt b/app/src/main/java/com/aros/apron/activity/MainActivity.kt index d65b5471..b71585ba 100644 --- a/app/src/main/java/com/aros/apron/activity/MainActivity.kt +++ b/app/src/main/java/com/aros/apron/activity/MainActivity.kt @@ -38,12 +38,10 @@ import com.aros.apron.manager.MissionV3Manager import com.aros.apron.manager.NavigationSatelliteSystemManager import com.aros.apron.manager.OSDManager import com.aros.apron.manager.PayloadWidgetManager -import com.aros.apron.manager.PerceptionManager import com.aros.apron.manager.RTKManager import com.aros.apron.manager.SpeakerManager import com.aros.apron.manager.StickManager import com.aros.apron.manager.StreamManager -import com.aros.apron.manager.UdpStreamManager import com.aros.apron.manager.WirelessLinkManager import com.aros.apron.mix.Aprondown import com.aros.apron.mix.Aprongim @@ -51,9 +49,7 @@ import com.aros.apron.tools.AlternateArucoDetect import com.aros.apron.tools.ApronArucoDetect import com.aros.apron.tools.ApronArucoDetectPort import com.aros.apron.tools.DroneHelper -import com.aros.apron.tools.DualCaptureHelper import com.aros.apron.tools.LogUtil -import com.aros.apron.tools.MixedVisionLanding import com.aros.apron.tools.MqttManager import com.aros.apron.tools.PreferenceUtils import com.aros.apron.tools.SimplePortScanner @@ -63,6 +59,7 @@ import dji.sdk.keyvalue.key.CameraKey import dji.sdk.keyvalue.key.DJIKey import dji.sdk.keyvalue.key.FlightControllerKey import dji.sdk.keyvalue.key.KeyTools +import dji.sdk.keyvalue.value.camera.CameraMode import dji.sdk.keyvalue.value.common.CameraLensType import dji.sdk.keyvalue.value.common.ComponentIndexType import dji.sdk.keyvalue.value.common.EmptyMsg @@ -73,11 +70,9 @@ import dji.v5.common.callback.CommonCallbacks.CompletionCallback import dji.v5.common.error.IDJIError import dji.v5.common.utils.GeoidManager import dji.v5.manager.KeyManager -import dji.v5.manager.aircraft.perception.radar.RadarManager import dji.v5.manager.datacenter.MediaDataCenter import dji.v5.manager.interfaces.ICameraStreamManager import dji.v5.manager.interfaces.ICameraStreamManager.AvailableCameraUpdatedListener -import dji.v5.manager.interfaces.IRadarManager import dji.v5.network.DJINetworkManager import dji.v5.network.IDJINetworkStatusListener import dji.v5.utils.common.JsonUtil @@ -533,7 +528,6 @@ open class MainActivity : BaseActivity() { } - private fun initView() { fpvParentView = findViewById(R.id.fpv_holder) mDrawerLayout = findViewById(R.id.root_view) @@ -560,23 +554,51 @@ open class MainActivity : BaseActivity() { btn_test = findViewById(R.id.btn_test) btn_test1 = findViewById(R.id.btn_test1) btn_test2 = findViewById(R.id.btn_test2) - btn_test3 = findViewById(R.id.btn_test3) +// btn_test3 = findViewById(R.id.btn_test3) btn_test?.setOnClickListener { - DualCaptureHelper.getInstance().captureNextFrame() + // if(cameraMode == 3){ +// //退出回放模式 +// MediaManager.getInstance().disablePlayback(); +// } + KeyManager.getInstance().setValue( + KeyTools.createKey(CameraKey.KeyCameraMode, ComponentIndexType.PORT_1), + CameraMode.find(12), + object : CompletionCallback { + override fun onSuccess() { + OSDManager.getInstance().pushFlightAttitude() + } + + override fun onFailure(error: IDJIError) { + + } + }) } btn_test1?.setOnClickListener { - SimplePortScanner.getInstance().stopScan() + KeyManager.getInstance().performAction( + KeyTools.createKey( + CameraKey.KeyStartShootPhoto, + ComponentIndexType.PORT_1 + ), + object : CommonCallbacks.CompletionCallbackWithParam { + override fun onSuccess(emptyMsg: EmptyMsg?) { + LogUtil.log(TAG, "拍照成功") + } + + override fun onFailure(error: IDJIError) { + LogUtil.log(TAG, "拍照失败:" + Gson().toJson(error)) + } + }) } btn_test2?.setOnClickListener { - StreamManager.getInstance().stopstream() - - } - btn_test3?.setOnClickListener { - StreamManager.getInstance().startstream() + StickManager.getInstance().enableVirtualStick1() } +// btn_test3?.setOnClickListener { +// StreamManager.getInstance().startstream() +// +// } initClickListener() @@ -711,35 +733,12 @@ open class MainActivity : BaseActivity() { startVtxHeartbeat() SpeakerManager.getInstance().initMegaphoneInfo() + + + //GimbalManager.getInstance().gimsetmode() //PayloadWidgetManager.getInstance().initPayloadInfo(); - MediaDataCenter.getInstance().cameraStreamManager.setVisionAssistViewDirection( - VisionAssistDirection.DOWN, object : CommonCallbacks.CompletionCallback { - override fun onSuccess() { - LogUtil.log(TAG, "开启成功") - } - override fun onFailure(p0: IDJIError) { - LogUtil.log(TAG, "开启失败" + p0) - } - }) - - val leDsSettings = LEDsSettings() - leDsSettings.setNavigationLEDsOn(false) - leDsSettings.setStatusIndicatorLEDsOn(true) - leDsSettings.setFrontLEDsOn(true) - KeyManager.getInstance().setValue( - KeyTools.createKey(FlightControllerKey.KeyLEDsSettings), - leDsSettings, - object : CompletionCallback { - override fun onSuccess() { - LogUtil.log(TAG, "夜航灯关闭成功") - } - - override fun onFailure(idjiError: IDJIError) { - LogUtil.log(TAG, "夜航灯关闭失败") - } - }) LogUtil.log(TAG, "自定义推流方式:" + PreferenceUtils.getInstance().customStreamType) @@ -751,25 +750,14 @@ open class MainActivity : BaseActivity() { 2 -> StreamManager.getInstance().startLiveWithCustom() else -> StreamManager.getInstance().startLiveWithCustom() } - val scanner = SimplePortScanner.getInstance() - scanner.setOnPortCheckListener(object : SimplePortScanner.OnPortCheckListener { - override fun onPortOpen() { - //LogUtil.log("qwq","✅ 本地8554端口已开启(每3秒扫描)") - } - - override fun onPortClosed() { - LogUtil.log("qwq", "❌ 本地8554端口已关闭(每3秒扫描)") - //重新开启这个rtp - StreamManager.getInstance().startLiveWithRTSP(); - } - }) + SimplePortScanner.getInstance().startScan() }, 5000) // 参数别改:5秒延迟确保相机就绪 LogUtil.log(TAG, "推流类型:" + PreferenceUtils.getInstance().customStreamType) } - } else if (PreferenceUtils.getInstance().cameraLocationType == 4||PreferenceUtils.getInstance().cameraLocationType == 5) { + } else if (PreferenceUtils.getInstance().cameraLocationType == 4 || PreferenceUtils.getInstance().cameraLocationType == 5) { if ((isFlightControllerConnect == null || isFlightControllerConnect != true) && (isCameraConnect == null || isCameraConnect != true)) { handler.postDelayed({ initDJIManager() @@ -811,60 +799,22 @@ open class MainActivity : BaseActivity() { GeoidManager.getInstance().init(this); + + //GimbalManager.getInstance().gimsetmode() //开启雷达监听器 //PerceptionManager.getInstance().isladraopeninti() - MediaDataCenter.getInstance().cameraStreamManager.setVisionAssistViewDirection( - VisionAssistDirection.DOWN, object : CommonCallbacks.CompletionCallback { - override fun onSuccess() { - LogUtil.log(TAG, "开启成功") - } - - override fun onFailure(p0: IDJIError) { - LogUtil.log(TAG, "开启失败" + p0) - } - }) - - val leDsSettings = LEDsSettings() - leDsSettings.setNavigationLEDsOn(false) - leDsSettings.setStatusIndicatorLEDsOn(true) - leDsSettings.setFrontLEDsOn(true) - KeyManager.getInstance().setValue( - KeyTools.createKey(FlightControllerKey.KeyLEDsSettings), - leDsSettings, - object : CompletionCallback { - override fun onSuccess() { - LogUtil.log(TAG, "夜航灯关闭成功") - } - - override fun onFailure(idjiError: IDJIError) { - LogUtil.log(TAG, "夜航灯关闭失败") - } - }) - LogUtil.log(TAG, "自定义推流方式:" + PreferenceUtils.getInstance().customStreamType) - Handler(Looper.getMainLooper()).postDelayed({ when (PreferenceUtils.getInstance().customStreamType) { 1 -> StreamManager.getInstance().startLiveWithRTSP() 2 -> StreamManager.getInstance().startLiveWithCustom() else -> StreamManager.getInstance().startLiveWithCustom() } - val scanner = SimplePortScanner.getInstance() - scanner.setOnPortCheckListener(object : SimplePortScanner.OnPortCheckListener { - override fun onPortOpen() { - //LogUtil.log("qwq","✅ 本地8554端口已开启(每3秒扫描)") - } - - override fun onPortClosed() { - LogUtil.log("qwq", "❌ 本地8554端口已关闭(每3秒扫描)") - //重新开启这个rtp - StreamManager.getInstance().startLiveWithRTSP(); - } - }) + SimplePortScanner.getInstance().startScan() }, 5000) // 参数别改:5秒延迟确保相机就绪 @@ -913,6 +863,7 @@ open class MainActivity : BaseActivity() { // SpeakerManager.getInstance().initMegaphoneInfo() + //GimbalManager.getInstance().gimsetmode() GeoidManager.getInstance().init(this); @@ -920,34 +871,6 @@ open class MainActivity : BaseActivity() { //PerceptionManager.getInstance().isladraopeninti() - MediaDataCenter.getInstance().cameraStreamManager.setVisionAssistViewDirection( - VisionAssistDirection.DOWN, object : CommonCallbacks.CompletionCallback { - override fun onSuccess() { - LogUtil.log(TAG, "开启成功") - } - - override fun onFailure(p0: IDJIError) { - LogUtil.log(TAG, "开启失败" + p0) - } - }) - - val leDsSettings = LEDsSettings() - leDsSettings.setNavigationLEDsOn(false) - leDsSettings.setStatusIndicatorLEDsOn(true) - leDsSettings.setFrontLEDsOn(true) - KeyManager.getInstance().setValue( - KeyTools.createKey(FlightControllerKey.KeyLEDsSettings), - leDsSettings, - object : CompletionCallback { - override fun onSuccess() { - LogUtil.log(TAG, "夜航灯关闭成功") - } - - override fun onFailure(idjiError: IDJIError) { - LogUtil.log(TAG, "夜航灯关闭失败") - } - }) - LogUtil.log(TAG, "自定义推流方式:" + PreferenceUtils.getInstance().customStreamType) @@ -958,18 +881,7 @@ open class MainActivity : BaseActivity() { 2 -> StreamManager.getInstance().startLiveWithCustom() else -> StreamManager.getInstance().startLiveWithCustom() } - val scanner = SimplePortScanner.getInstance() - scanner.setOnPortCheckListener(object : SimplePortScanner.OnPortCheckListener { - override fun onPortOpen() { - //LogUtil.log("qwq","✅ 本地8554端口已开启(每3秒扫描)") - } - - override fun onPortClosed() { - LogUtil.log("qwq", "❌ 本地8554端口已关闭(每3秒扫描)") - //重新开启这个rtp - StreamManager.getInstance().startLiveWithRTSP(); - } - }) + SimplePortScanner.getInstance().startScan() }, 5000) // 参数别改:5秒延迟确保相机就绪 @@ -1163,7 +1075,44 @@ open class MainActivity : BaseActivity() { @Subscribe(threadMode = ThreadMode.MAIN) fun onEvent(message: String?) { when (message) { - FLAG_START_DETECT_ARUCO_APRON -> + FLAG_START_DETECT_ARUCO_APRON -> { + + + MediaDataCenter.getInstance().getCameraStreamManager().setVisionAssistViewDirection( + VisionAssistDirection.DOWN, + object : CompletionCallback { + override fun onSuccess() { + LogUtil.log(TAG, "下视开启成功") + } + + override fun onFailure(idjiError: IDJIError) { + LogUtil.log(TAG, "下视开启失败") + } + }) + + val leDsSettings = LEDsSettings() + leDsSettings.setNavigationLEDsOn(false) + leDsSettings.setStatusIndicatorLEDsOn(true) + leDsSettings.setFrontLEDsOn(true) + KeyManager.getInstance().setValue( + KeyTools.createKey(FlightControllerKey.KeyLEDsSettings), + leDsSettings, + object : CompletionCallback { + override fun onSuccess() { + LogUtil.log(TAG, "夜航灯关闭成功") + } + + override fun onFailure(idjiError: IDJIError) { + LogUtil.log(TAG, "夜航灯关闭失败") + } + }) + + + + + + + KeyManager.getInstance().performAction( KeyTools.createKey(FlightControllerKey.KeyStopAutoLanding), object : CommonCallbacks.CompletionCallbackWithParam { @@ -1177,7 +1126,7 @@ open class MainActivity : BaseActivity() { AlternateLandingManager.getInstance().startTaskProcess(null) } }, 6000) - } else if (PreferenceUtils.getInstance().cameraLocationType == 4 ||PreferenceUtils.getInstance().cameraLocationType == 5) { + } else if (PreferenceUtils.getInstance().cameraLocationType == 4 || PreferenceUtils.getInstance().cameraLocationType == 5) { Handler().postDelayed(Runnable { if (!Aprongim.getInstance().isTriggerSuccess) { LogUtil.log(TAG, "图传异常:飞往备降点") @@ -1209,6 +1158,7 @@ open class MainActivity : BaseActivity() { DroneHelper.getInstance().isVirtualStickEnable = false DroneHelper.getInstance().setVerticalModeToVelocity() } + override fun onFailure(error: IDJIError) { if (startArucoType == 1) { return @@ -1227,7 +1177,7 @@ open class MainActivity : BaseActivity() { DroneHelper.getInstance().setVerticalModeToVelocity() } }) - + } FLAG_START_DETECT_ARUCO_ALTERNATE -> KeyManager.getInstance().performAction( KeyTools.createKey(FlightControllerKey.KeyStopAutoLanding), @@ -1242,7 +1192,7 @@ open class MainActivity : BaseActivity() { AlternateLandingManager.getInstance().startTaskProcess(null) } }, 6000) - } else if (PreferenceUtils.getInstance().cameraLocationType == 4|| PreferenceUtils.getInstance().cameraLocationType==5) { + } else if (PreferenceUtils.getInstance().cameraLocationType == 4 || PreferenceUtils.getInstance().cameraLocationType == 5) { Handler().postDelayed(Runnable { if (!Aprongim.getInstance().isTriggerSuccess) { LogUtil.log(TAG, "图传异常:飞往备降点") diff --git a/app/src/main/java/com/aros/apron/base/BaseManager.java b/app/src/main/java/com/aros/apron/base/BaseManager.java index 264e511b..b0ff29be 100644 --- a/app/src/main/java/com/aros/apron/base/BaseManager.java +++ b/app/src/main/java/com/aros/apron/base/BaseManager.java @@ -237,6 +237,11 @@ public abstract class BaseManager { * 上报航线任务进度 */ public void sendFlightTaskProgress2Server() { + + if( Movement.getInstance().getTask_media_count()!=0){ + LogUtil.log(TAG ,"getTask_media_count"+Movement.getInstance().getTask_media_count()); + } + LogUtil.log(TAG ,"QWQsendFlightTaskProgress2Server"); try { if (MqttManager.getInstance().mqttAndroidClient.isConnected()) { // 必须加 final,否则内部类(回调)里访问不了 diff --git a/app/src/main/java/com/aros/apron/callback/MqttCallBack.java b/app/src/main/java/com/aros/apron/callback/MqttCallBack.java index deb1a172..248ef6d6 100644 --- a/app/src/main/java/com/aros/apron/callback/MqttCallBack.java +++ b/app/src/main/java/com/aros/apron/callback/MqttCallBack.java @@ -23,6 +23,7 @@ import com.aros.apron.manager.FlyToPointManager; import com.aros.apron.manager.GimbalManager; import com.aros.apron.manager.MissionV3Manager; import com.aros.apron.manager.OSDManager; +import com.aros.apron.manager.PayloadlightManager; import com.aros.apron.manager.PerceptionManager; import com.aros.apron.manager.SpeakerManager; import com.aros.apron.manager.StickManager; @@ -178,15 +179,25 @@ public class MqttCallBack extends BaseManager implements MqttCallbackExtended { Synchronizedstatus.setInitStatus(true); }); } else if (Synchronizedstatus.getInitStatus()) { - LogUtil.log(TAG, "收到:航线" + jsonString); - //设置modecode - Movement.getInstance().setMode_code(1); - //设置标志为 - Movement.getInstance().setFlightmode(1); + if(!Synchronizedstatus.getFlighttaskExecuteStatus()){ + LogUtil.log(TAG, "收到:航线" + jsonString); + //设置modecode + Movement.getInstance().setMode_code(1); + //设置标志为 + Movement.getInstance().setFlightmode(1); + + //存储最新消息并开始自检 + MissionV3Manager.getInstance().taskExecute(message); + Synchronizedstatus.setIsruning(true); + + + Synchronizedstatus.setFlighttaskExecuteStatus(true); + + }else{ + + sendFailMsg2Server(message,"已经收到航线"); + } - //存储最新消息并开始自检 - MissionV3Manager.getInstance().taskExecute(message); - Synchronizedstatus.setIsruning(true); } } break; @@ -206,16 +217,15 @@ public class MqttCallBack extends BaseManager implements MqttCallbackExtended { if (!Movement.getInstance().isAlternate() && !ApronArucoDetectPort.getInstance().isStartAruco() && !ApronArucoDetect.getInstance().isStartAruco() && !Aprongim.getInstance().isStartAruco() && !Aprondown.getInstance().isStartAruco()) { // if(Movement.getInstance().getElevation()<15){ // -// -// // }else{ // FlightManager.getInstance().startGoHome(message); // } FlightManager.getInstance().startGoHome(message); } else { - sendMsg2Server(message); + sendFailMsg2Server(message,"正在视觉或飞往备降不允许返航"); sendEvent2Server("正在视觉或飞往备降不允许返航", 1); + LogUtil.log(TAG,"正在视觉或飞往备降不允许返航"); } break; case Constant.INBOUND: @@ -255,14 +265,22 @@ public class MqttCallBack extends BaseManager implements MqttCallbackExtended { Synchronizedstatus.setInitStatus(true); }); } else if (Synchronizedstatus.getInitStatus()) { - LogUtil.log(TAG, "收到:一键起飞" + jsonString); - //设置modecode - Movement.getInstance().setMode_code(1); - //设置标志为指令飞行 - Movement.getInstance().setFlightmode(2); - TakeoffProgressScheduler.getInstance().startReporting(); - TakeOffToPointManager.getInstance().taskExecute(message); - Synchronizedstatus.setIsruning(true); + if(!Synchronizedstatus.isTakeoff_to_point()){ + + LogUtil.log(TAG, "收到:一键起飞" + jsonString); + //设置modecode + Movement.getInstance().setMode_code(1); + //设置标志为指令飞行 + Movement.getInstance().setFlightmode(2); + TakeoffProgressScheduler.getInstance().startReporting(); + TakeOffToPointManager.getInstance().taskExecute(message); + Synchronizedstatus.setIsruning(true); + + Synchronizedstatus.setTakeoff_to_point(true); + }else{ + sendFailMsg2Server(message,"已经收到一键航线"); + } + } } break; @@ -298,8 +316,14 @@ public class MqttCallBack extends BaseManager implements MqttCallbackExtended { break; case Constant.DRONE_CONTROL: LogUtil.log(TAG, "收到:DRC-飞行控制" + jsonString); - resetVirtualStickHeartbeat(); - StickManager.getInstance().sendVirtualStickAdvancedParam(message); + if (!Movement.getInstance().isAlternate() && !ApronArucoDetectPort.getInstance().isStartAruco() && !ApronArucoDetect.getInstance().isStartAruco() && !Aprongim.getInstance().isStartAruco() && !Aprondown.getInstance().isStartAruco()) { + resetVirtualStickHeartbeat(); + StickManager.getInstance().sendVirtualStickAdvancedParam(message); + }else{ + sendFailMsg2Server(message,"正在视觉或飞往备降不允输入摇杆"); + sendEvent2Server("正在视觉或飞往备降不允输入摇杆", 1); + LogUtil.log(TAG,"正在视觉或飞往备降不允输入摇杆"); + } break; case Constant.DRONE_EMERGENCY_STOP: LogUtil.log(TAG, "收到:DRC-飞行器急停" + jsonString); @@ -328,6 +352,7 @@ public class MqttCallBack extends BaseManager implements MqttCallbackExtended { case Constant.CAMERA_SCREEN_DRAG: LogUtil.log(TAG, "收到:负载控制—画面拖动控制" + jsonString); if (ApronArucoDetect.getInstance().isStartAruco() || ApronArucoDetectPort.getInstance().isStartAruco() || Aprongim.getInstance().isStartAruco() || Aprondown.getInstance().isStartAruco()) { + sendFailMsg2Server(message,"自动降落不可以动负载"); sendEvent2Server("自动降落不可以动负载", 1); return; } else { @@ -337,6 +362,7 @@ public class MqttCallBack extends BaseManager implements MqttCallbackExtended { case Constant.CAMERA_AIM: LogUtil.log(TAG, "收到:负载控制—双击成为 AIM" + jsonString); if (ApronArucoDetect.getInstance().isStartAruco() || ApronArucoDetectPort.getInstance().isStartAruco() || Aprongim.getInstance().isStartAruco() || Aprondown.getInstance().isStartAruco()) { + sendFailMsg2Server(message,"自动降落不可以动负载"); sendEvent2Server("自动降落不可以动负载", 1); return; } else { @@ -346,6 +372,7 @@ public class MqttCallBack extends BaseManager implements MqttCallbackExtended { case Constant.CAMERA_FOCAL_LENGTH_SET: LogUtil.log(TAG, "收到:负载控制—变焦" + jsonString); if (ApronArucoDetect.getInstance().isStartAruco() || ApronArucoDetectPort.getInstance().isStartAruco() || Aprongim.getInstance().isStartAruco() || Aprondown.getInstance().isStartAruco()) { + sendFailMsg2Server(message,"自动降落不可以动负载"); sendEvent2Server("自动降落不可以动负载", 1); return; } else { @@ -355,6 +382,7 @@ public class MqttCallBack extends BaseManager implements MqttCallbackExtended { case Constant.GIMBAL_RESET: LogUtil.log(TAG, "收到:负载控制—重置云台" + jsonString); if (ApronArucoDetect.getInstance().isStartAruco() || ApronArucoDetectPort.getInstance().isStartAruco() || Aprongim.getInstance().isStartAruco() || Aprondown.getInstance().isStartAruco()) { + sendFailMsg2Server(message,"自动降落不可以动负载"); sendEvent2Server("自动降落不可以动负载", 1); return; } else { @@ -364,6 +392,7 @@ public class MqttCallBack extends BaseManager implements MqttCallbackExtended { case Constant.CAMERA_LOOK_AT: LogUtil.log(TAG, "收到:负载控制—Look At" + jsonString); if (ApronArucoDetect.getInstance().isStartAruco() || ApronArucoDetectPort.getInstance().isStartAruco() || Aprongim.getInstance().isStartAruco() || Aprondown.getInstance().isStartAruco()) { + sendFailMsg2Server(message,"自动降落不可以动负载"); sendEvent2Server("自动降落不可以动负载", 1); return; } else { @@ -417,6 +446,7 @@ public class MqttCallBack extends BaseManager implements MqttCallbackExtended { case Constant.CAMERA_FRAME_ZOOM: LogUtil.log(TAG, "收到:框选变焦" + jsonString); if (ApronArucoDetect.getInstance().isStartAruco() || ApronArucoDetectPort.getInstance().isStartAruco() || Aprongim.getInstance().isStartAruco() || Aprondown.getInstance().isStartAruco()) { + sendFailMsg2Server(message,"自动降落不可以动负载"); sendEvent2Server("自动降落不可以动负载", 1); return; } else { @@ -426,6 +456,7 @@ public class MqttCallBack extends BaseManager implements MqttCallbackExtended { case Constant.SPEAKER_AUDIO_PLAY_START: LogUtil.log(TAG, "收到:喊话器-开始播放音频" + jsonString); SpeakerProgressReporter.getInstance().startAudioReport(2); + SpeakerManager.getInstance().setindex(); synchronized (lock) { if (!Synchronizedstatus.isSpeakrunning()) { SpeakerManager.getInstance().speakerAudioPlayStart(message); @@ -439,6 +470,7 @@ public class MqttCallBack extends BaseManager implements MqttCallbackExtended { case Constant.SPEAKER_TTS_PLAY_START: LogUtil.log(TAG, "收到:喊话器-开始播放TTS文本" + jsonString); SpeakerProgressReporter.getInstance().startTTSReport(2); + SpeakerManager.getInstance().setindex(); synchronized (lock) { if (!Synchronizedstatus.isSpeakrunning()) { SpeakerManager.getInstance().speakerTTSPlayStart(message, 0); @@ -451,6 +483,7 @@ public class MqttCallBack extends BaseManager implements MqttCallbackExtended { break; case Constant.SPEAKER_REPLAY: LogUtil.log(TAG, "收到:喊话器-重新播放" + jsonString); + SpeakerManager.getInstance().setindex(); synchronized (lock) { if (!Synchronizedstatus.isSpeakrunning()) { SpeakerManager.getInstance().speakerReply(message); @@ -463,6 +496,7 @@ public class MqttCallBack extends BaseManager implements MqttCallbackExtended { break; case Constant.SPEAKER_PLAY_STOP: LogUtil.log(TAG, "收到:喊话器-停止播放" + jsonString); + SpeakerManager.getInstance().setindex(); synchronized (lock) { if (!Synchronizedstatus.isSpeakrunning()) { SpeakerManager.getInstance().speakerStop(message); @@ -476,6 +510,7 @@ public class MqttCallBack extends BaseManager implements MqttCallbackExtended { break; case Constant.SPEAKER_PLAY_MODE_SET: LogUtil.log(TAG, "收到:喊话器-设置播放模式" + jsonString); + SpeakerManager.getInstance().setindex(); synchronized (lock) { if (!Synchronizedstatus.isSpeakrunning()) { SpeakerManager.getInstance().speakerPlayModeSet(message); @@ -485,10 +520,10 @@ public class MqttCallBack extends BaseManager implements MqttCallbackExtended { return; } } - break; case Constant.SPEAKER_PLAY_VOLUME_SET: LogUtil.log(TAG, "收到:喊话器-设置音量" + jsonString); + SpeakerManager.getInstance().setindex(); synchronized (lock) { if (!Synchronizedstatus.isSpeakrunning()) { SpeakerManager.getInstance().speakerPlayVolumeSet(message); @@ -498,11 +533,10 @@ public class MqttCallBack extends BaseManager implements MqttCallbackExtended { return; } } - break; case Constant.DRC_SPEAKER_TTS_SET: LogUtil.log(TAG, "收到:喊话器-TTS喊话设置" + jsonString); - + SpeakerManager.getInstance().setindex(); synchronized (lock) { if (!Synchronizedstatus.isSpeakrunning()) { SpeakerManager.getInstance().speakerTTSPlayStart(message, 1); @@ -512,7 +546,6 @@ public class MqttCallBack extends BaseManager implements MqttCallbackExtended { return; } } - break; case Constant.UAV_LIVE_FPV: //LogUtil.log(TAG, "收到:切换推流fpv" + jsonString); @@ -525,17 +558,26 @@ public class MqttCallBack extends BaseManager implements MqttCallbackExtended { case Constant.DRC_LIGHT_BRIGHTNESS_SET: synchronized (lock) { if (Synchronizedstatus.isLight_brightnessrunning()){ + sendMsg2Server(message); return; }else { - + PayloadlightManager.getInstance().drc_light_brightness_set(message); + Synchronizedstatus.setLight_brightnessrunning(true); } } - // LogUtil.log(TAG, "收到:A1亮度设置 " + jsonString); - // 处理亮度设置逻辑 break; - case Constant.DRC_LIGHT_MODE_SET: // LogUtil.log(TAG, "收到:A1模式设置 " + jsonString); + synchronized (lock) { + if (Synchronizedstatus.isDrc_light_mode_set()){ + sendMsg2Server(message); + return; + }else { + PayloadlightManager.getInstance().drc_light_mode_set(message); + Synchronizedstatus.setDrc_light_mode_set(true); + } + } + // 处理模式设置逻辑 break; @@ -547,6 +589,15 @@ public class MqttCallBack extends BaseManager implements MqttCallbackExtended { case Constant.DRC_LIGHT_CALIBRATION: // LogUtil.log(TAG, "收到:A1云台校准 " + jsonString); // 处理云台校准逻辑 + synchronized (lock) { + if (Synchronizedstatus.isDrc_light_calibration()){ + sendMsg2Server(message); + return; + }else { + PayloadlightManager.getInstance().drc_light_calibration(message); + Synchronizedstatus.setDrc_light_calibration(true); + } + } break; diff --git a/app/src/main/java/com/aros/apron/entity/Movement.java b/app/src/main/java/com/aros/apron/entity/Movement.java index 47adfb0b..b5a794c0 100644 --- a/app/src/main/java/com/aros/apron/entity/Movement.java +++ b/app/src/main/java/com/aros/apron/entity/Movement.java @@ -116,6 +116,8 @@ public class Movement { private int GPSSatelliteCount; //卫星个数 private boolean Alternate=false; + private boolean camera3stick=false;//3号相机模式释放控制权 + //适配上云格式参数,拿到后再进行组装 private double measure_target_altitude; @@ -195,7 +197,7 @@ public class Movement { private int wind_direction; private int wind_speed; - private int camera_mode; + private int camera_mode=0; private int ir_metering_mode; private int temperature; private double x; @@ -210,7 +212,7 @@ public class Movement { private int record_time; private int recording_state; private int remain_photo_num; - private int remain_record_duration; + private int remain_record_duration=3000; private boolean screen_split_enable; private int wide_exposure_mode; private int wide_exposure_value; @@ -220,7 +222,7 @@ public class Movement { private int zoom_calibrate_nearest_focus_value; private int zoom_exposure_mode; private int zoom_exposure_value; - private double zoom_factor; + private double zoom_factor=2; private int zoom_focus_mode; private int zoom_focus_state; private int zoom_focus_value; @@ -278,6 +280,16 @@ public class Movement { private String freq_band_4g; private boolean istakeoffex=false; + private boolean waylineinterpter=true; + + + public boolean isWaylineinterpter() { + return waylineinterpter; + } + + public void setWaylineinterpter(boolean waylineinterpter) { + this.waylineinterpter = waylineinterpter; + } public boolean isAlternate() { return Alternate; @@ -344,6 +356,14 @@ public class Movement { private String md5; + public boolean isCamera3stick() { + return camera3stick; + } + + public void setCamera3stick(boolean camera3stick) { + this.camera3stick = camera3stick; + } + public int getSpeakerpercent() { return speakerpercent; } diff --git a/app/src/main/java/com/aros/apron/entity/Synchronizedstatus.java b/app/src/main/java/com/aros/apron/entity/Synchronizedstatus.java index 2774dc76..ecf0d510 100644 --- a/app/src/main/java/com/aros/apron/entity/Synchronizedstatus.java +++ b/app/src/main/java/com/aros/apron/entity/Synchronizedstatus.java @@ -25,14 +25,53 @@ public class Synchronizedstatus { //探照灯线程 private static volatile boolean light_brightnessrunning=false; + private static volatile boolean drc_light_mode_set=false; + + + private static volatile boolean drc_light_fine_tuning_set=false; + private static volatile boolean drc_light_calibration=false; + //喊话器线程 private static volatile boolean speakrunning=false; private static volatile boolean speakTTSrunning=false; private static volatile boolean speaksetrunning=false; + private static volatile boolean takeoff_to_point=false; + public static boolean isTakeoff_to_point() { + return takeoff_to_point; + } + + public static void setTakeoff_to_point(boolean takeoff_to_point) { + Synchronizedstatus.takeoff_to_point = takeoff_to_point; + } + + public static boolean isDrc_light_mode_set() { + return drc_light_mode_set; + } + + public static void setDrc_light_mode_set(boolean drc_light_mode_set) { + Synchronizedstatus.drc_light_mode_set = drc_light_mode_set; + } + + public static boolean isDrc_light_fine_tuning_set() { + return drc_light_fine_tuning_set; + } + + public static void setDrc_light_fine_tuning_set(boolean drc_light_fine_tuning_set) { + Synchronizedstatus.drc_light_fine_tuning_set = drc_light_fine_tuning_set; + } + + public static boolean isDrc_light_calibration() { + return drc_light_calibration; + } + + public static void setDrc_light_calibration(boolean drc_light_calibration) { + Synchronizedstatus.drc_light_calibration = drc_light_calibration; + } + public static boolean isSpeaksetrunning() { return speaksetrunning; } diff --git a/app/src/main/java/com/aros/apron/manager/AlternateLandingManager.java b/app/src/main/java/com/aros/apron/manager/AlternateLandingManager.java index 98f22a40..1793bbd8 100644 --- a/app/src/main/java/com/aros/apron/manager/AlternateLandingManager.java +++ b/app/src/main/java/com/aros/apron/manager/AlternateLandingManager.java @@ -301,6 +301,7 @@ public class AlternateLandingManager extends BaseManager { @Override public void run() { Movement.getInstance().setWaylinename("alternate"); + PreferenceUtils.getInstance().setWaylinename("alternate"); missionManager.startMission("alternate", new CommonCallbacks.CompletionCallback() { @Override public void onSuccess() { diff --git a/app/src/main/java/com/aros/apron/manager/CameraManager.java b/app/src/main/java/com/aros/apron/manager/CameraManager.java index 060ef712..4ffd222c 100644 --- a/app/src/main/java/com/aros/apron/manager/CameraManager.java +++ b/app/src/main/java/com/aros/apron/manager/CameraManager.java @@ -10,10 +10,12 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.amazonaws.services.kms.model.KeyState; import com.aros.apron.base.BaseManager; import com.aros.apron.entity.MessageDown; import com.aros.apron.entity.Movement; import com.aros.apron.tools.LogUtil; +import com.aros.apron.tools.PreferenceUtils; import com.google.gson.Gson; import dji.sdk.keyvalue.key.CameraKey; @@ -26,6 +28,7 @@ import dji.sdk.keyvalue.value.camera.CameraFocusMode; import dji.sdk.keyvalue.value.camera.CameraFocusState; import dji.sdk.keyvalue.value.camera.CameraISO; import dji.sdk.keyvalue.value.camera.CameraMode; +import dji.sdk.keyvalue.value.camera.CameraShootPhotoMode; import dji.sdk.keyvalue.value.camera.CameraShutterSpeed; import dji.sdk.keyvalue.value.camera.CameraStorageInfo; import dji.sdk.keyvalue.value.camera.CameraStorageInfos; @@ -54,12 +57,16 @@ import dji.sdk.keyvalue.value.product.ProductType; import dji.v5.common.callback.CommonCallbacks; import dji.v5.common.error.IDJIError; import dji.v5.manager.KeyManager; +import dji.v5.manager.SDKManager; +import dji.v5.manager.aircraft.waypoint3.WaypointMissionManager; +import dji.v5.manager.interfaces.IWaypointMissionManager; public class CameraManager extends BaseManager { private Handler panoHandler = new Handler(Looper.getMainLooper()); private Runnable panoRunnable; private boolean isPanoRunning = false; private static final long INTERVAL = 1000; // 1秒 + private void startReport() { if (isPanoRunning) return; // 已开启则忽略 @@ -90,573 +97,640 @@ public class CameraManager extends BaseManager { } - - private CameraManager() { -} + } -private static class CameraHolder { - private static final CameraManager INSTANCE = new CameraManager(); -} + private static class CameraHolder { + private static final CameraManager INSTANCE = new CameraManager(); + } -public static CameraManager getInstance() { - return CameraHolder.INSTANCE; -} + public static CameraManager getInstance() { + return CameraHolder.INSTANCE; + } -public void initCameraInfo() { + public void initCameraInfo() { - Boolean isConnect = KeyManager.getInstance().getValue(createKey(FlightControllerKey.KeyConnection)); - LogUtil.log(TAG,"isConnect"+isConnect); - if (isConnect != null && isConnect) { - //全局画面中测量的最高温度 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyThermalGlobalMinTemperature, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_THERMAL), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable Double aDouble, @Nullable Double t1) { - if (t1 != null) { - Movement.getInstance().setThermal_global_temperature_min(t1); + Boolean isConnect = KeyManager.getInstance().getValue(createKey(FlightControllerKey.KeyConnection)); + LogUtil.log(TAG, "isConnect" + isConnect); + if (isConnect != null && isConnect) { + //全局画面中测量的最高温度 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyThermalGlobalMinTemperature, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_THERMAL), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable Double aDouble, @Nullable Double t1) { + if (t1 != null) { + Movement.getInstance().setThermal_global_temperature_min(t1); + } } - } - }); + }); - //全景任务状态 - KeyManager.getInstance().listen(createKey(CameraKey.KeyVisionPhotoPanoramaMissionState, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable VisionPhotoPanoramaMissionState visionPhotoPanoramaMissionState, @Nullable VisionPhotoPanoramaMissionState t1) { - if (t1 != null) { - if (t1 == VisionPhotoPanoramaMissionState.IDLE) { - Movement.getInstance().setPhoto_current_step(3000); - } else if (t1 == VisionPhotoPanoramaMissionState.RELEASE) { + //全景任务状态 + KeyManager.getInstance().listen(createKey(CameraKey.KeyVisionPhotoPanoramaMissionState, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable VisionPhotoPanoramaMissionState visionPhotoPanoramaMissionState, @Nullable VisionPhotoPanoramaMissionState t1) { + if (t1 != null) { + if (t1 == VisionPhotoPanoramaMissionState.IDLE) { + Movement.getInstance().setPhoto_current_step(3000); + } else if (t1 == VisionPhotoPanoramaMissionState.RELEASE) { // Movement.getInstance().setPhoto_result(0); // Movement.getInstance().setPhoto_status("ok"); // Movement.getInstance().setCameraMode(3); // stopReport(); - } else if (t1 == VisionPhotoPanoramaMissionState.RUNNING) { - Movement.getInstance().setPhoto_status("in_progress"); - Movement.getInstance().setPhoto_current_step(3002); - } else if (t1 == VisionPhotoPanoramaMissionState.UNKNOWN) { + } else if (t1 == VisionPhotoPanoramaMissionState.RUNNING) { + Movement.getInstance().setPhoto_status("in_progress"); + Movement.getInstance().setPhoto_current_step(3002); + } else if (t1 == VisionPhotoPanoramaMissionState.UNKNOWN) { // Movement.getInstance().setPhoto_result(1); // Movement.getInstance().setPhoto_current_step(3000); // Movement.getInstance().setPhoto_status("fail"); - } else if (t1 == VisionPhotoPanoramaMissionState.PROCESSING) { - Movement.getInstance().setPhoto_current_step(3005); - } + } else if (t1 == VisionPhotoPanoramaMissionState.PROCESSING) { + Movement.getInstance().setPhoto_current_step(3005); + } // else if (t1 == VisionPhotoPanoramaMissionState.FORBIDDEN) { // Movement.getInstance().setPhoto_result(1); // Movement.getInstance().setPhoto_current_step(3000); // Movement.getInstance().setPhoto_status("fail"); // } - } - } - }); - //全景退出 - KeyManager.getInstance().listen(createKey(CameraKey.KeyPanoramaExitStatus, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable PanoramaExitStatus panoramaExitStatus, @Nullable PanoramaExitStatus t1) { - if(t1!=null){ - LogUtil.log(TAG,t1.toString()); - if(t1==PanoramaExitStatus.SUCCESSFUL){ - Movement.getInstance().setPhoto_current_step(3000); - Movement.getInstance().setPhoto_result(0); - Movement.getInstance().setPhoto_status("ok"); - Movement.getInstance().setCameraMode(3); - Movement.getInstance().setMode_code(3); - stopReport(); } } - } - }); - - KeyManager.getInstance().listen(createKey(CameraKey.KeyPanoramaProgressInPercent, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable Integer integer, @Nullable Integer t1) { - if (t1 != null) { - Movement.getInstance().setPhoto_percent(t1); - if(t1==100){ - Movement.getInstance().setPhoto_current_step(3000); - Movement.getInstance().setPhoto_result(0); - Movement.getInstance().setPhoto_status("ok"); - Movement.getInstance().setCameraMode(3); - Movement.getInstance().setMode_code(3); - stopReport(); + }); + //全景退出 + KeyManager.getInstance().listen(createKey(CameraKey.KeyPanoramaExitStatus, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable PanoramaExitStatus panoramaExitStatus, @Nullable PanoramaExitStatus t1) { + if (t1 != null) { + LogUtil.log(TAG, "全景退出状态:" + t1.toString()); + // 处理 SUCCESSFUL 和 CAMERA_TOPMODE_RESET 两种完成状态 + if (t1 == PanoramaExitStatus.SUCCESSFUL) { + Movement.getInstance().setPhoto_current_step(3000); + Movement.getInstance().setPhoto_result(0); + Movement.getInstance().setPhoto_status("ok"); + Movement.getInstance().setMode_code(3); + stopReport(); + } else if (t1 == PanoramaExitStatus.CAMERA_TOPMODE_RESET) { + Movement.getInstance().setPhoto_current_step(3000); + Movement.getInstance().setPhoto_result(0); + Movement.getInstance().setPhoto_status("fail"); + Movement.getInstance().setMode_code(3); + stopReport(); + } } } - } - }); - //是否正在拍全景 - KeyManager.getInstance().listen(createKey(CameraKey.KeyIsShootingPhotoPanorama, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable Boolean aBoolean, @Nullable Boolean t1) { - if (t1 != null) { - if (t1 == true) { - startReport(); - } else { - stopReport(); + }); + + KeyManager.getInstance().listen(createKey(CameraKey.KeyPanoramaProgressInPercent, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable Integer integer, @Nullable Integer t1) { + if (t1 != null) { + Movement.getInstance().setPhoto_percent(t1); + if (t1 == 100) { + Movement.getInstance().setPhoto_current_step(3000); + Movement.getInstance().setPhoto_result(0); + Movement.getInstance().setPhoto_status("ok"); + Movement.getInstance().setCameraMode(3); + Movement.getInstance().setMode_code(3); + stopReport(); + } } } - } - }); - - //激光测距信息 - KeyManager.getInstance().listen(createKey(CameraKey.KeyLaserMeasureInformation, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable LaserMeasureInformation laserMeasureInformation, @Nullable LaserMeasureInformation t1) { - if (t1 != null) { - if (t1.getLocation3D() != null) { - Movement.getInstance().setMeasure_target_altitude(t1.getLocation3D().getAltitude()); - Movement.getInstance().setMeasure_target_latitude(t1.getLocation3D().getLatitude()); - Movement.getInstance().setMeasure_target_longitude(t1.getLocation3D().getLongitude()); - Movement.getInstance().setMeasure_target_distance(t1.getDistance().intValue()); - Movement.getInstance().setMeasure_target_error_state(t1.getLaserMeasureState().value()); - Movement.getInstance().setPayload_index("53-0-0"); + }); + //是否正在拍全景 + KeyManager.getInstance().listen(createKey(CameraKey.KeyIsShootingPhotoPanorama, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable Boolean aBoolean, @Nullable Boolean t1) { + if (t1 != null) { + if (t1 == true) { + startReport(); + } else { + stopReport(); + } } } - } - }); + }); - //调色盘样式。{"0":"白热","1":"黑热","2":"描红","3":"医疗","5":"彩虹 1","6":"铁红","8":"北极","11":"熔岩","12":"热铁","13":"彩虹 2"} - KeyManager.getInstance().listen(createKey(CameraKey.KeyThermalPalette, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable CameraThermalPalette cameraThermalPalette, @Nullable CameraThermalPalette t1) { - if (t1 != null) { - Movement.getInstance().setThermal_current_palette_style(t1.value()); - } - } - }); - - //增益模式。{"0":"自动","1":"低增益, 测温范围0°C-500°C","2":"高增益, 测温范围-20°C-150°C"} - KeyManager.getInstance().listen(createKey(CameraKey.KeyThermalGainMode, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable ThermalGainMode thermalGainMode, @Nullable ThermalGainMode t1) { - if (t1 != null) { - Movement.getInstance().setThermal_gain_mode(t1.value()); - } - } - }); - - //全局画面中测量的最高温度 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyThermalGlobalMaxTemperature, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_THERMAL), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable Double aDouble, @Nullable Double t1) { - if (t1 != null) { - Movement.getInstance().setThermal_global_temperature_max(t1); - } - } - }); - - //等温线最高值。较低和中等等温线阈值之间的温度值将以调色板中的128-175色显示。 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyThermalIsothermUpperValue, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_THERMAL), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable Integer integer, @Nullable Integer t1) { - if (t1 != null) { - Movement.getInstance().setThermal_isotherm_upper_limit(t1); - } - } - }); - - //等温线最低值。较低和中等等温线阈值之间的温度值将以调色板中的128-175色显示。 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyThermalIsothermLowerValue, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_THERMAL), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable Integer integer, @Nullable Integer t1) { - if (t1 != null) { - Movement.getInstance().setThermal_isotherm_lower_limit(t1); - } - } - }); - - //是否开启等温线 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyThermalIsothermEnabled, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_THERMAL), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable Boolean aBoolean, @Nullable Boolean t1) { - if (t1 != null) { - Movement.getInstance().setThermal_isotherm_state(t1 ? 1 : 0); - } - } - }); - - //相机模式 - KeyManager.getInstance().listen(KeyTools.createKey(CameraKey. - KeyCameraMode, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable CameraMode oldValue, @Nullable CameraMode newValue) { - if (newValue != null) { - //Movement.getInstance().setCamera_mode(newValue.value()); - // LogUtil.log(TAG, "相机模式:" + newValue + "old" + oldValue); - } - } - }); - - //当前测温模式 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyThermalTemperatureMeasureMode, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_THERMAL), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable ThermalTemperatureMeasureMode thermalTemperatureMeasureMode, @Nullable ThermalTemperatureMeasureMode t1) { - if (t1 != null && thermalTemperatureMeasureMode != null) { - Movement.getInstance().setIr_metering_mode(thermalTemperatureMeasureMode.value()); - } - } - }); - - //当前测温的点的位置 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyThermalSpotMetersurePoint, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_THERMAL), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable DoublePoint2D doublePoint2D, @Nullable DoublePoint2D t1) { - if (t1 != null) { - Movement.getInstance().setX(t1.getX()); - Movement.getInstance().setX(t1.getY()); - } - } - }); - - //当前测温的点的温度 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyThermalSpotMetersureTemperature, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_THERMAL), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable Double aDouble, @Nullable Double t1) { - if (t1 != null) { - Movement.getInstance().setTemperature(t1.intValue()); - } - } - }); - - //当前红外变焦倍率 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyThermalZoomRatios, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_THERMAL), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable Double aDouble, @Nullable Double t1) { - if (t1 != null) { - Movement.getInstance().setIr_zoom_factor(t1.intValue()); - } - } - }); - - //拍照状态 - KeyManager.getInstance().listen(KeyTools.createKey(CameraKey.KeyPhotoState, - ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable PhotoState photoState, @Nullable PhotoState t1) { - if (t1 != null) { - Movement.getInstance().setPhoto_state(t1.value()); - } - } - }); - - //视频录制时长 - KeyManager.getInstance().listen(KeyTools.createKey(CameraKey. - KeyRecordingTime, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable Integer oldValue, @Nullable Integer newValue) { - if (newValue != null) { - Movement.getInstance().setRecord_time(newValue); - } - } - }); - //视频录制状态 - KeyManager.getInstance().listen(KeyTools.createKey(CameraKey. - KeyRecordingState, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable RecordingState recordingState, @Nullable RecordingState t1) { - if (t1 != null) { - Movement.getInstance().setRecording_state(t1.value() == 0 ? 0 : 1); - } - } - }); - - //剩余照片数 - KeyManager.getInstance().listen(KeyTools.createKey(CameraKey. - KeySDCardAvailablePhotoCount, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable Integer integer, @Nullable Integer t1) { - if (t1 != null) { - //LogUtil.log(TAG, "剩余拍照数setRemain_photo_num" + t1 + "old" + integer); - if (t1 != 0) { - Movement.getInstance().setRemain_photo_num(t1); - } - - } - } - }); - - //视频录制时长 - KeyManager.getInstance().listen(KeyTools.createKey(CameraKey.KeyRecordingTime, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable Integer integer, @Nullable Integer t1) { - if (t1 != null) { - Movement.getInstance().setRecord_time(t1); - } - } - }); - //是否在录像 - KeyManager.getInstance().listen(KeyTools.createKey(CameraKey.KeyVideoRecordingStatus, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable VideoRecordingStatus videoRecordingStatus, @Nullable VideoRecordingStatus t1) { - if (t1 != null) { - Boolean recording = t1.getIsRecording(); - if (recording != null && recording) { - Movement.getInstance().setRecording_state(1); // 正在录 - } else { - Movement.getInstance().setRecording_state(0); // 未录或未知 + //激光测距信息 + KeyManager.getInstance().listen(createKey(CameraKey.KeyLaserMeasureInformation, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable LaserMeasureInformation laserMeasureInformation, @Nullable LaserMeasureInformation t1) { + if (t1 != null) { + if (t1.getLocation3D() != null) { + Movement.getInstance().setMeasure_target_altitude(t1.getLocation3D().getAltitude()); + Movement.getInstance().setMeasure_target_latitude(t1.getLocation3D().getLatitude()); + Movement.getInstance().setMeasure_target_longitude(t1.getLocation3D().getLongitude()); + Movement.getInstance().setMeasure_target_distance(t1.getDistance().intValue()); + Movement.getInstance().setMeasure_target_error_state(t1.getLaserMeasureState().value()); + Movement.getInstance().setPayload_index("53-0-0"); + } } } - } - }); - //分屏是否使能 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyThermalDisplayMode, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_THERMAL), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable ThermalDisplayMode thermalDisplayMode, @Nullable ThermalDisplayMode t1) { - if (t1 != null) { - Movement.getInstance().setScreen_split_enable(t1.value() == 2 ? true : false); - } - } - }); + }); - //广角镜头曝光模式 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyExposureMode, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_WIDE), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable CameraExposureMode cameraExposureMode, @Nullable CameraExposureMode t1) { - if (t1 != null) { - //LogUtil.log(TAG, "监听曝光模式:" + t1.name()); - Movement.getInstance().setWide_exposure_mode(t1.value()); + //调色盘样式。{"0":"白热","1":"黑热","2":"描红","3":"医疗","5":"彩虹 1","6":"铁红","8":"北极","11":"熔岩","12":"热铁","13":"彩虹 2"} + KeyManager.getInstance().listen(createKey(CameraKey.KeyThermalPalette, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable CameraThermalPalette cameraThermalPalette, @Nullable CameraThermalPalette t1) { + if (t1 != null) { + Movement.getInstance().setThermal_current_palette_style(t1.value()); + } } - } - }); + }); - //广角镜头曝光值 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyExposureCompensation, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_WIDE), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable CameraExposureCompensation cameraExposureCompensation, @Nullable CameraExposureCompensation t1) { - if (t1!= null) { - LogUtil.log(TAG, "监听曝光范围:" + t1.value()); - Movement.getInstance().setWide_exposure_value(t1.value()); + //增益模式。{"0":"自动","1":"低增益, 测温范围0°C-500°C","2":"高增益, 测温范围-20°C-150°C"} + KeyManager.getInstance().listen(createKey(CameraKey.KeyThermalGainMode, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable ThermalGainMode thermalGainMode, @Nullable ThermalGainMode t1) { + if (t1 != null) { + Movement.getInstance().setThermal_gain_mode(t1.value()); + } } - } - }); + }); - //广角镜头感光度 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyISO, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_WIDE), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable CameraISO cameraISO, @Nullable CameraISO t1) { - if (t1 != null) { - Movement.getInstance().setWide_iso(t1.value()); + //全局画面中测量的最高温度 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyThermalGlobalMaxTemperature, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_THERMAL), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable Double aDouble, @Nullable Double t1) { + if (t1 != null) { + Movement.getInstance().setThermal_global_temperature_max(t1); + } } - } - }); + }); - //广角镜头快门速度 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyShutterSpeed, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_WIDE), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable CameraShutterSpeed cameraShutterSpeed, @Nullable CameraShutterSpeed t1) { - if (t1 != null) { - Movement.getInstance().setWide_shutter_speed(t1.value()); + //等温线最高值。较低和中等等温线阈值之间的温度值将以调色板中的128-175色显示。 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyThermalIsothermUpperValue, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_THERMAL), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable Integer integer, @Nullable Integer t1) { + if (t1 != null) { + Movement.getInstance().setThermal_isotherm_upper_limit(t1); + } } - } - }); + }); - //变焦镜头标定的最远对焦值 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyCameraFocusRingMaxValue, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable Integer integer, @Nullable Integer t1) { - if (t1 != null) { - Movement.getInstance().setZoom_calibrate_farthest_focus_value(t1); + //等温线最低值。较低和中等等温线阈值之间的温度值将以调色板中的128-175色显示。 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyThermalIsothermLowerValue, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_THERMAL), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable Integer integer, @Nullable Integer t1) { + if (t1 != null) { + Movement.getInstance().setThermal_isotherm_lower_limit(t1); + } } - } - }); + }); - //变焦镜头标定的最近对焦值 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyCameraFocusRingMinValue, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable Integer integer, @Nullable Integer t1) { - if (t1 != null) { - Movement.getInstance().setZoom_calibrate_farthest_focus_value(t1); + //是否开启等温线 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyThermalIsothermEnabled, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_THERMAL), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable Boolean aBoolean, @Nullable Boolean t1) { + if (t1 != null) { + Movement.getInstance().setThermal_isotherm_state(t1 ? 1 : 0); + } } - } - }); + }); - //变焦镜头曝光模式 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyExposureMode, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable CameraExposureMode cameraExposureMode, @Nullable CameraExposureMode t1) { - if (t1 != null) { - Movement.getInstance().setZoom_exposure_mode(t1.value()); + //相机模式 + KeyManager.getInstance().listen(KeyTools.createKey(CameraKey. + KeyCameraMode, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable CameraMode oldValue, @Nullable CameraMode newValue) { + if (newValue != null) { + //Movement.getInstance().setCamera_mode(newValue.value()); + // LogUtil.log(TAG, "相机模式:" + newValue + "old" + oldValue); + } } - } - }); + }); - //变焦镜头感光度 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyExposureCompensation, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable CameraExposureCompensation cameraExposureCompensation, @Nullable CameraExposureCompensation t1) { - if (t1 != null) { - Movement.getInstance().setZoom_exposure_value(t1.value()); + //当前测温模式 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyThermalTemperatureMeasureMode, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_THERMAL), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable ThermalTemperatureMeasureMode thermalTemperatureMeasureMode, @Nullable ThermalTemperatureMeasureMode t1) { + if (t1 != null && thermalTemperatureMeasureMode != null) { + Movement.getInstance().setIr_metering_mode(thermalTemperatureMeasureMode.value()); + } } - } - }); + }); - //变焦镜头感光度 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyExposureCompensation, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable CameraExposureCompensation cameraExposureCompensation, @Nullable CameraExposureCompensation t1) { - if (t1 != null) { - Movement.getInstance().setZoom_exposure_value(t1.value()); + //当前测温的点的位置 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyThermalSpotMetersurePoint, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_THERMAL), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable DoublePoint2D doublePoint2D, @Nullable DoublePoint2D t1) { + if (t1 != null) { + Movement.getInstance().setX(t1.getX()); + Movement.getInstance().setX(t1.getY()); + } } - } - }); - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyThermalZoomRatios, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable Double aDouble, @Nullable Double t1) { - if (t1 != null) { - Movement.getInstance().setZoom_factor(t1); - } - } - }); - //变焦倍数 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyCameraZoomRatios, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable Double aDouble, @Nullable Double t1) { - if (t1 != null) { - Movement.getInstance().setZoom_factor(t1); - } - } - }); + }); - //变焦镜头对焦模式 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyCameraFocusMode, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable CameraFocusMode cameraFocusMode, @Nullable CameraFocusMode t1) { - if (t1 != null) { - Movement.getInstance().setZoom_focus_mode(t1.value()); + //当前测温的点的温度 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyThermalSpotMetersureTemperature, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_THERMAL), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable Double aDouble, @Nullable Double t1) { + if (t1 != null) { + Movement.getInstance().setTemperature(t1.intValue()); + } } - } - }); + }); - //变焦镜头对焦状态 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyCameraFocusState, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable CameraFocusState cameraFocusState, @Nullable CameraFocusState t1) { - if (t1 != null) { - Movement.getInstance().setZoom_focus_state(t1.value()); + //当前红外变焦倍率 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyThermalZoomRatios, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_THERMAL), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable Double aDouble, @Nullable Double t1) { + if (t1 != null) { + Movement.getInstance().setIr_zoom_factor(t1.intValue()); + } } - } - }); + }); - //变焦镜头对焦值 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyCameraFocusRingValue, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable Integer integer, @Nullable Integer t1) { - if (t1 != null) { - Movement.getInstance().setZoom_focus_value(t1); + //拍照状态 + KeyManager.getInstance().listen(KeyTools.createKey(CameraKey.KeyPhotoState, + ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable PhotoState photoState, @Nullable PhotoState t1) { + if (t1 != null) { + Movement.getInstance().setPhoto_state(t1.value()); + } } - } - }); + }); - //变焦镜头感光度 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyISO, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable CameraISO cameraISO, @Nullable CameraISO t1) { - if (t1 != null) { - Movement.getInstance().setZoom_iso(t1.value()); + //视频录制时长 + KeyManager.getInstance().listen(KeyTools.createKey(CameraKey. + KeyRecordingTime, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable Integer oldValue, @Nullable Integer newValue) { + if (newValue != null) { + Movement.getInstance().setRecord_time(newValue); + } } - } - }); - - //变焦镜头最大对焦值 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyCameraFocusRingMaxValue, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable Integer integer, @Nullable Integer t1) { - if (t1 != null) { - Movement.getInstance().setZoom_max_focus_value(t1); + }); + //视频录制状态 + KeyManager.getInstance().listen(KeyTools.createKey(CameraKey. + KeyRecordingState, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable RecordingState recordingState, @Nullable RecordingState t1) { + if (t1 != null) { + Movement.getInstance().setRecording_state(t1.value() == 0 ? 0 : 1); + } } - } - }); + }); - //变焦镜头最小对焦值 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyCameraFocusRingMinValue, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable Integer integer, @Nullable Integer t1) { - if (t1 != null) { - Movement.getInstance().setZoom_min_focus_value(t1); + //剩余照片数 + KeyManager.getInstance().listen(KeyTools.createKey(CameraKey. + KeySDCardAvailablePhotoCount, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable Integer integer, @Nullable Integer t1) { + if (t1 != null) { + //LogUtil.log(TAG, "剩余拍照数setRemain_photo_num" + t1 + "old" + integer); + if (t1 != 0) { + Movement.getInstance().setRemain_photo_num(t1); + } + + } } - } - }); + }); - //变焦镜头快门速度 - KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyShutterSpeed, - ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable CameraShutterSpeed cameraShutterSpeed, @Nullable CameraShutterSpeed t1) { - if (t1 != null) { - Movement.getInstance().setZoom_shutter_speed(t1.value()); + //视频录制时长 + KeyManager.getInstance().listen(KeyTools.createKey(CameraKey.KeyRecordingTime, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable Integer integer, @Nullable Integer t1) { + if (t1 != null) { + Movement.getInstance().setRecord_time(t1); + } } - } - }); + }); + //是否在录像 + KeyManager.getInstance().listen(KeyTools.createKey(CameraKey.KeyVideoRecordingStatus, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable VideoRecordingStatus videoRecordingStatus, @Nullable VideoRecordingStatus t1) { + if (t1 != null) { + Boolean recording = t1.getIsRecording(); + if (recording != null && recording) { + Movement.getInstance().setRecording_state(1); // 正在录 + } else { + Movement.getInstance().setRecording_state(0); // 未录或未知 + } + } + } + }); + //分屏是否使能 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyThermalDisplayMode, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_THERMAL), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable ThermalDisplayMode thermalDisplayMode, @Nullable ThermalDisplayMode t1) { + if (t1 != null) { + Movement.getInstance().setScreen_split_enable(t1.value() == 2 ? true : false); + } + } + }); - //SD卡容量 - KeyManager.getInstance().listen(KeyTools.createKey(CameraKey.KeyCameraStorageInfos, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { - @Override - public void onValueChange(@Nullable CameraStorageInfos cameraStorageInfos, @Nullable CameraStorageInfos t1) { - if (t1 != null) { - // LogUtil.log(TAG,"剩余时间"+t1.getCurrentCameraStorageInfo().getAvailableVideoDuration()); - //剩余录像时间 - Movement.getInstance().setRemain_record_duration(t1.getCurrentCameraStorageInfo().getAvailableVideoDuration()); + //广角镜头曝光模式 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyExposureMode, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_WIDE), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable CameraExposureMode cameraExposureMode, @Nullable CameraExposureMode t1) { + if (t1 != null) { + //LogUtil.log(TAG, "监听曝光模式:" + t1.name()); + Movement.getInstance().setWide_exposure_mode(t1.value()); + } + } + }); - CameraStorageInfo cameraStorageInfoByLocation = t1.getCameraStorageInfoByLocation(CameraStorageLocation.SDCARD); - if (cameraStorageInfoByLocation != null) { + //广角镜头曝光值 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyExposureCompensation, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_WIDE), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable CameraExposureCompensation cameraExposureCompensation, @Nullable CameraExposureCompensation t1) { + if (t1 != null) { + LogUtil.log(TAG, "监听曝光范围:" + t1.value()); + Movement.getInstance().setWide_exposure_value(t1.value()); + } + } + }); + + //广角镜头感光度 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyISO, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_WIDE), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable CameraISO cameraISO, @Nullable CameraISO t1) { + if (t1 != null) { + Movement.getInstance().setWide_iso(t1.value()); + } + } + }); + + //广角镜头快门速度 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyShutterSpeed, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_WIDE), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable CameraShutterSpeed cameraShutterSpeed, @Nullable CameraShutterSpeed t1) { + if (t1 != null) { + Movement.getInstance().setWide_shutter_speed(t1.value()); + } + } + }); + + //变焦镜头标定的最远对焦值 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyCameraFocusRingMaxValue, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable Integer integer, @Nullable Integer t1) { + if (t1 != null) { + Movement.getInstance().setZoom_calibrate_farthest_focus_value(t1); + } + } + }); + + //变焦镜头标定的最近对焦值 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyCameraFocusRingMinValue, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable Integer integer, @Nullable Integer t1) { + if (t1 != null) { + Movement.getInstance().setZoom_calibrate_farthest_focus_value(t1); + } + } + }); + + //变焦镜头曝光模式 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyExposureMode, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable CameraExposureMode cameraExposureMode, @Nullable CameraExposureMode t1) { + if (t1 != null) { + Movement.getInstance().setZoom_exposure_mode(t1.value()); + } + } + }); + + //变焦镜头感光度 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyExposureCompensation, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable CameraExposureCompensation cameraExposureCompensation, @Nullable CameraExposureCompensation t1) { + if (t1 != null) { + Movement.getInstance().setZoom_exposure_value(t1.value()); + } + } + }); + + //变焦镜头感光度 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyExposureCompensation, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable CameraExposureCompensation cameraExposureCompensation, @Nullable CameraExposureCompensation t1) { + if (t1 != null) { + Movement.getInstance().setZoom_exposure_value(t1.value()); + } + } + }); + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyThermalZoomRatios, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable Double aDouble, @Nullable Double t1) { + if (t1 != null) { + Movement.getInstance().setZoom_factor(t1); + } + } + }); + //变焦倍数 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyCameraZoomRatios, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable Double aDouble, @Nullable Double t1) { + if (t1 != null) { + Movement.getInstance().setZoom_factor(t1); + } + } + }); + + //变焦镜头对焦模式 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyCameraFocusMode, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable CameraFocusMode cameraFocusMode, @Nullable CameraFocusMode t1) { + if (t1 != null) { + Movement.getInstance().setZoom_focus_mode(t1.value()); + } + } + }); + + //变焦镜头对焦状态 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyCameraFocusState, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable CameraFocusState cameraFocusState, @Nullable CameraFocusState t1) { + if (t1 != null) { + Movement.getInstance().setZoom_focus_state(t1.value()); + } + } + }); + + //变焦镜头对焦值 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyCameraFocusRingValue, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable Integer integer, @Nullable Integer t1) { + if (t1 != null) { + Movement.getInstance().setZoom_focus_value(t1); + } + } + }); + + //变焦镜头感光度 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyISO, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable CameraISO cameraISO, @Nullable CameraISO t1) { + if (t1 != null) { + Movement.getInstance().setZoom_iso(t1.value()); + } + } + }); + + //变焦镜头最大对焦值 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyCameraFocusRingMaxValue, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable Integer integer, @Nullable Integer t1) { + if (t1 != null) { + Movement.getInstance().setZoom_max_focus_value(t1); + } + } + }); + + //变焦镜头最小对焦值 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyCameraFocusRingMinValue, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable Integer integer, @Nullable Integer t1) { + if (t1 != null) { + Movement.getInstance().setZoom_min_focus_value(t1); + } + } + }); + + //变焦镜头快门速度 + KeyManager.getInstance().listen(KeyTools.createCameraKey(CameraKey.KeyShutterSpeed, + ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_ZOOM), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable CameraShutterSpeed cameraShutterSpeed, @Nullable CameraShutterSpeed t1) { + if (t1 != null) { + Movement.getInstance().setZoom_shutter_speed(t1.value()); + } + } + }); + + + KeyManager.getInstance().listen( + KeyTools.createKey(CameraKey.KeyConnection, ComponentIndexType.PORT_1), + this, + new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable Boolean oldValue, @Nullable Boolean newValue) { + if (Boolean.TRUE.equals(newValue)) { + CameraStorageInfos cameraStorageInfos = + KeyManager.getInstance().getValue(KeyTools.createKey(CameraKey.KeyCameraStorageInfos, ComponentIndexType.PORT_1)); + if (cameraStorageInfos == null || cameraStorageInfos.getCameraStorageInfoList() == + null || cameraStorageInfos.getCameraStorageInfoList().isEmpty()) { + //LogUtil.log(TAG, "相机存储信息为空,相机可能未连接"); + return; + } + CameraStorageInfo CameraStorageInfo = + cameraStorageInfos.getCameraStorageInfoList().get(0); + if(CameraStorageInfo.getAvailableVideoDuration()!=0){ + Movement.getInstance().setRemain_record_duration(CameraStorageInfo.getAvailableVideoDuration()); + LogUtil.log(TAG, "剩余时间" + CameraStorageInfo.getAvailableVideoDuration()); + } + // LogUtil.log(TAG, "剩余时间" + CameraStorageInfo.getAvailableVideoDuration()); + } + } + }); + + + + //SD卡容量 + KeyManager.getInstance().listen(KeyTools.createKey(CameraKey.KeyCameraStorageInfos, ComponentIndexType.PORT_1), this, new CommonCallbacks.KeyListener() { + @Override + public void onValueChange(@Nullable CameraStorageInfos cameraStorageInfos, @Nullable CameraStorageInfos t1) { + if (t1 != null) { + // LogUtil.log(TAG,"剩余时间"+t1.getCurrentCameraStorageInfo().getAvailableVideoDuration()); + //剩余录像时间 + if(t1.getCurrentCameraStorageInfo().getAvailableVideoDuration()!=0){ + Movement.getInstance().setRemain_record_duration(t1.getCurrentCameraStorageInfo().getAvailableVideoDuration()); + } + + CameraStorageInfo cameraStorageInfoByLocation = t1.getCameraStorageInfoByLocation(CameraStorageLocation.SDCARD); + if (cameraStorageInfoByLocation != null) { // //剩余可以拍照张数 // int pitcurenum = cameraStorageInfoByLocation.getAvailablePhotoCount(); // Movement.getInstance().setRemain_photo_num(pitcurenum); // LogUtil.log(TAG, "//剩余可以拍照张数" + pitcurenum); - Movement.getInstance().setTotal(cameraStorageInfoByLocation.getStorageCapacity() * 1024); - Movement.getInstance().setUsed((cameraStorageInfoByLocation.getStorageCapacity() * 1024) - - (cameraStorageInfoByLocation.getStorageLeftCapacity())); + Movement.getInstance().setTotal(cameraStorageInfoByLocation.getStorageCapacity() * 1024); + Movement.getInstance().setUsed((cameraStorageInfoByLocation.getStorageCapacity() * 1024) + - (cameraStorageInfoByLocation.getStorageLeftCapacity())); + } + } - } - } - }); + }); + } } -} -//切换相机拍照录像模式 -public void setCameraMode(MessageDown message) { - Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(CameraKey. - KeyConnection, ComponentIndexType.PORT_1)); - if (isConnect != null && isConnect && getGimbalAndCameraEnabled()) { - if (message != null) { + //切换相机拍照录像模式 + public void setCameraMode(MessageDown message) { + Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(CameraKey. + KeyConnection, ComponentIndexType.PORT_1)); + if (isConnect != null && isConnect && getGimbalAndCameraEnabled()) { + if (message != null) { - int cameraMode = message.getData().getCamera_mode(); - // 新增:如果当前已经是该模式,直接返回成功 - if (cameraMode == Movement.getInstance().getCamera_mode()) { - LogUtil.log(TAG, "相机模式已是" + cameraMode + ",无需切换"); - sendMsg2Server(message); - return; - } + int cameraMode = message.getData().getCamera_mode(); + // 新增:如果当前已经是该模式,直接返回成功 + if (cameraMode == Movement.getInstance().getCamera_mode()) { + LogUtil.log(TAG, "相机模式已是" + cameraMode + ",无需切换"); + sendMsg2Server(message); + return; + } + +// if (cameraMode == 3) { +// // 全景模式:DJI MSDK v5 中全景是 PHOTO_NORMAL 下的子模式 PANO_APP, +// // 不能用 CameraMode.find(12),需先确保处于 PHOTO_NORMAL,再设置拍照子模式 +// KeyManager.getInstance().setValue(KeyTools.createKey(CameraKey.KeyCameraMode, ComponentIndexType.PORT_1), +// CameraMode.PHOTO_NORMAL, +// new CommonCallbacks.CompletionCallback() { +// @Override +// public void onSuccess() { +// KeyManager.getInstance().setValue( +// KeyTools.createKey(CameraKey.KeyCameraMode, ComponentIndexType.PORT_1), +// CameraMode.PHOTO_PANORAMA, +// new CommonCallbacks.CompletionCallback() { +// @Override +// public void onSuccess() { +// Movement.getInstance().setCamera_mode(cameraMode); +// LogUtil.log(TAG, "切换全景模式成功"); +// OSDManager.getInstance().pushFlightAttitude(); +// sendMsg2Server(message); +// } +// +// @Override +// public void onFailure(@NonNull IDJIError error) { +// sendFailMsg2Server(message, "全景子模式设置失败:" + getIDJIErrorMsg(error)); +// } +// }); +// } +// +// @Override +// public void onFailure(@NonNull IDJIError error) { +// sendFailMsg2Server(message, "相机模式切换失败:" + getIDJIErrorMsg(error)); +// } +// }); +// return; +// } - ProductType productType = KeyManager.getInstance().getValue(KeyTools.createKey(ProductKey.KeyProductType)); - if (productType != null) { int cameraModevalue = 0; if (cameraMode == 1) { cameraModevalue = 1; @@ -665,10 +739,6 @@ public void setCameraMode(MessageDown message) { } else if (cameraMode == 3) { cameraModevalue = 12; } -// if(cameraMode == 3){ -// //退出回放模式 -// MediaManager.getInstance().disablePlayback(); -// } KeyManager.getInstance().setValue(KeyTools.createKey(CameraKey.KeyCameraMode, ComponentIndexType.PORT_1), CameraMode.find(cameraModevalue), @@ -688,368 +758,574 @@ public void setCameraMode(MessageDown message) { } }); - } else { - sendFailMsg2Server(message, "切换失败:当前状态相机禁止操作"); + } + } else { + sendFailMsg2Server(message, "当前状态相机禁止操作"); } - } else { - sendFailMsg2Server(message, "当前状态相机禁止操作"); - } -} - -//框选变焦 -public void camera_frame_zoom(MessageDown message) { - //这个locked参数没有处理 - - //使用aim转过去 - Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey( - CameraKey.KeyConnection, ComponentIndexType.PORT_1)); - - if (isConnect == null || !isConnect || !getGimbalAndCameraEnabled()) { - LogUtil.log(TAG, "指点对焦失败:相机未连接或禁止操作"); - return; } - CameraLensType type = parseLensType1(message.getData().getCamera_type()); - if (type == null) { - sendFailMsg2Server(message, "不支持的相机类型"); - return; - } - KeyManager.getInstance().setValue( - KeyTools.createCameraKey(CameraKey.KeyTapZoomEnable, - ComponentIndexType.PORT_1, type), - true, - new CommonCallbacks.CompletionCallback() { - @Override - public void onSuccess() { - LogUtil.log(TAG, "设置使能指点成功"); - //使用aim 加变焦 - camera_frame_zoom_and_bianjiao(message, type); + //框选变焦 + public void camera_frame_zoom(MessageDown message) { + //这个locked参数没有处理 + //使用aim转过去 + Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey( + CameraKey.KeyConnection, ComponentIndexType.PORT_1)); - } + if (isConnect == null || !isConnect || !getGimbalAndCameraEnabled()) { + LogUtil.log(TAG, "指点对焦失败:相机未连接或禁止操作"); + return; + } - @Override - public void onFailure(@NonNull IDJIError error) { - LogUtil.log(TAG, "设置使能指点失败:" + new Gson().toJson(error)); - sendFailMsg2Server(message, "设置使能指点失败:" + getIDJIErrorMsg(error)); - } - }); -} + CameraLensType type = parseLensType1(message.getData().getCamera_type()); + if (type == null) { + sendFailMsg2Server(message, "不支持的相机类型"); + return; + } -private CameraLensType parseLensType1(String cameraType) { - if (cameraType == null) return null; - if ("ir".equals(cameraType)) { - return CameraLensType.CAMERA_LENS_THERMAL; - } else if ("wide".equals(cameraType)) { - return CameraLensType.CAMERA_LENS_ZOOM; - } else if ("zoom".equals(cameraType)) { - return CameraLensType.CAMERA_LENS_ZOOM; - } - return null; -} - - -private void camera_frame_zoom_and_bianjiao(MessageDown message, CameraLensType type) { - ZoomTargetPointInfo info = new ZoomTargetPointInfo(); - info.setX(Double.valueOf(message.getData().getX())); - info.setY(Double.valueOf(message.getData().getY())); - info.setTapZoomModeEnable(true); - - double width = message.getData().getWidth(); - double height = message.getData().getHeight(); - - double zoomRatio = calculateZoomRatio(width, height); - - //没有对lock判断 - info.setMode(TapZoomMode.GIMBAL_FOLLOW); // 或 TAP_ZOOM模式,看需求 - - KeyManager.getInstance().performAction( - KeyTools.createCameraKey(CameraKey.KeyTapZoomAtTarget, - ComponentIndexType.PORT_1, type), - info, - new CommonCallbacks.CompletionCallbackWithParam() { - @Override - public void onSuccess(EmptyMsg emptyMsg) { - //开始变焦 - KeyManager.getInstance().setValue(KeyTools.createCameraKey(CameraKey.KeyCameraZoomRatios, - ComponentIndexType.PORT_1, type), - Double.valueOf(zoomRatio), new CommonCallbacks.CompletionCallback() { - @Override - public void onSuccess() { - LogUtil.log(TAG, "变焦成功"); - sendMsg2Server(message); - } - - @Override - public void onFailure(@NonNull IDJIError idjiError) { - sendFailMsg2Server(message, "变焦失败:" + getIDJIErrorMsg(idjiError)); - } - }); - } - - @Override - public void onFailure(@NonNull IDJIError error) { - sendFailMsg2Server(message, "aim操作失败:" + getIDJIErrorMsg(error)); - } - }); -} - -//设置变焦倍率 -public static double calculateZoomRatio(double width, double height) { - // 防呆:如果传入 0 或负数,返回 1 倍(不 zoom) - if (width <= 0 || height <= 0) { - return 1.0; - } - - // 取宽高中的大值(保证框能装下) - double maxDimension = Math.max(width, height); - - // 反比计算:框越小,zoom 越大 - // 例:max=1.0(全画面)→ zoom=1.0 - // max=0.5(半屏) → zoom=2.0 - // max=0.005(很小) → zoom=200.0 - double zoom = 1.0 / maxDimension; - - // 限制在你的相机范围内 1x ~ 200x - return Math.max(1.0, Math.min(200.0, zoom)); - -} - -//开始拍照 -public void startShootPhoto(MessageDown message) { - Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(CameraKey. - KeyConnection, ComponentIndexType.PORT_1)); - if (isConnect != null && isConnect && getGimbalAndCameraEnabled()) { - KeyManager.getInstance().performAction(KeyTools.createKey(CameraKey.KeyStartShootPhoto, - ComponentIndexType.PORT_1), - new CommonCallbacks.CompletionCallbackWithParam() { + KeyManager.getInstance().setValue( + KeyTools.createCameraKey(CameraKey.KeyTapZoomEnable, + ComponentIndexType.PORT_1, type), + true, + new CommonCallbacks.CompletionCallback() { @Override - public void onSuccess(EmptyMsg emptyMsg) { - LogUtil.log(TAG,"拍照成功"); - sendMsg2Server(message); + public void onSuccess() { + LogUtil.log(TAG, "设置使能指点成功"); + //使用aim 加变焦 + camera_frame_zoom_and_bianjiao(message, type); + + } @Override public void onFailure(@NonNull IDJIError error) { - LogUtil.log(TAG, "拍照失败:" + new Gson().toJson(error)); - sendFailMsg2Server(message, "拍照失败:" + getIDJIErrorMsg(error)); + LogUtil.log(TAG, "设置使能指点失败:" + new Gson().toJson(error)); + sendFailMsg2Server(message, "设置使能指点失败:" + getIDJIErrorMsg(error)); } }); - } else { - sendFailMsg2Server(message, "当前状态相机禁止操作"); - } -} - - -//结束拍照 -public void stopShootPhoto(MessageDown message) { - Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(CameraKey. - KeyConnection, ComponentIndexType.PORT_1)); - if (isConnect != null && isConnect && getGimbalAndCameraEnabled()) { - KeyManager.getInstance().performAction(KeyTools.createKey(CameraKey.KeyStopShootPhoto, - ComponentIndexType.PORT_1), new CommonCallbacks.CompletionCallbackWithParam() { - @Override - public void onSuccess(EmptyMsg emptyMsg) { - sendMsg2Server(message); - } - - @Override - public void onFailure(@NonNull IDJIError error) { - LogUtil.log(TAG, "停止拍照失败:" + new Gson().toJson(error)); - sendFailMsg2Server(message, "停止拍照失败:" + getIDJIErrorMsg(error)); - } - }); - } else { - sendFailMsg2Server(message, "当前状态相机禁止操作"); - } -} - - -//开始录像 -public void startRecordVideo(MessageDown message) { - Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(CameraKey. - KeyConnection, ComponentIndexType.PORT_1)); - if (isConnect != null && isConnect && getGimbalAndCameraEnabled()) { - KeyManager.getInstance().performAction(KeyTools.createKey(CameraKey.KeyStartRecord, - ComponentIndexType.PORT_1), new CommonCallbacks.CompletionCallbackWithParam() { - @Override - public void onSuccess(EmptyMsg emptyMsg) { - sendMsg2Server(message); - } - - @Override - public void onFailure(@NonNull IDJIError error) { - sendFailMsg2Server(message, "开始录像失败:" + getIDJIErrorMsg(error)); - } - }); - } else { - sendFailMsg2Server(message, "当前状态相机禁止操作"); - } -} - -//停止录像 -public void stopRecordVideo(MessageDown message) { - Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(CameraKey. - KeyConnection, ComponentIndexType.PORT_1)); - if (isConnect != null && isConnect) { - KeyManager.getInstance().performAction(KeyTools.createKey(CameraKey.KeyStopRecord, - ComponentIndexType.PORT_1), new CommonCallbacks.CompletionCallbackWithParam() { - @Override - public void onSuccess(EmptyMsg emptyMsg) { - LogUtil.log(TAG, "停止录像成功"); - sendMsg2Server(message); - } - - @Override - public void onFailure(@NonNull IDJIError error) { - sendFailMsg2Server(message, "停止录像失败:" + getIDJIErrorMsg(error)); - } - }); - } else { - sendFailMsg2Server(message, "当前状态相机禁止操作"); - } -} - - -// 设置变焦倍率 -public void setCameraZoomRatios(MessageDown message) { - Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(CameraKey. - KeyConnection, ComponentIndexType.PORT_1)); - if (isConnect == null || !isConnect || !getGimbalAndCameraEnabled()) { - sendFailMsg2Server(message, "当前状态相机禁止操作"); - return; } - if (message == null) return; - - String cameraType = message.getData().getCamera_type(); - double zoomFactor = message.getData().getZoom_factor(); - - // 检查是否有红外(H30T) - CameraType cameraTypeEnum = KeyManager.getInstance().getValue( - KeyTools.createKey(CameraKey.KeyCameraType, ComponentIndexType.PORT_1)); - boolean hasThermal = (cameraTypeEnum == CameraType.ZENMUSE_H30T); - - // 1. 映射视频流类型和镜头类型 - CameraVideoStreamSourceType streamSource; - CameraLensType lensType; - double minZoom, maxZoom; - final boolean isWide; - final boolean isIr; - - switch (cameraType) { - case "ir": - if (!hasThermal) { - sendFailMsg2Server(message, "当前负载无红外功能,仅H30T支持"); - return; - } - streamSource = CameraVideoStreamSourceType.INFRARED_CAMERA; - lensType = CameraLensType.CAMERA_LENS_THERMAL; - minZoom = 2; - maxZoom = 20; // 红外 2-20倍 - isWide = false; - isIr = true; - break; - case "wide": - streamSource = CameraVideoStreamSourceType.WIDE_CAMERA; - lensType = CameraLensType.CAMERA_LENS_WIDE; - minZoom = 1; - maxZoom = 1; - isWide = true; - isIr = false; - break; - case "zoom": - streamSource = CameraVideoStreamSourceType.ZOOM_CAMERA; - lensType = CameraLensType.CAMERA_LENS_ZOOM; - minZoom = 2; - maxZoom = 200; - isWide = false; - isIr = false; - break; - default: - streamSource = CameraVideoStreamSourceType.DEFAULT_CAMERA; - lensType = CameraLensType.CAMERA_LENS_ZOOM; - minZoom = 2; - maxZoom = 200; - isWide = false; - isIr = false; - break; + private CameraLensType parseLensType1(String cameraType) { + if (cameraType == null) return null; + if ("ir".equals(cameraType)) { + return CameraLensType.CAMERA_LENS_THERMAL; + } else if ("wide".equals(cameraType)) { + return CameraLensType.CAMERA_LENS_ZOOM; + } else if ("zoom".equals(cameraType)) { + return CameraLensType.CAMERA_LENS_ZOOM; + } + return null; } - // 2. 切换视频流 - final double finalMinZoom = minZoom; - final double finalMaxZoom = maxZoom; - KeyManager.getInstance().setValue( - KeyTools.createKey(CameraKey.KeyCameraVideoStreamSource, ComponentIndexType.PORT_1), - streamSource, - new CommonCallbacks.CompletionCallback() { - @Override - public void onSuccess() { - // 广角不设置变焦 - if (isWide) { - LogUtil.log(TAG, "广角切换成功,无需设置变焦"); - Movement.getInstance().setZoom_factor(1); - sendMsg2Server(message); - return; + private void camera_frame_zoom_and_bianjiao(MessageDown message, CameraLensType type) { + ZoomTargetPointInfo info = new ZoomTargetPointInfo(); + info.setX(Double.valueOf(message.getData().getX())); + info.setY(Double.valueOf(message.getData().getY())); + info.setTapZoomModeEnable(true); + + double width = message.getData().getWidth(); + double height = message.getData().getHeight(); + + double zoomRatio = calculateZoomRatio(width, height); + + //没有对lock判断 + info.setMode(TapZoomMode.GIMBAL_FOLLOW); // 或 TAP_ZOOM模式,看需求 + + KeyManager.getInstance().performAction( + KeyTools.createCameraKey(CameraKey.KeyTapZoomAtTarget, + ComponentIndexType.PORT_1, type), + info, + new CommonCallbacks.CompletionCallbackWithParam() { + @Override + public void onSuccess(EmptyMsg emptyMsg) { + //开始变焦 + KeyManager.getInstance().setValue(KeyTools.createCameraKey(CameraKey.KeyCameraZoomRatios, + ComponentIndexType.PORT_1, type), + Double.valueOf(zoomRatio), new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + LogUtil.log(TAG, "变焦成功"); + sendMsg2Server(message); + } + + @Override + public void onFailure(@NonNull IDJIError idjiError) { + sendFailMsg2Server(message, "变焦失败:" + getIDJIErrorMsg(idjiError)); + } + }); } - // 强制截断变焦范围 - final double validZoom = Math.max(finalMinZoom, Math.min(finalMaxZoom, zoomFactor)); + @Override + public void onFailure(@NonNull IDJIError error) { + sendFailMsg2Server(message, "aim操作失败:" + getIDJIErrorMsg(error)); + } + }); + } - new Handler(Looper.getMainLooper()).postDelayed(() -> { - if (isIr) { - KeyManager.getInstance().setValue( - KeyTools.createCameraKey(CameraKey.KeyThermalZoomRatios, - ComponentIndexType.PORT_1, lensType), - validZoom, - new CommonCallbacks.CompletionCallback() { - @Override - public void onSuccess() { - LogUtil.log(TAG, "红外变焦成功: " + validZoom); - Movement.getInstance().setZoom_factor((int) validZoom); - sendMsg2Server(message); - } + //设置变焦倍率 + public static double calculateZoomRatio(double width, double height) { + // 防呆:如果传入 0 或负数,返回 1 倍(不 zoom) + if (width <= 0 || height <= 0) { + return 1.0; + } - @Override - public void onFailure(@NonNull IDJIError error) { - sendFailMsg2Server(message, "红外变焦失败:" + getIDJIErrorMsg(error)); - } - } - ); - } else { - // 可见光变焦 - KeyManager.getInstance().setValue( - KeyTools.createCameraKey(CameraKey.KeyCameraZoomRatios, - ComponentIndexType.PORT_1, lensType), - validZoom, - new CommonCallbacks.CompletionCallback() { - @Override - public void onSuccess() { - LogUtil.log(TAG, "变焦成功: " + cameraType + "=" + validZoom); - Movement.getInstance().setZoom_factor((int) validZoom); - sendMsg2Server(message); - } + // 取宽高中的大值(保证框能装下) + double maxDimension = Math.max(width, height); - @Override - public void onFailure(@NonNull IDJIError error) { - sendFailMsg2Server(message, "设置变焦倍率失败:" + getIDJIErrorMsg(error)); - } - } - ); + // 反比计算:框越小,zoom 越大 + // 例:max=1.0(全画面)→ zoom=1.0 + // max=0.5(半屏) → zoom=2.0 + // max=0.005(很小) → zoom=200.0 + double zoom = 1.0 / maxDimension; + + // 限制在你的相机范围内 1x ~ 200x + return Math.max(1.0, Math.min(200.0, zoom)); + + } + + //开始拍照 + public void startShootPhoto(MessageDown message) { + Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(CameraKey. + KeyConnection, ComponentIndexType.PORT_1)); + + if (isConnect != null && isConnect && getGimbalAndCameraEnabled()) { + // 判断当前是否是全景模式 (mode 3) + if (Movement.getInstance().getCamera_mode() == 3) { + + String missionExecuteState = Movement.getInstance().getWaypointMissionExecuteState(); + LogUtil.log(TAG, "全景拍照前检查航线状态:" + missionExecuteState); + if ("EXECUTING".equals(missionExecuteState) || "INTERRUPTED".equals(missionExecuteState)) { + LogUtil.log(TAG, "航线正在执行或暂停,先退出航线"); + IWaypointMissionManager missionManager = WaypointMissionManager.getInstance(); + missionManager.stopMission(PreferenceUtils.getInstance().getWaylinename(), new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + LogUtil.log(TAG, "航线退出成功,等待 2 秒让相机控制权释放"); + // 等待航线退出后,延迟 2 秒再设置全景模式并拍照 + new Handler().postDelayed(() -> { + KeyManager.getInstance().setValue(KeyTools.createKey(CameraKey.KeyCameraMode, ComponentIndexType.PORT_1), + CameraMode.find(12), + new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + Movement.getInstance().setCamera_mode(3); + LogUtil.log(TAG, "切换全景模式成功,等待 500ms 后拍照"); + // 再等待 500ms 让相机模式稳定 + new Handler().postDelayed(() -> { + KeyManager.getInstance().performAction(KeyTools.createKey(CameraKey.KeyStartShootPhoto, + ComponentIndexType.PORT_1), + new CommonCallbacks.CompletionCallbackWithParam() { + @Override + public void onSuccess(EmptyMsg emptyMsg) { + LogUtil.log(TAG, "拍照成功"); + sendMsg2Server(message); + } + + @Override + public void onFailure(@NonNull IDJIError error) { + LogUtil.log(TAG, "拍照失败:" + new Gson().toJson(error)); + sendFailMsg2Server(message, "拍照失败:" + getIDJIErrorMsg(error)); + } + }); + }, 500); + } + + @Override + public void onFailure(@NonNull IDJIError error) { + LogUtil.log(TAG, "切换全景模式失败:" + new Gson().toJson(error)); + sendFailMsg2Server(message, "切换全景模式失败:" + getIDJIErrorMsg(error)); + } + }); + }, 2000); } - }, 200); + + @Override + public void onFailure(@NonNull IDJIError idjiError) { + LogUtil.log(TAG, "退出航线失败:" + new Gson().toJson(idjiError)); + // 退出失败也直接设置全景模式拍照 + new Handler().postDelayed(() -> { + KeyManager.getInstance().setValue(KeyTools.createKey(CameraKey.KeyCameraMode, ComponentIndexType.PORT_1), + CameraMode.find(12), + new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + Movement.getInstance().setCamera_mode(3); + KeyManager.getInstance().performAction(KeyTools.createKey(CameraKey.KeyStartShootPhoto, + ComponentIndexType.PORT_1), + new CommonCallbacks.CompletionCallbackWithParam() { + @Override + public void onSuccess(EmptyMsg emptyMsg) { + LogUtil.log(TAG, "拍照成功"); + sendMsg2Server(message); + } + + @Override + public void onFailure(@NonNull IDJIError error) { + LogUtil.log(TAG, "拍照失败:" + new Gson().toJson(error)); + sendFailMsg2Server(message, "拍照失败:" + getIDJIErrorMsg(error)); + } + }); + } + + @Override + public void onFailure(@NonNull IDJIError error) { + LogUtil.log(TAG, "退出拍照失败"); + } + }); + }, 2000); + } + }); + + } else { + // 没有航线执行,先读取相机实际模式 + CameraMode currentMode = KeyManager.getInstance().getValue( + KeyTools.createKey(CameraKey.KeyCameraMode, ComponentIndexType.PORT_1)); + LogUtil.log(TAG, "当前相机模式:" + currentMode); + + if (currentMode == CameraMode.PHOTO_PANORAMA) { + // 已经是全景模式,等待 500ms 让相机稳定后拍照 + LogUtil.log(TAG, "已是全景模式,等待 500ms 后拍照"); + new Handler().postDelayed(() -> { + KeyManager.getInstance().performAction(KeyTools.createKey(CameraKey.KeyStartShootPhoto, + ComponentIndexType.PORT_1), + new CommonCallbacks.CompletionCallbackWithParam() { + @Override + public void onSuccess(EmptyMsg emptyMsg) { + LogUtil.log(TAG, "拍照成功"); + sendMsg2Server(message); + } + + @Override + public void onFailure(@NonNull IDJIError error) { + LogUtil.log(TAG, "拍照失败:" + new Gson().toJson(error)); + sendFailMsg2Server(message, "拍照失败:" + getIDJIErrorMsg(error)); + } + }); + }, 500); + } else { + // 不是全景模式,先切换 + KeyManager.getInstance().setValue(KeyTools.createKey(CameraKey.KeyCameraMode, ComponentIndexType.PORT_1), + CameraMode.PHOTO_PANORAMA, + new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + Movement.getInstance().setCamera_mode(3); + LogUtil.log(TAG, "切换成功" + Movement.getInstance().getCamera_mode()); + // 切换成功后等待 500ms 再拍照 + new Handler().postDelayed(() -> { + KeyManager.getInstance().performAction(KeyTools.createKey(CameraKey.KeyStartShootPhoto, + ComponentIndexType.PORT_1), + new CommonCallbacks.CompletionCallbackWithParam() { + @Override + public void onSuccess(EmptyMsg emptyMsg) { + LogUtil.log(TAG, "拍照成功"); + sendMsg2Server(message); + } + + @Override + public void onFailure(@NonNull IDJIError error) { + LogUtil.log(TAG, "拍照失败:" + new Gson().toJson(error)); + sendFailMsg2Server(message, "拍照失败:" + getIDJIErrorMsg(error)); + } + }); + }, 500); + } + + @Override + public void onFailure(@NonNull IDJIError error) { + LogUtil.log(TAG, "切换全景模式失败:" + new Gson().toJson(error)); + sendFailMsg2Server(message, "切换全景模式失败:" + getIDJIErrorMsg(error)); + } + }); + } + } + + } else { + // 普通拍照模式:使用 KeyStartShootPhoto + KeyManager.getInstance().performAction(KeyTools.createKey(CameraKey.KeyStartShootPhoto, + ComponentIndexType.PORT_1), + new CommonCallbacks.CompletionCallbackWithParam() { + @Override + public void onSuccess(EmptyMsg emptyMsg) { + LogUtil.log(TAG, "拍照成功"); + sendMsg2Server(message); + } + + @Override + public void onFailure(@NonNull IDJIError error) { + LogUtil.log(TAG, "拍照失败:" + new Gson().toJson(error)); + sendFailMsg2Server(message, "拍照失败:" + getIDJIErrorMsg(error)); + } + }); + } + } else { + sendFailMsg2Server(message, "当前状态相机禁止操作"); + } + } + + + //结束拍照 + public void stopShootPhoto(MessageDown message) { + Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(CameraKey. + KeyConnection, ComponentIndexType.PORT_1)); + if (isConnect != null && isConnect && getGimbalAndCameraEnabled()) { + KeyManager.getInstance().performAction(KeyTools.createKey(CameraKey.KeyStopShootPhoto, + ComponentIndexType.PORT_1), new CommonCallbacks.CompletionCallbackWithParam() { + @Override + public void onSuccess(EmptyMsg emptyMsg) { + sendMsg2Server(message); } @Override public void onFailure(@NonNull IDJIError error) { - sendFailMsg2Server(message, "切换相机视频流失败:" + getIDJIErrorMsg(error)); + LogUtil.log(TAG, "停止拍照失败:" + new Gson().toJson(error)); + sendFailMsg2Server(message, "停止拍照失败:" + getIDJIErrorMsg(error)); } + }); + } else { + sendFailMsg2Server(message, "当前状态相机禁止操作"); + } + } + + + //开始录像 + public void startRecordVideo(MessageDown message) { + Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(CameraKey. + KeyConnection, ComponentIndexType.PORT_1)); + if (isConnect != null && isConnect && getGimbalAndCameraEnabled()) { + // 检查当前相机模式,确保在录像模式 + CameraMode currentCameraMode = KeyManager.getInstance().getValue( + KeyTools.createKey(CameraKey.KeyCameraMode, ComponentIndexType.PORT_1)); + +// new Handler().postDelayed(() -> { +// KeyManager.getInstance().setValue( +// KeyTools.createKey(CameraKey.KeyCameraMode, ComponentIndexType.PORT_1), +// CameraMode.VIDEO_NORMAL, new CommonCallbacks.CompletionCallback() { +// @Override +// public void onSuccess() { +// } +// @Override +// public void onFailure(@NonNull IDJIError idjiError) { +// } +// }); +// },500); + + + if (currentCameraMode != CameraMode.VIDEO_NORMAL) { + // 不在录像模式,先切换到录像模式 + LogUtil.log(TAG, "相机模式不在录像模式,先切换模式"); + KeyManager.getInstance().setValue( + KeyTools.createKey(CameraKey.KeyCameraMode, ComponentIndexType.PORT_1), + CameraMode.VIDEO_NORMAL, + new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + LogUtil.log(TAG, "切换到录像模式成功,开始录像"); + + new Handler().postDelayed(() -> { + doStartRecord(message); + }, 500); + + } + + @Override + public void onFailure(@NonNull IDJIError error) { + LogUtil.log(TAG, "切换到录像模式失败:" + new Gson().toJson(error)); + sendFailMsg2Server(message, "切换录像模式失败:" + getIDJIErrorMsg(error)); + } + }); + } else { + // 已经在录像模式,直接录像 + doStartRecord(message); } - ); -} + } else { + sendFailMsg2Server(message, "当前状态相机禁止操作"); + } + } + + // 执行录像的私有方法 + private void doStartRecord(MessageDown message) { + KeyManager.getInstance().performAction(KeyTools.createKey(CameraKey.KeyStartRecord, + ComponentIndexType.PORT_1), new CommonCallbacks.CompletionCallbackWithParam() { + @Override + public void onSuccess(EmptyMsg emptyMsg) { + + LogUtil.log(TAG, "开始录像成功"); + sendMsg2Server(message); + } + + @Override + public void onFailure(@NonNull IDJIError error) { + LogUtil.log(TAG, "开始录像失败:" + new Gson().toJson(error)); + sendFailMsg2Server(message, "开始录像失败:" + getIDJIErrorMsg(error)); + } + }); + } + + //停止录像 + public void stopRecordVideo(MessageDown message) { + Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(CameraKey. + KeyConnection, ComponentIndexType.PORT_1)); + if (isConnect != null && isConnect) { + KeyManager.getInstance().performAction(KeyTools.createKey(CameraKey.KeyStopRecord, + ComponentIndexType.PORT_1), new CommonCallbacks.CompletionCallbackWithParam() { + @Override + public void onSuccess(EmptyMsg emptyMsg) { + LogUtil.log(TAG, "停止录像成功"); + sendMsg2Server(message); + } + + @Override + public void onFailure(@NonNull IDJIError error) { + sendFailMsg2Server(message, "停止录像失败:" + getIDJIErrorMsg(error)); + } + }); + } else { + sendFailMsg2Server(message, "当前状态相机禁止操作"); + } + } + + + // 设置变焦倍率 + public void setCameraZoomRatios(MessageDown message) { + Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(CameraKey. + KeyConnection, ComponentIndexType.PORT_1)); + if (isConnect == null || !isConnect || !getGimbalAndCameraEnabled()) { + sendFailMsg2Server(message, "当前状态相机禁止操作"); + return; + } + + if (message == null) return; + + String cameraType = message.getData().getCamera_type(); + double zoomFactor = message.getData().getZoom_factor(); + + // 检查是否有红外(H30T) + CameraType cameraTypeEnum = KeyManager.getInstance().getValue( + KeyTools.createKey(CameraKey.KeyCameraType, ComponentIndexType.PORT_1)); + boolean hasThermal = (cameraTypeEnum == CameraType.ZENMUSE_H30T); + + // 1. 映射视频流类型和镜头类型 + CameraVideoStreamSourceType streamSource; + CameraLensType lensType; + double minZoom, maxZoom; + final boolean isWide; + final boolean isIr; + + switch (cameraType) { + case "ir": + if (!hasThermal) { + sendFailMsg2Server(message, "当前负载无红外功能,仅H30T支持"); + return; + } + streamSource = CameraVideoStreamSourceType.INFRARED_CAMERA; + lensType = CameraLensType.CAMERA_LENS_THERMAL; + minZoom = 2; + maxZoom = 20; // 红外 2-20倍 + isWide = false; + isIr = true; + break; + case "wide": + streamSource = CameraVideoStreamSourceType.WIDE_CAMERA; + lensType = CameraLensType.CAMERA_LENS_WIDE; + minZoom = 1; + maxZoom = 1; + isWide = true; + isIr = false; + break; + case "zoom": + streamSource = CameraVideoStreamSourceType.ZOOM_CAMERA; + lensType = CameraLensType.CAMERA_LENS_ZOOM; + minZoom = 2; + maxZoom = 200; + isWide = false; + isIr = false; + break; + default: + streamSource = CameraVideoStreamSourceType.DEFAULT_CAMERA; + lensType = CameraLensType.CAMERA_LENS_ZOOM; + minZoom = 2; + maxZoom = 200; + isWide = false; + isIr = false; + break; + } + + // 2. 切换视频流 + final double finalMinZoom = minZoom; + final double finalMaxZoom = maxZoom; + + KeyManager.getInstance().setValue( + KeyTools.createKey(CameraKey.KeyCameraVideoStreamSource, ComponentIndexType.PORT_1), + streamSource, + new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + // 广角不设置变焦 + if (isWide) { + LogUtil.log(TAG, "广角切换成功,无需设置变焦"); + Movement.getInstance().setZoom_factor(1); + sendMsg2Server(message); + return; + } + + // 强制截断变焦范围 + final double validZoom = Math.max(finalMinZoom, Math.min(finalMaxZoom, zoomFactor)); + + new Handler(Looper.getMainLooper()).postDelayed(() -> { + if (isIr) { + KeyManager.getInstance().setValue( + KeyTools.createCameraKey(CameraKey.KeyThermalZoomRatios, + ComponentIndexType.PORT_1, lensType), + validZoom, + new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + LogUtil.log(TAG, "红外变焦成功: " + validZoom); + Movement.getInstance().setZoom_factor((int) validZoom); + sendMsg2Server(message); + } + + @Override + public void onFailure(@NonNull IDJIError error) { + sendFailMsg2Server(message, "红外变焦失败:" + getIDJIErrorMsg(error)); + } + } + ); + } else { + // 可见光变焦 + KeyManager.getInstance().setValue( + KeyTools.createCameraKey(CameraKey.KeyCameraZoomRatios, + ComponentIndexType.PORT_1, lensType), + validZoom, + new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + LogUtil.log(TAG, "变焦成功: " + cameraType + "=" + validZoom); + Movement.getInstance().setZoom_factor((int) validZoom); + sendMsg2Server(message); + } + + @Override + public void onFailure(@NonNull IDJIError error) { + sendFailMsg2Server(message, "设置变焦倍率失败:" + getIDJIErrorMsg(error)); + } + } + ); + } + }, 200); + } + + @Override + public void onFailure(@NonNull IDJIError error) { + sendFailMsg2Server(message, "切换相机视频流失败:" + getIDJIErrorMsg(error)); + } + } + ); + } // private void setstepThermalZoomRatios(){ // KeyManager.getInstance().setValue( @@ -1098,42 +1374,42 @@ public void setCameraZoomRatios(MessageDown message) { // } // } -//切换广角变焦红外 -public void setCameraVideoStreamSource(MessageDown message) { - Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(CameraKey. - KeyConnection, ComponentIndexType.PORT_1)); - if (isConnect != null && isConnect && getGimbalAndCameraEnabled()) { - if (message != null) { - int type = 1; - switch (message.getData().getVideo_type()) { - case "ir": - type = 3; - break; - case "normal": - type = 0; - break; - case "wide": - type = 1; - break; - case "zoom": - type = 2; - break; - } + //切换广角变焦红外 + public void setCameraVideoStreamSource(MessageDown message) { + Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(CameraKey. + KeyConnection, ComponentIndexType.PORT_1)); + if (isConnect != null && isConnect && getGimbalAndCameraEnabled()) { + if (message != null) { + int type = 1; + switch (message.getData().getVideo_type()) { + case "ir": + type = 3; + break; + case "normal": + type = 0; + break; + case "wide": + type = 1; + break; + case "zoom": + type = 2; + break; + } - KeyManager.getInstance().setValue(KeyTools.createKey(CameraKey.KeyCameraVideoStreamSource, - ComponentIndexType.PORT_1) - , CameraVideoStreamSourceType.find(type), - new CommonCallbacks.CompletionCallback() { - @Override - public void onSuccess() { - sendMsg2Server(message); - } + KeyManager.getInstance().setValue(KeyTools.createKey(CameraKey.KeyCameraVideoStreamSource, + ComponentIndexType.PORT_1) + , CameraVideoStreamSourceType.find(type), + new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + sendMsg2Server(message); + } - @Override - public void onFailure(@NonNull IDJIError error) { - sendFailMsg2Server(message, "切换相机视频流失败:" + getIDJIErrorMsg(error)); - } - }); + @Override + public void onFailure(@NonNull IDJIError error) { + sendFailMsg2Server(message, "切换相机视频流失败:" + getIDJIErrorMsg(error)); + } + }); // if (type == 3) { // KeyManager.getInstance().setValue(KeyTools.createCameraKey(CameraKey.KeyThermalDisplayMode, // ComponentIndexType.PORT_1, @@ -1151,12 +1427,12 @@ public void setCameraVideoStreamSource(MessageDown message) { // } // }); // } + } + } else { + sendFailMsg2Server(message, "当前状态相机禁止操作"); } - } else { - sendFailMsg2Server(message, "当前状态相机禁止操作"); - } -} + } // //设置红外镜头的显示模式 // public void setThermalDisplayMode(MQMessage message) { @@ -1211,7 +1487,7 @@ public void setCameraVideoStreamSource(MessageDown message) { // // -/// /设置对焦模式 + /// /设置对焦模式 //public void setCameraFocusMode(MQMessage message) { // Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(CameraKey. // KeyConnection,ComponentIndexType.PORT_1)); @@ -1240,34 +1516,34 @@ public void setCameraVideoStreamSource(MessageDown message) { //} // //格式化SD卡 -public void formatStorage(MessageDown message) { - Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(CameraKey. - KeyConnection, ComponentIndexType.PORT_1)); - if (isConnect != null && isConnect && getGimbalAndCameraEnabled()) { - KeyManager.getInstance().performAction(KeyTools.createKey(CameraKey.KeyFormatStorage, ComponentIndexType.PORT_1), CameraStorageLocation.SDCARD, new CommonCallbacks.CompletionCallbackWithParam() { - @Override - public void onSuccess(EmptyMsg emptyMsg) { - if (message != null) { - sendMsg2Server(message); + public void formatStorage(MessageDown message) { + Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(CameraKey. + KeyConnection, ComponentIndexType.PORT_1)); + if (isConnect != null && isConnect && getGimbalAndCameraEnabled()) { + KeyManager.getInstance().performAction(KeyTools.createKey(CameraKey.KeyFormatStorage, ComponentIndexType.PORT_1), CameraStorageLocation.SDCARD, new CommonCallbacks.CompletionCallbackWithParam() { + @Override + public void onSuccess(EmptyMsg emptyMsg) { + if (message != null) { + sendMsg2Server(message); + } + LogUtil.log(TAG, "sd卡已格式化"); } - LogUtil.log(TAG, "sd卡已格式化"); - } - @Override - public void onFailure(@NonNull IDJIError error) { - if (message != null) { - sendFailMsg2Server(message, "SD卡格式化失败:" + getIDJIErrorMsg(error)); + @Override + public void onFailure(@NonNull IDJIError error) { + if (message != null) { + sendFailMsg2Server(message, "SD卡格式化失败:" + getIDJIErrorMsg(error)); + } + LogUtil.log(TAG, "sd卡格式化失败:" + new Gson().toJson(error)); } - LogUtil.log(TAG, "sd卡格式化失败:" + new Gson().toJson(error)); + }); + } else { + if (message != null) { + sendFailMsg2Server(message, "当前状态相机禁止操作"); } - }); - } else { - if (message != null) { - sendFailMsg2Server(message, "当前状态相机禁止操作"); + LogUtil.log(TAG, "当前状态相机禁止操作"); + } - LogUtil.log(TAG, "当前状态相机禁止操作"); - - } // // } //// @@ -1345,105 +1621,107 @@ public void formatStorage(MessageDown message) { // } //} // -} - -//指点对焦 -public void tapZoomAtTarget(MessageDown message) { - Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey( - CameraKey.KeyConnection, ComponentIndexType.PORT_1)); - // - LogUtil.log(TAG, "双击回中" + message.toString()); - if (isConnect == null || !isConnect || !getGimbalAndCameraEnabled()) { - LogUtil.log(TAG, "指点对焦失败:相机未连接或禁止操作"); - return; } - CameraLensType type = parseLensType(message.getData().getCamera_type()); - if (type == null) { - sendFailMsg2Server(message, "不支持的相机类型"); - return; + //指点对焦 + public void tapZoomAtTarget(MessageDown message) { + Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey( + CameraKey.KeyConnection, ComponentIndexType.PORT_1)); + // + LogUtil.log(TAG, "双击回中" + message.toString()); + if (isConnect == null || !isConnect || !getGimbalAndCameraEnabled()) { + LogUtil.log(TAG, "指点对焦失败:相机未连接或禁止操作"); + return; + } + + + CameraLensType type = parseLensType(message.getData().getCamera_type()); + if (type == null) { + sendFailMsg2Server(message, "不支持的相机类型"); + return; + } + + KeyManager.getInstance().setValue( + KeyTools.createCameraKey(CameraKey.KeyTapZoomEnable, + ComponentIndexType.PORT_1, type), + true, + new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + LogUtil.log(TAG, "设置使能指点成功"); + performTapZoom(message, type); + } + + @Override + public void onFailure(@NonNull IDJIError error) { + LogUtil.log(TAG, "设置使能指点失败:" + new Gson().toJson(error)); + sendFailMsg2Server(message, "设置使能指点失败:" + getIDJIErrorMsg(error)); + } + }); } - KeyManager.getInstance().setValue( - KeyTools.createCameraKey(CameraKey.KeyTapZoomEnable, - ComponentIndexType.PORT_1, type), - true, - new CommonCallbacks.CompletionCallback() { + private void performTapZoom(MessageDown message, CameraLensType type) { + ZoomTargetPointInfo info = new ZoomTargetPointInfo(); + info.setX(Double.valueOf(message.getData().getX())); + info.setY(Double.valueOf(message.getData().getY())); + +// info.setTapZoomModeEnable(true); +// //没有对lock判断 +// info.setMode(TapZoomMode.GIMBAL_FOLLOW); // 或 TAP_ZOOM模式,看需求 + + KeyManager.getInstance().performAction( + KeyTools.createCameraKey(CameraKey.KeyTapZoomAtTarget, + ComponentIndexType.PORT_1, type), + info, + new CommonCallbacks.CompletionCallbackWithParam() { + @Override + public void onSuccess(EmptyMsg emptyMsg) { + sendMsg2Server(message); + } + + @Override + public void onFailure(@NonNull IDJIError error) { + sendFailMsg2Server(message, "aim失败:" + getIDJIErrorMsg(error)); + } + }); + } + + private CameraLensType parseLensType(String cameraType) { + if (cameraType == null) return null; + if ("ir".equals(cameraType)) { + return CameraLensType.CAMERA_LENS_THERMAL; + } else if ("wide".equals(cameraType)) { + return CameraLensType.CAMERA_LENS_ZOOM; + } else if ("zoom".equals(cameraType)) { + return CameraLensType.CAMERA_LENS_ZOOM; + } + return null; + } + + + //切换为广角镜头,降低曝光率 + public void resumeLensToWideISOManual() { + Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(CameraKey. + KeyConnection, ComponentIndexType.PORT_1)); + if (isConnect != null && isConnect) { + //切换成广角镜头 + KeyManager.getInstance().setValue(KeyTools.createKey(CameraKey.KeyCameraVideoStreamSource, + ComponentIndexType.PORT_1), CameraVideoStreamSourceType.WIDE_CAMERA, new CommonCallbacks.CompletionCallback() { @Override public void onSuccess() { - LogUtil.log(TAG, "设置使能指点成功"); - performTapZoom(message, type); + LogUtil.log(TAG, "返航时将镜头切为广角"); } @Override public void onFailure(@NonNull IDJIError error) { - LogUtil.log(TAG, "设置使能指点失败:" + new Gson().toJson(error)); - sendFailMsg2Server(message, "设置使能指点失败:" + getIDJIErrorMsg(error)); + LogUtil.log(TAG, "返航切换广角失败:" + new Gson().toJson(error)); } }); -} -private void performTapZoom(MessageDown message, CameraLensType type) { - ZoomTargetPointInfo info = new ZoomTargetPointInfo(); - info.setX(Double.valueOf(message.getData().getX())); - info.setY(Double.valueOf(message.getData().getY())); - info.setTapZoomModeEnable(true); - //没有对lock判断 - info.setMode(TapZoomMode.GIMBAL_FOLLOW); // 或 TAP_ZOOM模式,看需求 - - KeyManager.getInstance().performAction( - KeyTools.createCameraKey(CameraKey.KeyTapZoomAtTarget, - ComponentIndexType.PORT_1, type), - info, - new CommonCallbacks.CompletionCallbackWithParam() { - @Override - public void onSuccess(EmptyMsg emptyMsg) { - sendMsg2Server(message); - } - - @Override - public void onFailure(@NonNull IDJIError error) { - sendFailMsg2Server(message, "指点变焦失败:" + getIDJIErrorMsg(error)); - } - }); -} - -private CameraLensType parseLensType(String cameraType) { - if (cameraType == null) return null; - if ("ir".equals(cameraType)) { - return CameraLensType.CAMERA_LENS_THERMAL; - } else if ("wide".equals(cameraType)) { - return CameraLensType.CAMERA_LENS_WIDE; - } else if ("zoom".equals(cameraType)) { - return CameraLensType.CAMERA_LENS_ZOOM; + } else { + LogUtil.log(TAG, "降落切换广角失败:当前状态相机禁止操作"); + } } - return null; -} - - -//切换为广角镜头,降低曝光率 -public void resumeLensToWideISOManual() { - Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(CameraKey. - KeyConnection, ComponentIndexType.PORT_1)); - if (isConnect != null && isConnect) { - //切换成广角镜头 - KeyManager.getInstance().setValue(KeyTools.createKey(CameraKey.KeyCameraVideoStreamSource, - ComponentIndexType.PORT_1), CameraVideoStreamSourceType.WIDE_CAMERA, new CommonCallbacks.CompletionCallback() { - @Override - public void onSuccess() { - LogUtil.log(TAG, "返航时将镜头切为广角"); - } - - @Override - public void onFailure(@NonNull IDJIError error) { - LogUtil.log(TAG, "返航切换广角失败:" + new Gson().toJson(error)); - } - }); - - } else { - LogUtil.log(TAG, "降落切换广角失败:当前状态相机禁止操作"); - } -} // //设置自定义文件后缀 // public void setCustomExpandNameSetting() { diff --git a/app/src/main/java/com/aros/apron/manager/DockCloseManager.java b/app/src/main/java/com/aros/apron/manager/DockCloseManager.java index 352df1a5..e84371b9 100644 --- a/app/src/main/java/com/aros/apron/manager/DockCloseManager.java +++ b/app/src/main/java/com/aros/apron/manager/DockCloseManager.java @@ -25,6 +25,12 @@ public class DockCloseManager extends BaseManager { private final int maxRetries = 2; private int sendDockCloseSuccessTimes; private boolean isSendDockCloseSuccess; + // 是否允许继续重试(开门后设为false,防止关门重试把已开的门又关了) + private volatile boolean allowRetry = true; + + public void stopRetry() { + allowRetry = false; + } private DockCloseManager() { } @@ -88,6 +94,10 @@ public class DockCloseManager extends BaseManager { final Handler mainHandler = new Handler(Looper.getMainLooper()); private void retrySend() { + if (!allowRetry) { + LogUtil.log(TAG, "已取消关门重试(门已打开)"); + return; + } sendDockCloseSuccessTimes++; if (sendDockCloseSuccessTimes < maxRetries) { mainHandler.postDelayed(() -> sendDockCloseMsg2Server(), 2000); @@ -97,6 +107,10 @@ public class DockCloseManager extends BaseManager { } private void handleNotConnected() { + if (!allowRetry) { + LogUtil.log(TAG, "已取消关门重试(门已打开)"); + return; + } if (!isSendDockCloseSuccess && sendDockCloseSuccessTimes < maxRetries) { sendDockCloseSuccessTimes++; mainHandler.postDelayed(() -> sendDockCloseMsg2Server(), 2000); diff --git a/app/src/main/java/com/aros/apron/manager/FlightManager.java b/app/src/main/java/com/aros/apron/manager/FlightManager.java index ff96c110..6a0cb38a 100644 --- a/app/src/main/java/com/aros/apron/manager/FlightManager.java +++ b/app/src/main/java/com/aros/apron/manager/FlightManager.java @@ -37,6 +37,7 @@ import java.util.Objects; import dji.sdk.keyvalue.key.AirLinkKey; import dji.sdk.keyvalue.key.CameraKey; import dji.sdk.keyvalue.key.FlightControllerKey; +import dji.sdk.keyvalue.key.GimbalKey; import dji.sdk.keyvalue.key.KeyTools; import dji.sdk.keyvalue.key.ProductKey; import dji.sdk.keyvalue.key.RtkMobileStationKey; @@ -62,6 +63,7 @@ import dji.sdk.keyvalue.value.flightcontroller.PropellerRotationStatus; import dji.sdk.keyvalue.value.flightcontroller.RemoteControllerFlightMode; import dji.sdk.keyvalue.value.flightcontroller.RidWorkingStatusPushMsg; import dji.sdk.keyvalue.value.flightcontroller.WindDirection; +import dji.sdk.keyvalue.value.gimbal.GimbalMode; import dji.sdk.keyvalue.value.product.ProductType; import dji.sdk.keyvalue.value.rtkmobilestation.RTKTakeoffAltitudeInfo; import dji.v5.common.callback.CommonCallbacks; @@ -131,18 +133,18 @@ public class FlightManager extends BaseManager { LogUploadManager.getInstance().uploadTodayLog(); count++; } - //连上就待机 - MediaDataCenter.getInstance().getCameraStreamManager().setVisionAssistViewDirection(VisionAssistDirection.DOWN, new CommonCallbacks.CompletionCallback() { - @Override - public void onSuccess() { - LogUtil.log(TAG, "设置下视辅助视频成功"); - } - - @Override - public void onFailure(@NonNull IDJIError idjiError) { - LogUtil.log(TAG, "设置下视辅助视频失败"); - } - }); +// //连上就待机 +// MediaDataCenter.getInstance().getCameraStreamManager().setVisionAssistViewDirection(VisionAssistDirection.DOWN, new CommonCallbacks.CompletionCallback() { +// @Override +// public void onSuccess() { +// LogUtil.log(TAG, "设置下视辅助视频成功"); +// } +// +// @Override +// public void onFailure(@NonNull IDJIError idjiError) { +// LogUtil.log(TAG, "设置下视辅助视频失败"); +// } +// }); Movement.getInstance().setMissionFinish(false); Movement.getInstance().setMode_code(0); @@ -490,10 +492,37 @@ public class FlightManager extends BaseManager { //Movement.getInstance().setMode_code(3); break; case AUTO_TAKE_OFF: + +// KeyManager.getInstance().setValue(KeyTools.createKey(GimbalKey.KeyGimbalMode, ComponentIndexType.PORT_1), GimbalMode.YAW_FOLLOW, new CommonCallbacks.CompletionCallback() { +// @Override +// public void onSuccess() { +// LogUtil.log(TAG,"航线云台恢复跟随"); +// } +// +// @Override +// public void onFailure(@NonNull IDJIError idjiError) { +// LogUtil.log(TAG,"航线云台恢复跟随失败"); +// } +// }); + + //我觉得可能会重复设置 //Movement.getInstance().setMode_code(4); break; case WAYPOINT: + +// KeyManager.getInstance().setValue(KeyTools.createKey(GimbalKey.KeyGimbalMode, ComponentIndexType.PORT_1), GimbalMode.YAW_FOLLOW, new CommonCallbacks.CompletionCallback() { +// @Override +// public void onSuccess() { +// LogUtil.log(TAG,"航线云台恢复跟随"); +// } +// +// @Override +// public void onFailure(@NonNull IDJIError idjiError) { +// LogUtil.log(TAG,"航线云台恢复跟随失败"); +// } +// }); + //Movement.getInstance().setMode_code(5); break; case PANO: @@ -837,13 +866,16 @@ public class FlightManager extends BaseManager { private void closeCabinDoor() { // 获取飞行状态和航线状态 - boolean isFlyingAndHeightOk = isFlying && Movement.getInstance().getElevation() > 30; + boolean isFlyingAndHeightOk = isFlying && Movement.getInstance().getElevation() > 20; boolean isDebugMode = PreferenceUtils.getInstance().getIsDebugMode(); String missionState = Movement.getInstance().getWaypointMissionExecuteState(); boolean isMissionExecuting = (!TextUtils.isEmpty(missionState) && (missionState.equals("EXECUTING") || missionState.equals("ENTER_WAYLINE")) || (!TextUtils.isEmpty(Movement.getInstance().getPlaneMode()) && Movement.getInstance().getPlaneMode().equals("WAYPOINT"))); + boolean isReturningHome = goHomeExecutionState == GoHomeState.RETURNING_TO_HOME.value() || + goHomeExecutionState == GoHomeState.LANDING.value(); + // 当飞机在飞行,高度足够,且航线状态为EXECUTING或ENTER_WAYLINE时,触发关舱门,开启水平避障 if (!PreferenceUtils.getInstance().getTriggerToAlternatePoint() && isFlyingAndHeightOk && !isDebugMode && isMissionExecuting && !sendCloseCabinDoorMsg) { sendCloseCabinDoorMsg = true; @@ -862,6 +894,7 @@ public class FlightManager extends BaseManager { private void openCabinDoor() { boolean isReturningHome = goHomeExecutionState == GoHomeState.RETURNING_TO_HOME.value() || goHomeExecutionState == GoHomeState.LANDING.value(); + double distance = Movement.getInstance().getHome_distance(); double flyingHeight = Movement.getInstance().getElevation(); boolean isDebugMode = PreferenceUtils.getInstance().getIsDebugMode(); @@ -872,6 +905,7 @@ public class FlightManager extends BaseManager { isReturningHome && isDistanceAndHeightValid && !isDebugMode) { LogUtil.log(TAG, "返航距离:" + distance + "---当前高度:" + flyingHeight); sendOpenCabinDoorMsg = true; + DockCloseManager.getInstance().stopRetry(); DockOpenManager.getInstance().sendDockOpenMsg2Server(); } @@ -880,8 +914,38 @@ public class FlightManager extends BaseManager { //降落时将云台朝下 private void gimbalDownwards() { + if (goHomeExecutionState == GoHomeState.LANDING.value() && Movement.getInstance().getElevation() > 11 && !isGimbalDownwards) { + MediaDataCenter.getInstance().getCameraStreamManager().setVisionAssistViewDirection(VisionAssistDirection.DOWN, new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + LogUtil.log(TAG,"下视开启成功"); + } + + @Override + public void onFailure(@NonNull IDJIError idjiError) { + LogUtil.log(TAG,"下视开启失败"); + } + }); + + LEDsSettings leDsSettings = new LEDsSettings(); + leDsSettings.setNavigationLEDsOn(false); + leDsSettings.setStatusIndicatorLEDsOn(true); + leDsSettings.setFrontLEDsOn(true); + KeyManager.getInstance().setValue(KeyTools.createKey(FlightControllerKey.KeyLEDsSettings), leDsSettings, new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + LogUtil.log(TAG,"夜航灯关闭成功"); + } + + @Override + public void onFailure(@NonNull IDJIError idjiError) { + LogUtil.log(TAG,"夜航灯关闭失败"); + } + }); + + DroneHelper.getInstance().setGimbalPitchDegree(); //将镜头设置为自动对焦 DroneHelper.getInstance().setCameraFocusMode(); @@ -907,6 +971,7 @@ public class FlightManager extends BaseManager { isGimbalDownwards = true; + PerceptionManager.getInstance().setPerceptionEnable(false); PerceptionManager.getInstance().setObstacleAvoidanceupEnabled(false); PerceptionManager.getInstance().setObstacleAvoidancedownEnabled(false); @@ -1068,16 +1133,21 @@ public class FlightManager extends BaseManager { if (isFlying && (Movement.getInstance().getElevation() < 15 && Movement.getInstance().getUltrasonicHeight() < 50) && !isSendDetect) { - LogUtil.log(TAG,"相对高度"+Movement.getInstance().getElevation()+"超声波高度"+Movement.getInstance().getUltrasonicHeight()); + // LogUtil.log(TAG,"相对高度"+Movement.getInstance().getElevation()+"超声波高度"+Movement.getInstance().getUltrasonicHeight()); double flyingHeight = Movement.getInstance().getElevation(); double thresholdMin = triggerToAlternatePoint ? FLYING_HEIGHT_THRESHOLD_MIN_ALTERNATE : FLYING_HEIGHT_THRESHOLD_MIN; + + if (flyingHeight > thresholdMin) { + //LogUtil.log(TAG,"相对高度"+Movement.getInstance().getElevation()+"超声波高度"+Movement.getInstance().getUltrasonicHeight()); + boolean shouldTriggerDetection; if (isDebugMode) { shouldTriggerDetection = goHomeExecutionState == 2; } else { + shouldTriggerDetection = goHomeExecutionState == 2 || needTriggerApronArucoLand || needTriggerAlterArucoLand; } if (shouldTriggerDetection) { @@ -1093,10 +1163,9 @@ public class FlightManager extends BaseManager { if (Movement.getInstance().getBattery_a_capacity_percent() > 40) { AMSConfig.getInstance().setAlternateLandingTimes(10 + ""); } - if (PreferenceUtils.getInstance().getTriggerToAlternatePoint()) { LogUtil.log(TAG, "识别AlterTag:" + PreferenceUtils.getInstance().getNeedTriggerAlterArucoLand()); - EventBus.getDefault().post(FLAG_START_DETECT_ARUCO_ALTERNATE); + //EventBus.getDefault().post(FLAG_START_DETECT_ARUCO_ALTERNATE); PreferenceUtils.getInstance().setNeedTriggerAlterArucoLand(true); PreferenceUtils.getInstance().setNeedTriggerApronArucoLand(false); LogUtil.log(TAG, "开始识别备降点二维码,椭球高度:" + Movement.getInstance().getElevation() + "米" + "--超声波高度:" + Movement.getInstance().getUltrasonicHeight() + "分米"); @@ -1257,7 +1326,7 @@ public class FlightManager extends BaseManager { //Movement.getInstance().setMissionFinish(true); // }, 1000); //原有那个替换 - if(Movement.getInstance().getMission_type()==0){ + if(PreferenceUtils.getInstance().getMissionType()==0){ Movement.getInstance().setMissionFinish1(true); } @@ -1270,6 +1339,11 @@ public class FlightManager extends BaseManager { public void startGoHome(MessageDown message) { FlightMode flightMode = KeyManager.getInstance().getValue(createKey(FlightControllerKey.KeyFlightMode)); + if (!getGimbalAndCameraEnabled()) { + return; + } + + if (Movement.getInstance().isPlaneWing() && Movement.getInstance().getHome_distance() < 20 && Movement.getInstance().getElevation() < 88 && Movement.getInstance().getBattery_a_capacity_percent() > 25 diff --git a/app/src/main/java/com/aros/apron/manager/FlightTaskProgressManager.java b/app/src/main/java/com/aros/apron/manager/FlightTaskProgressManager.java index c34166db..c80f0e2b 100644 --- a/app/src/main/java/com/aros/apron/manager/FlightTaskProgressManager.java +++ b/app/src/main/java/com/aros/apron/manager/FlightTaskProgressManager.java @@ -31,12 +31,13 @@ public class FlightTaskProgressManager extends BaseManager { lastExecuteTime = now; //如果是一键起飞航线或之后的指点飞行,这个就不用发,除此之外航线以及指点飞行都要发 - if (Movement.getInstance().getMission_type()==0&&(Movement.getInstance().isPlaneWing() - || Movement.getInstance().isMotorsOn() - || Movement.getInstance().isMissionFinish1())) { + if (PreferenceUtils.getInstance().getMissionType()==0&& (Movement.getInstance().isPlaneWing() + || Movement.getInstance().isMotorsOn()) && Movement.getInstance().isWaylineinterpter() ) { sendFlightTaskProgress2Server(); } + + //// //只要一个满足就上报 // if (Movement.getInstance().isPlaneWing() || Movement.getInstance().isMotorsOn()) { // sendFlightTaskProgress2Server(); diff --git a/app/src/main/java/com/aros/apron/manager/GimbalManager.java b/app/src/main/java/com/aros/apron/manager/GimbalManager.java index d19bf106..2d81356f 100644 --- a/app/src/main/java/com/aros/apron/manager/GimbalManager.java +++ b/app/src/main/java/com/aros/apron/manager/GimbalManager.java @@ -3,7 +3,9 @@ package com.aros.apron.manager; import static com.aros.apron.tools.Utils.getIDJIErrorMsg; import static dji.sdk.keyvalue.key.KeyTools.createKey; +import android.os.Handler; import android.text.TextUtils; +import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -65,7 +67,6 @@ public class GimbalManager extends BaseManager { Aprongim.getInstance().setDoublePayload(PreferenceUtils.getInstance().getCameraLocationType() == 4); - LogUtil.log(TAG, "主摄像头位置:" + PreferenceUtils.getInstance().getCameraLocationType()); Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(FlightControllerKey.KeyConnection)); @@ -100,7 +101,7 @@ public class GimbalManager extends BaseManager { Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(GimbalKey. KeyConnection, ComponentIndexType.PORT_1)); - if (isConnect != null && isConnect) { + if (isConnect != null && isConnect && getGimbalAndCameraEnabled()) { if (!message.getData().isLocked()) { GimbalSpeedRotation gimbalSpeedRotation = new GimbalSpeedRotation(); gimbalSpeedRotation.setPitch(message.getData().getPitch_speed()); @@ -174,9 +175,11 @@ public class GimbalManager extends BaseManager { Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(GimbalKey. KeyConnection, ComponentIndexType.PORT_1)); if (isConnect != null && isConnect) { + KeyManager.getInstance().performAction(KeyTools.createKey(GimbalKey.KeyGimbalReset, ComponentIndexType.PORT_1), GimbalResetType.PITCH_YAW, new CommonCallbacks.CompletionCallbackWithParam() { @Override public void onSuccess(EmptyMsg emptyMsg) { + LogUtil.log(TAG, "云台复位"); } @@ -195,8 +198,9 @@ public class GimbalManager extends BaseManager { public void gimbalReset(MessageDown message) { Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(GimbalKey. KeyConnection, ComponentIndexType.PORT_1)); - if (isConnect != null && isConnect) { + if (isConnect != null && isConnect && getGimbalAndCameraEnabled()) { switch (message.getData().getReset_mode()) { + //回中 case 0: KeyManager.getInstance().performAction(KeyTools.createKey(GimbalKey.KeyGimbalReset, ComponentIndexType.PORT_1), GimbalResetType.PITCH_YAW, new CommonCallbacks.CompletionCallbackWithParam() { @Override @@ -211,6 +215,7 @@ public class GimbalManager extends BaseManager { } ); break; + //向下 case 1: GimbalAngleRotation rotation = new GimbalAngleRotation(); rotation.setMode(GimbalAngleRotationMode.ABSOLUTE_ANGLE); @@ -230,6 +235,7 @@ public class GimbalManager extends BaseManager { } ); break; + //偏航回中 case 2: KeyManager.getInstance().performAction(KeyTools.createKey(GimbalKey.KeyGimbalReset, ComponentIndexType.PORT_1), GimbalResetType.ONLY_YAW, new CommonCallbacks.CompletionCallbackWithParam() { @@ -245,12 +251,10 @@ public class GimbalManager extends BaseManager { } ); break; + //俯仰向下 case 3: GimbalAngleRotation rotation1 = new GimbalAngleRotation(); rotation1.setMode(GimbalAngleRotationMode.ABSOLUTE_ANGLE); - if (!TextUtils.isEmpty(Movement.getInstance().getGimbal_yaw() + "")) { - rotation1.setYaw(Movement.getInstance().getGimbal_yaw()); - } rotation1.setPitch(-90.0); KeyManager.getInstance().performAction(KeyTools.createKey(GimbalKey.KeyRotateByAngle, ComponentIndexType.PORT_1), rotation1, new CommonCallbacks.CompletionCallbackWithParam() { @Override @@ -276,17 +280,27 @@ public class GimbalManager extends BaseManager { public void gimbalLookAt(MessageDown message) { Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(GimbalKey. KeyConnection, ComponentIndexType.PORT_1)); - // LogUtil.log(TAG,"isConnect"+isConnect); - if (isConnect != null && isConnect) { + // LogUtil.log(TAG,"isConnect"+isConnect); + if (isConnect != null && isConnect && getGimbalAndCameraEnabled()) { + LookAtInfo lookAtInfo = new LookAtInfo(); +// lookAtInfo.setMode(message.getData().isLocked() ? +// LookAtMode.LOOK_AT_GIMBAL_FOLLOWING : LookAtMode.LOOK_AT_GIMBAL_FREE); + lookAtInfo.setMode(message.getData().isLocked() ? - LookAtMode.LOOK_AT_GIMBAL_FOLLOWING : LookAtMode.LOOK_AT_GIMBAL_FREE); + LookAtMode.LOOK_AT_GIMBAL_FREE : LookAtMode.LOOK_AT_GIMBAL_FREE); + LocationCoordinate3D locationCoordinate3D = new LocationCoordinate3D(); locationCoordinate3D.setLatitude(message.getData().getLatitude()); locationCoordinate3D.setLongitude(message.getData().getLongitude()); locationCoordinate3D.setAltitude(Double.parseDouble(message.getData().getHeight() + "")); lookAtInfo.setLocation(locationCoordinate3D); - if(message.getData().isLocked()==true){ + + + LogUtil.log(TAG, "lookAtInfo" + lookAtInfo.toString()); + +// if(message.getData().isLocked()==true){ + if (false) { KeyManager.getInstance().setValue(KeyTools.createKey(GimbalKey.KeyGimbalMode), GimbalMode.YAW_FOLLOW, new CommonCallbacks.CompletionCallback() { @Override public void onSuccess() { @@ -294,13 +308,13 @@ public class GimbalManager extends BaseManager { KeyManager.getInstance().performAction(KeyTools.createKey(FlightControllerKey.KeyLookAt), lookAtInfo, new CommonCallbacks.CompletionCallbackWithParam() { @Override public void onSuccess(EmptyMsg emptyMsg) { - LogUtil.log(TAG,"看向目标点成功"); + LogUtil.log(TAG, "看向目标点成功"); sendMsg2Server(message); } @Override public void onFailure(@NonNull IDJIError error) { - LogUtil.log(TAG,"看向目标点失败"+error); + LogUtil.log(TAG, "看向目标点失败" + error); sendFailMsg2Server(message, "看向目标点失败:" + getIDJIErrorMsg(error)); } } @@ -312,17 +326,17 @@ public class GimbalManager extends BaseManager { //设置云台跟随失败 } }); - }else{ + } else { KeyManager.getInstance().performAction(KeyTools.createKey(FlightControllerKey.KeyLookAt), lookAtInfo, new CommonCallbacks.CompletionCallbackWithParam() { @Override public void onSuccess(EmptyMsg emptyMsg) { - LogUtil.log(TAG,"看向目标点成功"); + LogUtil.log(TAG, "看向目标点成功"); sendMsg2Server(message); } @Override public void onFailure(@NonNull IDJIError error) { - LogUtil.log(TAG,"看向目标点失败"+error); + LogUtil.log(TAG, "看向目标点失败" + error); sendFailMsg2Server(message, "看向目标点失败:" + getIDJIErrorMsg(error)); } } diff --git a/app/src/main/java/com/aros/apron/manager/MediaManager.java b/app/src/main/java/com/aros/apron/manager/MediaManager.java index 489fa33f..d12e0000 100644 --- a/app/src/main/java/com/aros/apron/manager/MediaManager.java +++ b/app/src/main/java/com/aros/apron/manager/MediaManager.java @@ -42,6 +42,7 @@ import dji.sdk.keyvalue.value.camera.MediaFileType; import dji.sdk.keyvalue.value.common.ComponentIndexType; import dji.v5.common.callback.CommonCallbacks; import dji.v5.common.error.IDJIError; + import dji.v5.manager.KeyManager; import dji.v5.manager.datacenter.MediaDataCenter; import dji.v5.manager.datacenter.media.MediaFile; @@ -97,6 +98,18 @@ public class MediaManager extends BaseManager { private boolean isEnablePlayback; public void enablePlayback() { + // 每次进入媒体模式时清空已上传文件集合 + uploadedFileNames.clear(); + // 重置失败计数和标志 + enterPlayBackFailTimes = 0; + isEnablePlayback = false; + // 重置拉取文件列表相关的计数器 + pullMediaFileListFromCameraFailTimes = 0; + updatingWaitCount = 0; + pullqwq = false; + + LogUtil.log(TAG, "已清空上传文件集合"); + MediaDataCenter.getInstance().getMediaManager().enable(new CommonCallbacks.CompletionCallback() { @Override public void onSuccess() { @@ -104,17 +117,16 @@ public class MediaManager extends BaseManager { new Handler().postDelayed(new Runnable() { @Override public void run() { - MediaFileListDataSource source = new MediaFileListDataSource.Builder().setIndexType(ComponentIndexType.PORT_1).build(); - // MediaDataCenter.getInstance().getMediaManager().setMediaFileDataSource(source); + MediaFileListDataSource source = new + MediaFileListDataSource.Builder().setIndexType(ComponentIndexType.PORT_1).build(); + MediaDataCenter.getInstance().getMediaManager().setMediaFileDataSource(source); new Handler().postDelayed(new Runnable() { @Override public void run() { pullMediaFileListFromCamera(); - isEnablePlayback = true; } }, 3000); - isEnablePlayback = true; } }, 3000); } @@ -185,10 +197,31 @@ public class MediaManager extends BaseManager { // 状态为UP_TO_DATE,获取文件列表数据 LogUtil.log(TAG, "状态为UP_TO_DATE,获取文件列表数据"); try { + // 确保获取文件列表数据 List rawList = MediaDataCenter.getInstance().getMediaManager().getMediaFileListData().getData(); + + // 检查文件列表是否为空 + if (rawList == null || rawList.isEmpty()) { + LogUtil.log(TAG, "文件列表为空,重试拉取"); + // 重试拉取文件列表 + if (pullMediaFileListFromCameraFailTimes < 5) { + pullMediaFileListFromCameraFailTimes++; + LogUtil.log(TAG, "第" + pullMediaFileListFromCameraFailTimes + "次重试..."); + new Handler().postDelayed(MediaManager.this::pullMediaFileListFromCamera, 2000); + } else { + LogUtil.log(TAG, "重试次数达到上限,拉取失败"); + ApronExecutionStatus.getInstance().setAircraftWaitShutDown(true); + sendEvent2Server("拉取媒体文件失败",2); + disablePlayback(); + LogUtil.log(TAG, "发送关闭无人机"); + } + return; + } + + LogUtil.log(TAG, "原始文件列表数量: " + rawList.size()); + // 过滤已上传文件 mediaFiles = new ArrayList<>(); - Movement.getInstance().setTask_media_count(mediaFiles.size()); for (MediaFile mf : rawList) { if (!uploadedFileNames.contains(mf.getFileName())) { mediaFiles.add(mf); @@ -196,6 +229,13 @@ public class MediaManager extends BaseManager { LogUtil.log(TAG, "跳过已上传文件: " + mf.getFileName()); } } + // 修复:在过滤后设置任务媒体计数 + Movement.getInstance().setTask_media_count(mediaFiles.size()); + LogUtil.log(TAG, "过滤后文件数量: " + mediaFiles.size()); + if(PreferenceUtils.getInstance().getMissionType()==0){ + sendFlightTaskProgress2Server(); + } + if (mediaFiles.isEmpty()) { LogUtil.log(TAG, "所有文件均已上传,直接清理"); @@ -224,7 +264,7 @@ public class MediaManager extends BaseManager { } } else { // 其他状态(如UPDATING),等待状态变化 - LogUtil.log(TAG, "状态为" + mState + ",等待状态变化..."); + LogUtil.log(TAG, "状态为" + mState + ",等待状态变化... (count=" + updatingWaitCount + ")"); updatingWaitCount++; // 增加超时处理,避免无限等待 diff --git a/app/src/main/java/com/aros/apron/manager/MissionV3Manager.java b/app/src/main/java/com/aros/apron/manager/MissionV3Manager.java index 21101dec..6461159d 100644 --- a/app/src/main/java/com/aros/apron/manager/MissionV3Manager.java +++ b/app/src/main/java/com/aros/apron/manager/MissionV3Manager.java @@ -34,8 +34,11 @@ import java.util.List; import dji.sdk.keyvalue.key.CameraKey; import dji.sdk.keyvalue.key.FlightControllerKey; +import dji.sdk.keyvalue.key.GimbalKey; import dji.sdk.keyvalue.key.KeyTools; +import dji.sdk.keyvalue.value.common.ComponentIndexType; import dji.sdk.keyvalue.value.flightcontroller.RemoteControllerFlightMode; +import dji.sdk.keyvalue.value.gimbal.GimbalMode; import dji.sdk.wpmz.value.mission.Wayline; import dji.sdk.wpmz.value.mission.WaylineExecuteWaypoint; import dji.sdk.wpmz.value.mission.WaylineWaylinesParseInfo; @@ -157,27 +160,27 @@ public class MissionV3Manager extends BaseManager { //这个是原来可控制那个发送最终状态的逻辑 - break; case READY: if (Movement.getInstance().getFlightmode() == 2 && istakeoff_ok == false) { Movement.getInstance().setTakeoff_status("task_ready"); } - if (PreferenceUtils.getInstance().getMissionType() == 2 - ) { - Movement.getInstance().setTask_status("paused"); - } else { - Movement.getInstance().setTask_status("in_progress"); - } +// if (PreferenceUtils.getInstance().getMissionType() == 2 +// ) { +// Movement.getInstance().setTask_status("paused"); +// } else { +// Movement.getInstance().setTask_status("in_progress"); +// } sendEvent2Server("任务状态:准备中", 1); break; case UPLOADING: - if (PreferenceUtils.getInstance().getMissionType() == 2 - ) { - Movement.getInstance().setTask_status("paused"); - } else { - Movement.getInstance().setTask_status("in_progress"); - } + +// if (PreferenceUtils.getInstance().getMissionType() == 2 +// ) { +// Movement.getInstance().setTask_status("paused"); +// } else { +// Movement.getInstance().setTask_status("in_progress"); +// } sendEvent2Server("任务状态:上传中", 1); Movement.getInstance().setVirtualStickQuitMission(false); @@ -185,30 +188,46 @@ public class MissionV3Manager extends BaseManager { break; case PREPARING: - if (PreferenceUtils.getInstance().getMissionType() == 2 - ) { - Movement.getInstance().setTask_status("paused"); - } else { - Movement.getInstance().setTask_status("in_progress"); - } + + + + Movement.getInstance().setTask_status("in_progress"); + +// if (PreferenceUtils.getInstance().getMissionType() == 2 +// ) { +// Movement.getInstance().setTask_status("paused"); +// } else { +// Movement.getInstance().setTask_status("in_progress"); +// } sendEvent2Server("任务状态:执行准备中", 1); Movement.getInstance().setVirtualStickQuitMission(false); - - - break; case ENTER_WAYLINE: +// KeyManager.getInstance().setValue(KeyTools.createKey(GimbalKey.KeyGimbalMode, ComponentIndexType.PORT_1), GimbalMode.YAW_FOLLOW, new CommonCallbacks.CompletionCallback() { +// @Override +// public void onSuccess() { +// LogUtil.log(TAG,"航线云台跟随"); +// } +// +// @Override +// public void onFailure(@NonNull IDJIError idjiError) { +// LogUtil.log(TAG,"航线云台跟随失败"); +// } +// }); + enterWayLineTime = System.currentTimeMillis(); if (Movement.getInstance().getFlightmode() == 2) { Movement.getInstance().setTakeoff_status("wayline_progress"); } - if (PreferenceUtils.getInstance().getMissionType() == 2 - ) { - Movement.getInstance().setTask_status("paused"); - } else { - Movement.getInstance().setTask_status("in_progress"); - } + Movement.getInstance().setTask_status("in_progress"); + +// if (PreferenceUtils.getInstance().getMissionType() == 2 +// ) { +// Movement.getInstance().setTask_status("paused"); +// } else { +// Movement.getInstance().setTask_status("in_progress"); +// } Movement.getInstance().setVirtualStickQuitMission(false); sendEvent2Server("任务状态:进入航线飞行,飞往指定航线的第一个航点", 1); @@ -218,7 +237,6 @@ public class MissionV3Manager extends BaseManager { //航线飞行 if (Movement.getInstance().getFlightmode() == 1) { - Movement.getInstance().setMode_code(5); } else if (Movement.getInstance().getFlightmode() == 2) { //指令飞行 @@ -229,17 +247,21 @@ public class MissionV3Manager extends BaseManager { case EXECUTING: sendEvent2Server("任务状态:航线任务执行中", 1); - if (PreferenceUtils.getInstance().getMissionType() == 2 - ) { - Movement.getInstance().setTask_status("paused"); - } else { - Movement.getInstance().setTask_status("in_progress"); - } + Movement.getInstance().setTask_status("in_progress"); + +// if (PreferenceUtils.getInstance().getMissionType() == 2 +// ) { +// Movement.getInstance().setTask_status("paused"); +// } else { +// Movement.getInstance().setTask_status("in_progress"); +// } + Movement.getInstance().setVirtualStickQuitMission(false); break; case INTERRUPTED: + if (Movement.getInstance().getFlightmode() == 2) { Movement.getInstance().setTakeoff_status("wayline_cancel"); TakeoffProgressScheduler.getInstance().stopReporting(); @@ -247,8 +269,13 @@ public class MissionV3Manager extends BaseManager { Movement.getInstance().setVirtualStickQuitMission(false); sendEvent2Server("任务状态:航线任务执行中断", 1); - Movement.getInstance().setTask_status("paused"); + Movement.getInstance().setTask_status("paused"); + if(PreferenceUtils.getInstance().getMissionType()==0){ + sendFlightTaskProgress2Server(); + } + + Movement.getInstance().setWaylineinterpter(false); //切换成手动飞行 @@ -257,13 +284,27 @@ public class MissionV3Manager extends BaseManager { break; case RECOVERING: Movement.getInstance().setVirtualStickQuitMission(false); + +// KeyManager.getInstance().setValue(KeyTools.createKey(GimbalKey.KeyGimbalMode, ComponentIndexType.PORT_1), GimbalMode.YAW_FOLLOW, new CommonCallbacks.CompletionCallback() { +// @Override +// public void onSuccess() { +// LogUtil.log(TAG,"航线云台恢复跟随"); +// } +// +// @Override +// public void onFailure(@NonNull IDJIError idjiError) { +// LogUtil.log(TAG,"航线云台恢复跟随失败"); +// } +// }); + sendEvent2Server("任务状态:航线任务恢复中", 1); - if (PreferenceUtils.getInstance().getMissionType() == 2 - ) { - Movement.getInstance().setTask_status("paused"); - } else { - Movement.getInstance().setTask_status("in_progress"); - } + +// if (PreferenceUtils.getInstance().getMissionType() == 2 +// ) { +// Movement.getInstance().setTask_status("paused"); +// } else { +// Movement.getInstance().setTask_status("in_progress"); +// } break; @@ -272,13 +313,15 @@ public class MissionV3Manager extends BaseManager { //释放锁 Synchronizedstatus.setIsruning(false); Synchronizedstatus.setInitStatus(false); + Synchronizedstatus.setFlighttaskExecuteStatus(false); + Synchronizedstatus.setTakeoff_to_point(false); - //如果是虚拟摇杆导致的退出应该要可恢复 - if (Movement.getInstance().getMode_code() == 16) { - PreferenceUtils.getInstance().setMissionType(2); - } else { - - } +// //如果是虚拟摇杆导致的退出应该要可恢复 +// if (Movement.getInstance().getMode_code() == 16) { +// PreferenceUtils.getInstance().setMissionType(2); +// } else { +// +// } if (Movement.getInstance().getFlightmode() == 2) { // @@ -300,7 +343,7 @@ public class MissionV3Manager extends BaseManager { mainHandler.postDelayed(new Runnable() { @Override public void run() { - if (finishWayLineTime - enterWayLineTime <= 8000 && !Movement.getInstance().isPlaneWing() + if (finishWayLineTime - enterWayLineTime <= 5000 && !Movement.getInstance().isPlaneWing() ) { isMissionStart = false; totalretryStartMissiontimes++; @@ -316,15 +359,30 @@ public class MissionV3Manager extends BaseManager { break; case RETURN_TO_START_POINT: + +// KeyManager.getInstance().setValue(KeyTools.createKey(GimbalKey.KeyGimbalMode, ComponentIndexType.PORT_1), GimbalMode.YAW_FOLLOW, new CommonCallbacks.CompletionCallback() { +// @Override +// public void onSuccess() { +// LogUtil.log(TAG,"航线云台恢复跟随"); +// } +// +// @Override +// public void onFailure(@NonNull IDJIError idjiError) { +// LogUtil.log(TAG,"航线云台恢复跟随失败"); +// } +// }); + //自动返航 Movement.getInstance().setMode_code(9); - if (PreferenceUtils.getInstance().getMissionType() == 2 - ) { - Movement.getInstance().setTask_status("paused"); - } else { - Movement.getInstance().setTask_status("in_progress"); - } + + Movement.getInstance().setTask_status("in_progress"); +// if (PreferenceUtils.getInstance().getMissionType() == 2 +// ) { +// Movement.getInstance().setTask_status("paused"); +// } else { +// Movement.getInstance().setTask_status("in_progress"); +// } break; @@ -355,6 +413,9 @@ public class MissionV3Manager extends BaseManager { sendEvent2Server("航线中断原因" + error.toString(), 2); } }); + + + waypointMissionManager.addWaypointActionListener(new WaypointActionListener() { @Override public void onExecutionStart(int actionId) { @@ -377,7 +438,7 @@ public class MissionV3Manager extends BaseManager { } }); - }, 2000); // 参数别改:2s延迟 + }, 500); // 参数别改:2s延迟 } // 存储最新的航线消息 @@ -387,6 +448,7 @@ public class MissionV3Manager extends BaseManager { PreferenceUtils.getInstance().setMissionType(0); + Movement.getInstance().setMission_type(0); PreferenceUtils.getInstance().setFlightId(message.getData().getFlight_id()); PreferenceUtils.getInstance().setAlternatePointLon(message.getData().getAlternate_land_point().getLongitude() + ""); @@ -408,6 +470,8 @@ public class MissionV3Manager extends BaseManager { Movement.getInstance().setTask_current_step(5); + + //1.检查图传是否连接 //避免重复执行 if (isReceiverMission == false) { @@ -507,7 +571,7 @@ public class MissionV3Manager extends BaseManager { // if (isMissionStateValid && isPlaneMessageValid && isGpsQualityValid) { sendEvent2Server("卫星数量" + GPSSatelliteCount + "gps是否ok" + GPSSatelliteCountValid, 1); - if (isGpsQualityValid || GPSSatelliteCountValid) { + if (isGpsQualityValid || GPSSatelliteCountValid ) { //5.下载航线 downLoadKMZFile(message); sendEvent2Server("执行下载航线成功", 1); @@ -614,8 +678,7 @@ public class MissionV3Manager extends BaseManager { * @param message */ private void pushKMZFileToAircraft(MessageDown message) { - Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(FlightControllerKey. - KeyConnection)); + Boolean isConnect = true; if (isConnect != null && isConnect) { KMZInfo kmzInfo = WPMZManager.getInstance().getKMZInfo( @@ -656,7 +719,7 @@ public class MissionV3Manager extends BaseManager { @Override public void onSuccess() { Movement.getInstance().setWaylinename("aros"); - + PreferenceUtils.getInstance().setWaylinename("aros"); // "2": "起飞准备完毕", Movement.getInstance().setMode_code(2); LogUtil.log(TAG, "航线上传成功,准备执行任务"); @@ -721,8 +784,7 @@ public class MissionV3Manager extends BaseManager { * @param message */ public void startMission(MessageDown message) { - Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(FlightControllerKey. - KeyConnection)); + Boolean isConnect =true; if (isConnect != null && isConnect) { int missionStateCode = Movement.getInstance().getMissionStateCode(); //每次航线开始时,重置是否需要识别二维码状态,避免刚起飞就识别二维码/并确保不是飞向备降点的航线 @@ -839,6 +901,9 @@ public class MissionV3Manager extends BaseManager { Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(FlightControllerKey. KeyConnection)); if (isConnect != null && isConnect) { + if (Movement.getInstance().getFlightmode() == 1) { + Movement.getInstance().setMode_code(5); + } IWaypointMissionManager missionManager = WaypointMissionManager.getInstance(); //如果航线是暂停状态,直接恢复航线,否则查询断点信息 if (Movement.getInstance().getMissionStateCode() == 7) { @@ -847,7 +912,19 @@ public class MissionV3Manager extends BaseManager { public void onSuccess() { sendMsg2Server(message); Movement.getInstance().setTask_status("in_progress"); - sendFlightTaskProgress2Server(); + + if( PreferenceUtils.getInstance().getMissionType()==0){ + Movement.getInstance().setCameraMode(5); + }else if( PreferenceUtils.getInstance().getMissionType()==1){ + Movement.getInstance().setCameraMode(17); + } + + + if(PreferenceUtils.getInstance().getMissionType()==0){ + sendFlightTaskProgress2Server(); + } + + Movement.getInstance().setWaylineinterpter(true); } @Override @@ -870,9 +947,20 @@ public class MissionV3Manager extends BaseManager { public void onSuccess() { sendMsg2Server(message); PreferenceUtils.getInstance().setIsNewRoute(false); + + if( PreferenceUtils.getInstance().getMissionType()==0){ + Movement.getInstance().setCameraMode(5); + }else if( PreferenceUtils.getInstance().getMissionType()==1){ + Movement.getInstance().setCameraMode(17); + } + LogUtil.log(TAG, "恢复断点航线成功"); Movement.getInstance().setTask_status("in_progress"); - sendFlightTaskProgress2Server(); + if(PreferenceUtils.getInstance().getMissionType()==0){ + sendFlightTaskProgress2Server(); + } + + Movement.getInstance().setWaylineinterpter(true); } @Override diff --git a/app/src/main/java/com/aros/apron/manager/PayloadWidgetManager.java b/app/src/main/java/com/aros/apron/manager/PayloadWidgetManager.java index b658314a..89c76e2a 100644 --- a/app/src/main/java/com/aros/apron/manager/PayloadWidgetManager.java +++ b/app/src/main/java/com/aros/apron/manager/PayloadWidgetManager.java @@ -56,14 +56,14 @@ public class PayloadWidgetManager extends BaseManager { //负载信息 Map payloadManager = PayloadCenter.getInstance().getPayloadManager(); if (payloadManager != null) { - IPayloadManager iPayloadManager = payloadManager.get(PayloadIndexType.PORT_1); + IPayloadManager iPayloadManager = payloadManager.get(PayloadIndexType.PORT_2); if (iPayloadManager != null) { - PayloadCenter.getInstance().getPayloadManager().get(PayloadIndexType.PORT_1).pullWidgetInfoFromPayload(new CommonCallbacks.CompletionCallback() { + PayloadCenter.getInstance().getPayloadManager().get(PayloadIndexType.PORT_2).pullWidgetInfoFromPayload(new CommonCallbacks.CompletionCallback() { @Override public void onSuccess() { //基础信息 - PayloadCenter.getInstance().getPayloadManager().get(PayloadIndexType.PORT_1).addPayloadBasicInfoListener(new PayloadBasicInfoListener() { + PayloadCenter.getInstance().getPayloadManager().get(PayloadIndexType.PORT_2).addPayloadBasicInfoListener(new PayloadBasicInfoListener() { @Override public void onPayloadBasicInfoUpdate(PayloadBasicInfo info) { LogUtil.log(TAG, "左侧负载基础信息:" + info.toString()); @@ -71,7 +71,7 @@ public class PayloadWidgetManager extends BaseManager { } }); - PayloadCenter.getInstance().getPayloadManager().get(PayloadIndexType.PORT_1).addPayloadDataListener(new PayloadDataListener() { + PayloadCenter.getInstance().getPayloadManager().get(PayloadIndexType.PORT_2).addPayloadDataListener(new PayloadDataListener() { @Override public void onDataFromPayloadUpdate(byte[] data) { LogUtil.log(TAG, "左侧负载数据信息:" +new String(data, java.nio.charset.StandardCharsets.UTF_8).replaceAll("[^\\x20-\\x7E\\u4e00-\\u9fa5]", "")); @@ -80,14 +80,14 @@ public class PayloadWidgetManager extends BaseManager { }); //可以把负载设备控件打印 - PayloadCenter.getInstance().getPayloadManager().get(PayloadIndexType.PORT_1).addPayloadWidgetInfoListener(new PayloadWidgetInfoListener() { + PayloadCenter.getInstance().getPayloadManager().get(PayloadIndexType.PORT_2).addPayloadWidgetInfoListener(new PayloadWidgetInfoListener() { @Override public void onPayloadWidgetInfoUpdate(PayloadWidgetInfo info) { LogUtil.log(TAG, "左侧负载控件信息:" + info.toString()); XcFileLog.getInstace().w(TAG, "左侧负载控件信息:" + info.toString()); //如果负载为空 if (info.getConfigInterfaceWidgetList() == null || info.getMainInterfaceWidgetList() == null) { - PayloadCenter.getInstance().getPayloadManager().get(PayloadIndexType.PORT_1).pullWidgetInfoFromPayload(new CommonCallbacks.CompletionCallback() { + PayloadCenter.getInstance().getPayloadManager().get(PayloadIndexType.PORT_2).pullWidgetInfoFromPayload(new CommonCallbacks.CompletionCallback() { @Override public void onSuccess() { LogUtil.log(TAG, "负载重复拉取成功"); diff --git a/app/src/main/java/com/aros/apron/manager/PayloadlightManager.java b/app/src/main/java/com/aros/apron/manager/PayloadlightManager.java new file mode 100644 index 00000000..7fdef1cc --- /dev/null +++ b/app/src/main/java/com/aros/apron/manager/PayloadlightManager.java @@ -0,0 +1,295 @@ +package com.aros.apron.manager; + +import static com.aros.apron.tools.Utils.getIDJIErrorMsg; + +import androidx.annotation.NonNull; + +import com.aros.apron.base.BaseManager; +import com.aros.apron.entity.MessageDown; +import com.aros.apron.entity.PayloadInfo; +import com.aros.apron.entity.Synchronizedstatus; +import com.aros.apron.tools.LogUtil; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import dji.sdk.keyvalue.key.GimbalKey; +import dji.sdk.keyvalue.key.KeyTools; +import dji.sdk.keyvalue.value.common.EmptyMsg; +import dji.sdk.keyvalue.value.payload.WidgetType; +import dji.sdk.keyvalue.value.payload.WidgetValue; +import dji.v5.common.callback.CommonCallbacks; +import dji.v5.common.error.IDJIError; +import dji.v5.manager.KeyManager; +import dji.v5.manager.aircraft.payload.PayloadCenter; +import dji.v5.manager.aircraft.payload.PayloadIndexType; +import dji.v5.manager.interfaces.IPayloadManager; + +/** + *夜航灯设置 + * + */ + +public class PayloadlightManager extends BaseManager { + private String TAG = this.getClass().getSimpleName(); + private boolean issettrue=false; + private PayloadlightManager() { + } + + private static class PayloadlightManagerHolder { + private static final PayloadlightManager INSTANCE = new PayloadlightManager(); + } + + public static PayloadlightManager getInstance() { + return PayloadlightManagerHolder.INSTANCE; + } + Map payloadManager = PayloadCenter.getInstance().getPayloadManager(); + IPayloadManager iPayloadManager; + public void setindex(int index){ + if(index==1){ + iPayloadManager = payloadManager.get(PayloadIndexType.PORT_1); + }else if(index==2){ + iPayloadManager = payloadManager.get(PayloadIndexType.PORT_2); + }else if(index==3){ + iPayloadManager = payloadManager.get(PayloadIndexType.PORT_3); + }else if(index==4){ + iPayloadManager = payloadManager.get(PayloadIndexType.PORT_4); + } + } + + public void drc_light_brightness_set(MessageDown message){ + if(message!=null){ + //索引 + if(issettrue=false){ + setindex(message.getData().getPsdk_index()); + issettrue=true; + } + + WidgetValue widgetValue=new WidgetValue(); + widgetValue.setValue(message.getData().getBrightness()); + widgetValue.setIndex(3); + widgetValue.setType(WidgetType.RANGE); + + + iPayloadManager.setWidgetValue(widgetValue, new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + LogUtil.log(TAG,"亮度设置成功"); + sendMsg2Server(message); + Synchronizedstatus.setLight_brightnessrunning(false); + } + + @Override + public void onFailure(@NonNull IDJIError idjiError) { + LogUtil.log(TAG,"亮度设置失败"); + sendFailMsg2Server(message, "亮度设置失败:" + getIDJIErrorMsg(idjiError)); + Synchronizedstatus.setLight_brightnessrunning(false); + } + }); + } + } + + + public void drc_light_mode_set(MessageDown message){ + if(message!=null){ + //索引 + if(issettrue=false){ + setindex(message.getData().getPsdk_index()); + issettrue=true; + } + + WidgetValue widgetValue=new WidgetValue(); + + + if(message.getData().getMode()==0){ + + //关闭 + widgetValue.setValue(0); + widgetValue.setIndex(3); + widgetValue.setType(WidgetType.SWITCH); + + iPayloadManager.setWidgetValue(widgetValue, new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + LogUtil.log(TAG,"探照灯关闭成功"); + sendMsg2Server(message); + Synchronizedstatus.setDrc_light_mode_set(false); + } + + @Override + public void onFailure(@NonNull IDJIError idjiError) { + LogUtil.log(TAG,"探照灯关闭失败"); + sendFailMsg2Server(message, "探照灯关闭失败:" + getIDJIErrorMsg(idjiError)); + Synchronizedstatus.setDrc_light_mode_set(false); + } + }); + + + + }else if(message.getData().getMode()==1){ + + + + + //打开 + widgetValue.setValue(1); + widgetValue.setIndex(3); + widgetValue.setType(WidgetType.SWITCH); + + iPayloadManager.setWidgetValue(widgetValue, new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + LogUtil.log(TAG,"探照灯打开成功"); + + WidgetValue widgetValue1=new WidgetValue(); + widgetValue1.setValue(0); + widgetValue1.setIndex(0); + widgetValue1.setType(WidgetType.SWITCH); + iPayloadManager.setWidgetValue(widgetValue1, new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + LogUtil.log(TAG,"关闭爆闪模式成功"); + WidgetValue widgetValue2=new WidgetValue(); + widgetValue2.setValue(2); + widgetValue2.setIndex(2); + widgetValue2.setType(WidgetType.RANGE); + iPayloadManager.setWidgetValue(widgetValue2, new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + LogUtil.log(TAG,"设置亮度全开"); + sendMsg2Server(message); + Synchronizedstatus.setDrc_light_mode_set(false); + } + + @Override + public void onFailure(@NonNull IDJIError idjiError) { + LogUtil.log(TAG,"设置亮度全开失败"); + sendMsg2Server(message); + Synchronizedstatus.setDrc_light_mode_set(false); + } + }); + } + + @Override + public void onFailure(@NonNull IDJIError idjiError) { + LogUtil.log(TAG,"关闭爆闪模式失败"); + sendMsg2Server(message); + Synchronizedstatus.setDrc_light_mode_set(false); + } + }); + + + } + + @Override + public void onFailure(@NonNull IDJIError idjiError) { + LogUtil.log(TAG,"探照灯打开失败"); + sendMsg2Server(message); + Synchronizedstatus.setDrc_light_mode_set(false); + } + }); + + + + }else{ + //爆闪 + widgetValue.setValue(1); + widgetValue.setIndex(3); + widgetValue.setType(WidgetType.SWITCH); + + iPayloadManager.setWidgetValue(widgetValue, new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + LogUtil.log(TAG,"探照灯打开成功"); + WidgetValue widgetValue1=new WidgetValue(); + widgetValue1.setValue(1); + widgetValue1.setIndex(0); + widgetValue1.setType(WidgetType.SWITCH); + iPayloadManager.setWidgetValue(widgetValue1, new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + LogUtil.log(TAG,"爆闪模式打开成功"); + + WidgetValue widgetValue2=new WidgetValue(); + widgetValue2.setValue(2); + widgetValue2.setIndex(2); + widgetValue2.setType(WidgetType.RANGE); + iPayloadManager.setWidgetValue(widgetValue2, new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + LogUtil.log(TAG,"设置亮度全开"); + sendMsg2Server(message); + Synchronizedstatus.setDrc_light_mode_set(false); + } + + @Override + public void onFailure(@NonNull IDJIError idjiError) { + LogUtil.log(TAG,"设置亮度全开失败"); + sendFailMsg2Server(message, "设置亮度全开失败:" + getIDJIErrorMsg(idjiError)); + Synchronizedstatus.setDrc_light_mode_set(false); + } + }); + + } + + @Override + public void onFailure(@NonNull IDJIError idjiError) { + LogUtil.log(TAG,"爆闪模式打开失败"); + sendFailMsg2Server(message, "爆闪模式打开失败:" + getIDJIErrorMsg(idjiError)); + Synchronizedstatus.setDrc_light_mode_set(false); + + } + }); + + + } + + @Override + public void onFailure(@NonNull IDJIError idjiError) { + LogUtil.log(TAG,"探照灯打开失败"); + sendFailMsg2Server(message, "探照灯打开失败:" + getIDJIErrorMsg(idjiError)); + Synchronizedstatus.setDrc_light_mode_set(false); + } + }); + } + } + } + + public void drc_light_calibration(MessageDown message){ + if(message!=null) { + //索引 + if (issettrue = false) { + setindex(message.getData().getPsdk_index()); + issettrue = true; + } + KeyManager.getInstance().performAction(KeyTools.createKey(GimbalKey.KeyLightGimbalCalibrate), new CommonCallbacks.CompletionCallbackWithParam() { + @Override + public void onSuccess(EmptyMsg emptyMsg) { + LogUtil.log(TAG,"启动校准"); + sendMsg2Server(message); + Synchronizedstatus.setDrc_light_calibration(false); + } + + @Override + public void onFailure(@NonNull IDJIError idjiError) { + LogUtil.log(TAG,"启动校准失败"); + sendFailMsg2Server(message, "启动校准失败:" + getIDJIErrorMsg(idjiError)); + Synchronizedstatus.setDrc_light_calibration(false); + } + }); + } + } + + public void drc_light_fine_tuning_set(){ + + + } + + + + + + + +} diff --git a/app/src/main/java/com/aros/apron/manager/PerceptionManager.java b/app/src/main/java/com/aros/apron/manager/PerceptionManager.java index f1f541e7..64eb3fa9 100644 --- a/app/src/main/java/com/aros/apron/manager/PerceptionManager.java +++ b/app/src/main/java/com/aros/apron/manager/PerceptionManager.java @@ -50,6 +50,7 @@ public class PerceptionManager extends BaseManager { Boolean isConnect = KeyManager.getInstance().getValue(createKey(FlightControllerKey.KeyConnection)); if (isConnect != null && isConnect) { IPerceptionManager perceptionManager = dji.v5.manager.aircraft.perception.PerceptionManager.getInstance(); + //关闭避障 perceptionManager.setObstacleAvoidanceType(perceptionEnable ? ObstacleAvoidanceType.BRAKE : ObstacleAvoidanceType.CLOSE, new CommonCallbacks.CompletionCallback() { @Override @@ -67,7 +68,18 @@ public class PerceptionManager extends BaseManager { if (perceptionEnable) { LogUtil.log(TAG, "避障开启失败:" + new Gson().toJson(idjiError)); } else { - LogUtil.log(TAG, "第" + closePerceptionTimes + "次关闭避障失败:" + new Gson().toJson(idjiError)); + String errorMsg = new Gson().toJson(idjiError); + LogUtil.log(TAG, "第" + closePerceptionTimes + "次关闭避障失败:" + errorMsg); + + // 特殊错误处理:飞机不支持或当前状态不支持 + // 这通常意味着飞机已经在地面,避障系统已自动关闭,可以认为关闭成功 + if ("CURRENT_AIRCRAFT_NOT_SUPPORT".equals(idjiError.errorCode()) + || "NOT_SUPPORTED".equals(idjiError.errorCode())) { + LogUtil.log(TAG, "避障已自动关闭(飞机未起飞/已降落),视为关闭成功"); + closePerceptionSuccess = true; // 标记为成功,停止重试 + return; + } + if (!closePerceptionSuccess) { if (closePerceptionTimes <= 5) { new Handler().postDelayed(new Runnable() { @@ -82,7 +94,7 @@ public class PerceptionManager extends BaseManager { } }, 2000); } else { - LogUtil.log(TAG, "避障关闭" + closePerceptionTimes + "次失败"); + LogUtil.log(TAG, "避障关闭" + closePerceptionTimes + "次失败,放弃重试"); } } } @@ -109,7 +121,7 @@ public class PerceptionManager extends BaseManager { @Override public void onFailure(@NonNull IDJIError idjiError) { - LogUtil.log(TAG, "开启水平避障:" + new Gson().toJson(idjiError)); + LogUtil.log(TAG, "水平避障:"+perceptionEnable + new Gson().toJson(idjiError)); } }); @@ -133,7 +145,7 @@ public class PerceptionManager extends BaseManager { @Override public void onFailure(@NonNull IDJIError idjiError) { - LogUtil.log(TAG, "开启水平避障:" + new Gson().toJson(idjiError)); + LogUtil.log(TAG, "避障up:"+perceptionEnable + new Gson().toJson(idjiError)); } }); @@ -157,7 +169,7 @@ public class PerceptionManager extends BaseManager { @Override public void onFailure(@NonNull IDJIError idjiError) { - LogUtil.log(TAG, "开启水平避障:" + new Gson().toJson(idjiError)); + LogUtil.log(TAG, "下避障:"+perceptionEnable+ new Gson().toJson(idjiError)); } }); diff --git a/app/src/main/java/com/aros/apron/manager/SpeakerManager.java b/app/src/main/java/com/aros/apron/manager/SpeakerManager.java index acb3ae9a..5a2f6483 100644 --- a/app/src/main/java/com/aros/apron/manager/SpeakerManager.java +++ b/app/src/main/java/com/aros/apron/manager/SpeakerManager.java @@ -27,6 +27,7 @@ import dji.v5.manager.aircraft.megaphone.MegaphoneIndex; import dji.v5.manager.aircraft.megaphone.MegaphoneInfo; import dji.v5.manager.aircraft.megaphone.MegaphoneInfoListener; import dji.v5.manager.aircraft.megaphone.MegaphoneManager; +import dji.v5.manager.aircraft.megaphone.MegaphoneStatus; import dji.v5.manager.aircraft.megaphone.PlayMode; import dji.v5.manager.aircraft.megaphone.UploadType; import okhttp3.Call; @@ -37,6 +38,8 @@ import okhttp3.Response; public class SpeakerManager extends BaseManager { + + private boolean issetok=false; private SpeakerManager() { } private static class SpeakerHolder { @@ -47,27 +50,33 @@ public class SpeakerManager extends BaseManager { } private int megaphoneStatus; private XTtsPcmGenerator ttsGenerator; + public void initMegaphoneInfo() { MegaphoneManager.getInstance().addMegaphoneInfoListener(new MegaphoneInfoListener() { @Override public void onUpdateMegaphoneInfo(MegaphoneInfo megaphoneInfo) { if (megaphoneInfo != null) { - megaphoneStatus = megaphoneInfo.getStatus().ordinal(); + MegaphoneStatus megaphoneStatus = megaphoneInfo.getStatus(); + //LogUtil.log(TAG,"喊话器"+megaphoneStatus); + // 当喊话器状态为"已连接"时(status=2),再设置位置 + if (megaphoneStatus == MegaphoneStatus.IDLE && issetok==false) { + + MegaphoneManager.getInstance().setMegaphoneIndex(MegaphoneIndex.PORT_2, new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + issetok=true; + LogUtil.log(TAG,"喊话器位置设置成功"); + } + + @Override + public void onFailure(@NonNull IDJIError error) { + LogUtil.log(TAG,"喊话器位置设置失败:"+getIDJIErrorMsg(error)); + } + }); + } } } }); - MegaphoneManager.getInstance().setMegaphoneIndex(MegaphoneIndex.PORT_2, new CommonCallbacks.CompletionCallback() { - @Override - public void onSuccess() { - LogUtil.log(TAG,"喊话器位置设置成功"); - } - - @Override - public void onFailure(@NonNull IDJIError error) { - LogUtil.log(TAG,"喊话器位置设置失败:"+getIDJIErrorMsg(error)); - } - }); - } public void speakerAudioPlayStart(MessageDown message) { sendMsg2Server(message); @@ -393,6 +402,7 @@ public class SpeakerManager extends BaseManager { MegaphoneManager.getInstance().startPlay(new CommonCallbacks.CompletionCallback() { @Override public void onSuccess() { + sendMsg2Server(message); Movement.getInstance().setTTS_status("ok"); Movement.getInstance().setStep_key("play"); sendEvent2Server("喊话器播放TTS音频成功", 1); @@ -402,6 +412,7 @@ public class SpeakerManager extends BaseManager { @Override public void onFailure(@NonNull IDJIError error) { + sendFailMsg2Server(message, "喊话器播放TTS音频失败:" + getIDJIErrorMsg(error)); sendEvent2Server("喊话器播放TTS音频失败:" + getIDJIErrorMsg(error), 2); LogUtil.log(TAG,"喊话器播放TTS音频失败qwq" + getIDJIErrorMsg(error)); Synchronizedstatus.setSpeakTTSrunning(false); @@ -431,4 +442,19 @@ public class SpeakerManager extends BaseManager { LogUtil.log(TAG, "设置 speakTTSrunning 为 false"); LogUtil.log(TAG, "speakerTTSPlayStart 方法执行完成"); } + + public void setindex(){ + MegaphoneManager.getInstance().setMegaphoneIndex(MegaphoneIndex.PORT_2, new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + issetok=true; + LogUtil.log(TAG,"喊话器位置设置成功"); + } + + @Override + public void onFailure(@NonNull IDJIError error) { + LogUtil.log(TAG,"喊话器位置设置失败:"+getIDJIErrorMsg(error)); + } + }); + } } \ No newline at end of file diff --git a/app/src/main/java/com/aros/apron/manager/StickManager.java b/app/src/main/java/com/aros/apron/manager/StickManager.java index 5ba9bc4f..235834ee 100644 --- a/app/src/main/java/com/aros/apron/manager/StickManager.java +++ b/app/src/main/java/com/aros/apron/manager/StickManager.java @@ -59,9 +59,8 @@ public class StickManager extends BaseManager { public void onSuccess() { LogUtil.log(TAG, "控制权获取成功"); VirtualStickManager.getInstance().setVirtualStickAdvancedModeEnabled(true); - - } + @Override public void onFailure(@NonNull IDJIError error) { LogUtil.log(TAG, "拖动控制权获取成功"); @@ -78,6 +77,7 @@ public class StickManager extends BaseManager { VirtualStickManager.getInstance().setVirtualStickAdvancedModeEnabled(false); } + @Override public void onFailure(@NonNull IDJIError error) { LogUtil.log(TAG, "拖动控制权取消成功"); @@ -89,56 +89,80 @@ public class StickManager extends BaseManager { //取消虚拟摇杆控制权 public void enableVirtualStick(MessageDown message) { - if(Movement.getInstance().isVirtualcontrollget()==true){ + if (Movement.getInstance().isVirtualcontrollget() == true) { sendMsg2Server(message); return; } //吐过开启了drc或者使用过摇杆 - if(Movement.getInstance().isOpendrc()==false){ - VirtualStickManager.getInstance().setVirtualStickAdvancedModeEnabled(true); - VirtualStickManager.getInstance().enableVirtualStick(new CommonCallbacks.CompletionCallback() { - @Override - public void onSuccess() { - Movement.getInstance().setOpendrc(true); - if (message != null) { - LogUtil.log(TAG, "DRC回复"+message); - sendMsg2Server(message); + if (Movement.getInstance().isOpendrc() == false) { + VirtualStickManager.getInstance().setVirtualStickAdvancedModeEnabled(true); + VirtualStickManager.getInstance().enableVirtualStick(new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + Movement.getInstance().setOpendrc(true); + if (message != null) { + LogUtil.log(TAG, "DRC回复" + message); + sendMsg2Server(message); + } + LogUtil.log(TAG, "控制权获取成功"); + VirtualStickManager.getInstance().setVirtualStickAdvancedModeEnabled(true); + //获得过控制权 + Movement.getInstance().setVirtualcontrollget(true); } - LogUtil.log(TAG, "控制权获取成功"); - VirtualStickManager.getInstance().setVirtualStickAdvancedModeEnabled(true); - //获得过控制权 - Movement.getInstance().setVirtualcontrollget(true); - } - @Override - public void onFailure(@NonNull IDJIError error) { - if (message != null) { - sendFailMsg2Server(message, "控制权获取失败:" + Utils.getIDJIErrorMsg(error)); + @Override + public void onFailure(@NonNull IDJIError error) { + if (message != null) { + sendFailMsg2Server(message, "控制权获取失败:" + Utils.getIDJIErrorMsg(error)); + } } - } - }); + }); - }else{ + } else { sendMsg2Server(message); } } + public void enableVirtualStick2() { + VirtualStickManager.getInstance().setVirtualStickAdvancedModeEnabled(true); + VirtualStickManager.getInstance().enableVirtualStick(new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + LogUtil.log(TAG, "控制权获取成功"); + } + + @Override + public void onFailure(@NonNull IDJIError error) { + LogUtil.log(TAG, "控制权获取失败"); + } + }); + + } + //取消虚拟摇杆控制权 public void disableVirtualStick(MessageDown message) { - if(Movement.getInstance().isVirtualcontrollget()==false){ + + + if (Movement.getInstance().isVirtualcontrollget() == false) { sendMsg2Server(message); return; } + + if (!getGimbalAndCameraEnabled()) { + return; + } + + VirtualStickManager.getInstance().disableVirtualStick(new CommonCallbacks.CompletionCallback() { @Override public void onSuccess() { if (message != null) { sendMsg2Server(message); - if(Movement.getInstance().getFlightmode()==1){ + if (Movement.getInstance().getFlightmode() == 1) { Movement.getInstance().setMode_code(5); - }else if(Movement.getInstance().getFlightmode()==2){ + } else if (Movement.getInstance().getFlightmode() == 2) { Movement.getInstance().setMode_code(3); } @@ -149,16 +173,34 @@ public class StickManager extends BaseManager { Movement.getInstance().setVirtualcontrollget(false); } + @Override public void onFailure(@NonNull IDJIError error) { - if (message!=null){ - sendFailMsg2Server(message,"控制权释放失败:"+ Utils.getIDJIErrorMsg(error)); + if (message != null) { + sendFailMsg2Server(message, "控制权释放失败:" + Utils.getIDJIErrorMsg(error)); } //LogUtil.log(TAG, "控制权释放失败:"+Utils.getIDJIErrorMsg(error)); } }); } + public void disableVirtualStick2() { + if (Movement.getInstance().isVirtualcontrollget() == false) { + return; + } + VirtualStickManager.getInstance().disableVirtualStick(new CommonCallbacks.CompletionCallback() { + @Override + public void onSuccess() { + LogUtil.log(TAG, "控制权已取消"); + } + + @Override + public void onFailure(@NonNull IDJIError error) { + LogUtil.log(TAG, "控制权释放失败:" + Utils.getIDJIErrorMsg(error)); + } + }); + } + //飞行控制权抢夺 public void setVirtualStickModeEnabled(MessageDown message) { //Movement.getInstance().setMode_code(3); @@ -169,7 +211,6 @@ public class StickManager extends BaseManager { }, 100); - ////// Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(FlightControllerKey.KeyConnection)); ////// if (isConnect != null && isConnect) { ////// FlightMode flightMode = KeyManager.getInstance().getValue(KeyTools.createKey(FlightControllerKey.KeyFlightMode)); @@ -252,32 +293,32 @@ public class StickManager extends BaseManager { public void sendVirtualStickAdvancedParam(MessageDown message) { Boolean isConnect = KeyManager.getInstance().getValue( KeyTools.createKey(FlightControllerKey.KeyConnection)); - if (isConnect != null && isConnect ) { - if (!getGimbalAndCameraEnabled()){ + if (isConnect != null && isConnect) { + if (!getGimbalAndCameraEnabled()) { return; } - if (!Movement.getInstance().isPlaneWing()){ - LogUtil.log(TAG,"飞机未起飞:禁止手控"); + if (!Movement.getInstance().isPlaneWing()) { + LogUtil.log(TAG, "飞机未起飞:禁止手控"); return; } VirtualStickFlightControlParam param = new VirtualStickFlightControlParam(); - param.setRollPitchControlMode(RollPitchControlMode.VELOCITY);// - param.setYawControlMode(YawControlMode.ANGULAR_VELOCITY); - param.setVerticalControlMode(VerticalControlMode.VELOCITY); - param.setRollPitchCoordinateSystem(FlightCoordinateSystem.BODY); + param.setRollPitchControlMode(RollPitchControlMode.VELOCITY);// + param.setYawControlMode(YawControlMode.ANGULAR_VELOCITY); + param.setVerticalControlMode(VerticalControlMode.VELOCITY); + param.setRollPitchCoordinateSystem(FlightCoordinateSystem.BODY); - if (!TextUtils.isEmpty(message.getData().getY())){ + if (!TextUtils.isEmpty(message.getData().getY())) { param.setPitch(Double.valueOf(message.getData().getY()));//左右(速度模式-10m/s-10m/s) } - if (!TextUtils.isEmpty(message.getData().getX())){ + if (!TextUtils.isEmpty(message.getData().getX())) { param.setRoll(Double.valueOf(message.getData().getX()));//前后(速度模式-10m/s-10m/s) } - if (!TextUtils.isEmpty(message.getData().getW())){ + if (!TextUtils.isEmpty(message.getData().getW())) { param.setYaw(Double.valueOf(message.getData().getW()));//旋转(角速度模式-100-100) } - if (!TextUtils.isEmpty(message.getData().getH())){ + if (!TextUtils.isEmpty(message.getData().getH())) { param.setVerticalThrottle(Double.valueOf(message.getData().getH()));//上下(速度模式-4m/s-4m/s) } @@ -299,11 +340,4 @@ public class StickManager extends BaseManager { // } - - - - - - - } diff --git a/app/src/main/java/com/aros/apron/manager/StreamManager.java b/app/src/main/java/com/aros/apron/manager/StreamManager.java index 82e5d720..a4686fdb 100644 --- a/app/src/main/java/com/aros/apron/manager/StreamManager.java +++ b/app/src/main/java/com/aros/apron/manager/StreamManager.java @@ -44,7 +44,7 @@ import dji.v5.manager.interfaces.ILiveStreamManager; public class StreamManager extends BaseManager { private static final String TAG = "StreamManager"; - // ========== 【新增】线程池和主线程Handler,防止ANR ========== + // ========== 【新增】线程池和主线程 Handler,防止 ANR ========== private final ExecutorService streamExecutor = Executors.newSingleThreadExecutor(); private final Handler mainHandler = new Handler(Looper.getMainLooper()); @@ -59,6 +59,14 @@ public class StreamManager extends BaseManager { return StreamHolder.INSTANCE; } + // ========== 【新增】重置推流状态,用于端口关闭后重启 ========== + public void resetStreamState() { + startLiveFailTimes = 0; + isLiveStreamAlreadyStart = false; + isStartingRTSP = false; // 重置并发标志 + LogUtil.log(TAG, "推流状态已重置"); + } + public void stopstream() { streamExecutor.execute(() -> { ILiveStreamManager liveStreamManager = MediaDataCenter.getInstance().getLiveStreamManager(); @@ -143,8 +151,9 @@ public class StreamManager extends BaseManager { private int startLiveFailTimes; private boolean isLiveStreamAlreadyStart; + private boolean isStartingRTSP = false; // 防止并发调用 - //知眸测试 + // 知眸测试 public void startLiveWithCustom() { streamExecutor.execute(() -> { Boolean isAircraftConnected = KeyManager.getInstance().getValue(DJIKey.create(ProductKey.KeyConnection)); @@ -203,13 +212,13 @@ public class StreamManager extends BaseManager { } - private int isliveindex = 1; //1代表port 2代表fpv + private int isliveindex = 1; //1 代表 port 2 代表 fpv public void switchptspfpv(ComponentIndexType ComponentIndex, MessageDown message) { isliveindex = 2; sendMsg2Server(message); ILiveStreamManager liveStreamManager = MediaDataCenter.getInstance().getLiveStreamManager(); - LogUtil.log(TAG, "切换RTSP推流fpv:" + PreferenceUtils.getInstance().getRtspUserName() + LogUtil.log(TAG, "切换 RTSP 推流 fpv:" + PreferenceUtils.getInstance().getRtspUserName() + "--" + PreferenceUtils.getInstance().getRtspPort() + "--" + PreferenceUtils.getInstance().getRtspPassWord()); LiveStreamSettings.Builder streamSettingBuilder = new LiveStreamSettings.Builder(); @@ -231,7 +240,7 @@ public class StreamManager extends BaseManager { isliveindex = 1; sendMsg2Server(message); ILiveStreamManager liveStreamManager = MediaDataCenter.getInstance().getLiveStreamManager(); - LogUtil.log(TAG, "切换RTSP推流port:" + PreferenceUtils.getInstance().getRtspUserName() + LogUtil.log(TAG, "切换 RTSP 推流 port:" + PreferenceUtils.getInstance().getRtspUserName() + "--" + PreferenceUtils.getInstance().getRtspPort() + "--" + PreferenceUtils.getInstance().getRtspPassWord()); LiveStreamSettings.Builder streamSettingBuilder = new LiveStreamSettings.Builder(); @@ -249,17 +258,48 @@ public class StreamManager extends BaseManager { liveStreamManager.setLiveVideoBitrateMode(LiveVideoBitrateMode.AUTO); } - // ========== 【核心修复】RTSP推流入口,全部在子线程执行 ========== + // ========== 【核心修复】RTSP 推流入口,全部在子线程执行 ========== public void startLiveWithRTSP() { + // 防止并发调用 + if (isStartingRTSP) { + LogUtil.log(TAG, "startLiveWithRTSP 正在执行中,忽略本次调用"); + return; + } + streamExecutor.execute(() -> { + isStartingRTSP = true; + + // 重置失败计数(每次新尝试时) + if (startLiveFailTimes == 0) { + LogUtil.log(TAG, "========== 开始 RTSP 推流流程 =========="); + } + Boolean isAircraftConnected = KeyManager.getInstance().getValue(DJIKey.create(FlightControllerKey.KeyConnection)); if (isAircraftConnected == null || !isAircraftConnected) { LogUtil.log(TAG, "飞行器未连接"); + isStartingRTSP = false; return; } - // 检查相机流是否准备好 + + ILiveStreamManager liveStreamManager = MediaDataCenter.getInstance().getLiveStreamManager(); + if (liveStreamManager == null) { + LogUtil.log(TAG, "LiveStreamManager 为 null"); + isStartingRTSP = false; + return; + } + + // 1. 检查是否已经在推流,避免重复启动 + if (liveStreamManager.isStreaming()) { + LogUtil.log(TAG, "RTSP 推流已在运行,无需重复启动"); + isLiveStreamAlreadyStart = true; + isStartingRTSP = false; + SimplePortScanner.getInstance().startScan(); // 确保端口扫描在运行 + return; + } + + // 2. 检查相机流是否准备好 if (!MainActivity.Companion.getStreamReceive()) { - LogUtil.log(TAG, "相机流未准备好,尝试切换FPVWidget恢复"); + LogUtil.log(TAG, "相机流未准备好,尝试切换 FPV Widget 恢复"); mainHandler.post(() -> { MainActivity mainActivity = MainActivity.Companion.getInstance(); if (mainActivity != null) { @@ -269,99 +309,88 @@ public class StreamManager extends BaseManager { mainHandler.postDelayed(() -> { streamExecutor.execute(() -> { - if (startLiveFailTimes < 2) { + if (startLiveFailTimes < 3) { startLiveFailTimes++; + LogUtil.log(TAG, "相机流未准备好,第" + startLiveFailTimes + "次重试"); startLiveWithRTSP(); } else { - forceStartLive(); LogUtil.log(TAG, "相机流未准备好,重试次数已达上限,强制启动"); + forceStartLive(); + isStartingRTSP = false; // 重置并发标志 } }); - }, 1500); + }, 2000); return; } - if (PreferenceUtils.getInstance().getRtspUserName() != null && - PreferenceUtils.getInstance().getRtspPort() != null && - PreferenceUtils.getInstance().getRtspPassWord() != null) { + // 3. 检查 RTSP 配置 + String rtspUser = PreferenceUtils.getInstance().getRtspUserName(); + String rtspPort = PreferenceUtils.getInstance().getRtspPort(); + String rtspPass = PreferenceUtils.getInstance().getRtspPassWord(); - ILiveStreamManager liveStreamManager = MediaDataCenter.getInstance().getLiveStreamManager(); - LogUtil.log(TAG, "自定义RTSP推流:" + PreferenceUtils.getInstance().getRtspUserName() - + "--" + PreferenceUtils.getInstance().getRtspPort() + "--" + PreferenceUtils.getInstance().getRtspPassWord()); - - // 设置参数在主线程执行(部分DJI API要求) - mainHandler.post(() -> { - if (isliveindex == 1) { - LiveStreamSettings.Builder streamSettingBuilder = new LiveStreamSettings.Builder(); - LiveStreamSettings streamSettings = streamSettingBuilder.setLiveStreamType(LiveStreamType.RTSP) - .setRtspSettings(new RtspSettings.Builder().setPassWord(PreferenceUtils.getInstance().getRtspPassWord()). - setPort(Integer.parseInt(PreferenceUtils.getInstance().getRtspPort())). - setUserName(PreferenceUtils.getInstance().getRtspUserName()).build()).build(); - - liveStreamManager.setLiveStreamSettings(streamSettings); - liveStreamManager.setCameraIndex(ComponentIndexType.PORT_1); - liveStreamManager.setLiveStreamQuality(StreamQuality.FULL_HD); - liveStreamManager.setLiveVideoBitrateMode(LiveVideoBitrateMode.AUTO); - } else { - LiveStreamSettings.Builder streamSettingBuilder = new LiveStreamSettings.Builder(); - LiveStreamSettings streamSettings = streamSettingBuilder.setLiveStreamType(LiveStreamType.RTSP) - .setRtspSettings(new RtspSettings.Builder().setPassWord(PreferenceUtils.getInstance().getRtspPassWord()). - setPort(Integer.parseInt(PreferenceUtils.getInstance().getRtspPort())). - setUserName(PreferenceUtils.getInstance().getRtspUserName()).build()).build(); - - liveStreamManager.setLiveStreamSettings(streamSettings); - liveStreamManager.setCameraIndex(ComponentIndexType.FPV); - liveStreamManager.setLiveStreamQuality(StreamQuality.FULL_HD); - liveStreamManager.setLiveVideoBitrateMode(LiveVideoBitrateMode.AUTO); - } - }); - - // 稍微等待设置生效 - try { - Thread.sleep(100); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - return; - } - - if (!liveStreamManager.isStreaming()) { - // 直接启动 - doStartLiveWithRTSP(liveStreamManager, false); - } else { - // 先停止再启动 - liveStreamManager.stopStream(new CommonCallbacks.CompletionCallback() { - @Override - public void onSuccess() { - // 在子线程延迟2秒,替代 Handler.postDelayed - try { - Thread.sleep(2000); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - return; - } - doStartLiveWithRTSP(liveStreamManager, true); - } - - @Override - public void onFailure(@NonNull IDJIError error) { - mainHandler.post(() -> { - LogUtil.log(TAG, "停止旧流失败:" + new Gson().toJson(error)); - // 即使停止失败也尝试启动 - streamExecutor.execute(() -> doStartLiveWithRTSP(liveStreamManager, true)); - }); - } - }); - } - } else { - LogUtil.log(TAG, "RTSP配置参数有误"); + if (rtspUser == null || rtspPort == null || rtspPass == null || + rtspUser.isEmpty() || rtspPort.isEmpty() || rtspPass.isEmpty()) { + LogUtil.log(TAG, "RTSP 配置参数有误:user=" + rtspUser + ", port=" + rtspPort); + isStartingRTSP = false; // 重置并发标志 + return; } + + LogUtil.log(TAG, "RTSP 配置检查通过:user=" + rtspUser + ", port=" + rtspPort + ", camera=" + (isliveindex == 1 ? "PORT_1" : "FPV")); + + // 4. 等待相机模式稳定(避免刚切换模式就推流) + try { + Thread.sleep(500); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + + // 5. 设置 RTSP 参数(在主线程执行) + final ILiveStreamManager finalLiveStreamManager = liveStreamManager; + mainHandler.post(() -> { + LiveStreamSettings.Builder streamSettingBuilder = new LiveStreamSettings.Builder(); + LiveStreamSettings streamSettings = streamSettingBuilder.setLiveStreamType(LiveStreamType.RTSP) + .setRtspSettings(new RtspSettings.Builder() + .setPassWord(rtspPass) + .setPort(Integer.parseInt(rtspPort)) + .setUserName(rtspUser) + .build()) + .build(); + + finalLiveStreamManager.setLiveStreamSettings(streamSettings); + + // 6. 设置相机源 + ComponentIndexType cameraIndex = (isliveindex == 1) ? ComponentIndexType.PORT_1 : ComponentIndexType.FPV; + finalLiveStreamManager.setCameraIndex(cameraIndex); + + // 7. 设置推流质量 + finalLiveStreamManager.setLiveStreamQuality(StreamQuality.FULL_HD); + finalLiveStreamManager.setLiveVideoBitrateMode(LiveVideoBitrateMode.AUTO); + + LogUtil.log(TAG, "RTSP 参数设置完成,等待 500ms 后启动推流"); + + // 8. 等待设置生效 + mainHandler.postDelayed(() -> { + streamExecutor.execute(() -> { + // 9. 启动推流前再次检查 + if (finalLiveStreamManager.isStreaming()) { + LogUtil.log(TAG, "推流已在运行,跳过启动"); + isLiveStreamAlreadyStart = true; + isStartingRTSP = false; // 重置并发标志 + SimplePortScanner.getInstance().startScan(); // 确保端口扫描在运行 + return; + } + + LogUtil.log(TAG, "开始调用 startStream..."); + doStartLiveWithRTSP(finalLiveStreamManager, false); + }); + }, 500); + }); }); } private void forceStartLive() { - streamExecutor.execute(() -> { if (PreferenceUtils.getInstance().getRtspUserName() != null && PreferenceUtils.getInstance().getRtspPort() != null && @@ -387,10 +416,11 @@ public class StreamManager extends BaseManager { @Override public void onSuccess() { mainHandler.post(() -> { - LogUtil.log(TAG, "强制启动RTSP推流成功"); + LogUtil.log(TAG, "强制启动 RTSP 推流成功"); MainActivity mainActivity = MainActivity.Companion.getInstance(); mainActivity.swapVideoSource(); isLiveStreamAlreadyStart = true; + isStartingRTSP = false; // 重置并发标志 SimplePortScanner.getInstance().startScan(); }); } @@ -398,24 +428,44 @@ public class StreamManager extends BaseManager { @Override public void onFailure(@NonNull IDJIError error) { mainHandler.post(() -> { - LogUtil.log(TAG, "强制启动RTSP推流失败:" + new Gson().toJson(error)); + LogUtil.log(TAG, "强制启动 RTSP 推流失败:" + new Gson().toJson(error)); + isStartingRTSP = false; // 重置并发标志 + // 失败后也尝试重置状态并重启 + resetStreamState(); }); } }); }); + } else { + LogUtil.log(TAG, "RTSP 配置参数有误,无法强制启动"); + isStartingRTSP = false; // 重置并发标志 } }); } // ========== 【新增】实际启动流的私有方法,确保在子线程执行 ========== private void doStartLiveWithRTSP(ILiveStreamManager liveStreamManager, boolean isRestart) { + // 启动前再次检查状态 + if (liveStreamManager.isStreaming()) { + LogUtil.log(TAG, "推流已在运行,跳过启动 (isRestart=" + isRestart + ")"); + isLiveStreamAlreadyStart = true; + isStartingRTSP = false; // 重置并发标志 + SimplePortScanner.getInstance().startScan(); // 确保端口扫描在运行 + return; + } + + LogUtil.log(TAG, "开始调用 startStream... (isRestart=" + isRestart + ")"); + liveStreamManager.startStream(new CommonCallbacks.CompletionCallback() { @Override public void onSuccess() { mainHandler.post(() -> { - LogUtil.log(TAG, "自定义RTSP推流启动成功" + (isRestart ? "(重启)" : "")); + LogUtil.log(TAG, "自定义 RTSP 推流启动成功" + (isRestart ? "(重启)" : "")); isliveindex = 1; isLiveStreamAlreadyStart = true; + startLiveFailTimes = 0; // 重置失败计数 + isStartingRTSP = false; // 重置并发标志 + LogUtil.log(TAG, "========== RTSP 推流启动成功 =========="); // 开始端口扫描 SimplePortScanner.getInstance().startScan(); }); @@ -424,20 +474,41 @@ public class StreamManager extends BaseManager { @Override public void onFailure(@NonNull IDJIError error) { mainHandler.post(() -> { - LogUtil.log(TAG, "第" + startLiveFailTimes + "次开始RTSP推流失败:" + new Gson().toJson(error)); + String detailedError = "第" + startLiveFailTimes + "次开始 RTSP 推流失败:type=" + error.errorType()+ ", code=" + error.errorCode() + ", hint=" + error.hint(); + LogUtil.log(TAG, detailedError); + LogUtil.log(TAG, "完整错误:" + new Gson().toJson(error)); + + // 错误类型判断 + if (error.hint() != null) { + if (error.hint().contains("CAMERA")) { + LogUtil.log(TAG, "[诊断] 相机相关错误:可能是相机模式不对/相机被占用/SD 卡异常"); + } else if (error.hint().contains("LIVE")) { + LogUtil.log(TAG, "[诊断] 推流相关错误:可能是推流配置问题/端口被占用"); + } else if (error.hint().contains("PORT") || error.hint().contains("port")) { + LogUtil.log(TAG, "[诊断] 端口相关错误:请检查 RTSP 端口是否被占用"); + } + } + if (!isLiveStreamAlreadyStart) { - // 延时3秒后重试,重试也提交到线程池 + // 延时 3 秒后重试,重试也提交到线程池 mainHandler.postDelayed(() -> { streamExecutor.execute(() -> { if (startLiveFailTimes < 10) { startLiveFailTimes++; + LogUtil.log(TAG, "准备第" + startLiveFailTimes + "次重试 RTSP 推流"); startLiveWithRTSP(); + } else { + LogUtil.log(TAG, "RTSP 推流重试次数已达上限 (10 次),放弃"); + LogUtil.log(TAG, "========== RTSP 推流失败 =========="); + isStartingRTSP = false; // 重置并发标志 } }); }, 3000); + } else { + isStartingRTSP = false; // 重置并发标志 } }); } }); } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/aros/apron/manager/TakeOffToPointManager.java b/app/src/main/java/com/aros/apron/manager/TakeOffToPointManager.java index 3c4439c4..80d9f836 100644 --- a/app/src/main/java/com/aros/apron/manager/TakeOffToPointManager.java +++ b/app/src/main/java/com/aros/apron/manager/TakeOffToPointManager.java @@ -314,6 +314,7 @@ public class TakeOffToPointManager extends BaseManager { @Override public void onSuccess() { Movement.getInstance().setWaylinename("takeofftopoint"); + PreferenceUtils.getInstance().setWaylinename("takeofftopoint"); //起飞准备完毕 Movement.getInstance().setMode_code(2); sendEvent2Server("航线上传成功,准备执行任务", 1); diff --git a/app/src/main/java/com/aros/apron/mix/Aprondown.java b/app/src/main/java/com/aros/apron/mix/Aprondown.java index 6aabc938..9f862574 100644 --- a/app/src/main/java/com/aros/apron/mix/Aprondown.java +++ b/app/src/main/java/com/aros/apron/mix/Aprondown.java @@ -657,7 +657,7 @@ public class Aprondown { private void performOperation() { LogUtil.log(TAG_LOG, "快速下拉中..." + handlerCallbackCount); - DroneHelper.getInstance().moveVxVyYawrateHeight(0f, 0f, 0f, -5); + DroneHelper.getInstance().moveVxVyYawrateHeight(0f, 0f, 0f, -5.5); handlerCallbackCount++; } diff --git a/app/src/main/java/com/aros/apron/mix/Aprongim.java b/app/src/main/java/com/aros/apron/mix/Aprongim.java index 66b57941..eb006a69 100644 --- a/app/src/main/java/com/aros/apron/mix/Aprongim.java +++ b/app/src/main/java/com/aros/apron/mix/Aprongim.java @@ -189,10 +189,10 @@ public class Aprongim { if(isDoublePayload){ if (ultHeight <=5) { - LENS_OFFSET_X=-125; + LENS_OFFSET_X=-130; LENS_OFFSET_Y=120; }else if(ultHeight<10){ - LENS_OFFSET_X=-85; + LENS_OFFSET_X=-90; LENS_OFFSET_Y=80; } else if (ultHeight<20) { LENS_OFFSET_X=-70; @@ -907,7 +907,7 @@ public class Aprongim { private void performOperation() { LogUtil.log(TAG_LOG, String.format("【执行移动】速降 vz=-4 count=%d/20", handlerCallbackCount)); - DroneHelper.getInstance().moveVxVyYawrateHeight(0f, 0f, 0f, -5); + DroneHelper.getInstance().moveVxVyYawrateHeight(0f, 0f, 0f, -5.5); handlerCallbackCount++; } diff --git a/app/src/main/java/com/aros/apron/tools/ApronArucoDetect.java b/app/src/main/java/com/aros/apron/tools/ApronArucoDetect.java index 79e2a266..87a414f7 100644 --- a/app/src/main/java/com/aros/apron/tools/ApronArucoDetect.java +++ b/app/src/main/java/com/aros/apron/tools/ApronArucoDetect.java @@ -86,6 +86,13 @@ public class ApronArucoDetect { // ========== 【新增】2帧一处理计数器 ========== private int frameCounter = 0; + // ========== 【新增】高度稳定性监测 ========== + private long lastHeightCheckTime = 0; + private double lastUltrasonicHeight = 0; + private static final long HEIGHT_STABLE_THRESHOLD = 45000; // 45秒 + private static final double HEIGHT_CHANGE_THRESHOLD =1; // 10厘米 + private boolean isHeightStableMonitoring = false; + // ========== 原有方法 ========== public int getCheckThrowingErrorsTimes() { return checkThrowingErrorsTimes; } public void setCheckThrowingErrorsTimes(int v) { checkThrowingErrorsTimes = v; } @@ -198,6 +205,55 @@ public class ApronArucoDetect { // 只保留6号码 ids = keepOnly6(ids, corners); + int ultHeight = Movement.getInstance().getUltrasonicHeight(); + + // ========== 【新增】高度稳定性监测 ========== + if (ultHeight > 0) { + if (!isHeightStableMonitoring) { + // 开始监测 + isHeightStableMonitoring = true; + lastHeightCheckTime = System.currentTimeMillis(); + lastUltrasonicHeight = ultHeight; + LogUtil.log(TAG_LOG, "开始监测高度稳定性,基准高度: " + ultHeight + " 分米"); + } else { + // 检查高度变化 + long currentTime = System.currentTimeMillis(); + double heightChange = Math.abs(ultHeight - lastUltrasonicHeight); + + if (heightChange > HEIGHT_CHANGE_THRESHOLD) { + // 高度有明显变化,重置计时器 + lastHeightCheckTime = currentTime; + lastUltrasonicHeight = ultHeight; + LogUtil.log(TAG_LOG, "高度变化: " + heightChange + " 分米,重置计时器"); + } else if (currentTime - lastHeightCheckTime > HEIGHT_STABLE_THRESHOLD) { + // 45秒内高度没有变动,执行复降 + LogUtil.log(TAG_LOG, "45秒内高度未变动,执行复降"); + + if (ultHeight <= 20) { + DroneHelper.getInstance().moveVxVyYawrateHeight(0f, 0f, 0f, 3f); + if (dropTimes > Integer.parseInt(AMSConfig.getInstance().getAlternateLandingTimes())) { + LogUtil.log(TAG_LOG, "超过复降限制,去备降点"); + AlternateLandingManager.getInstance().startTaskProcess(null); + Movement.getInstance().setAlternate(true); + return; + } + if (dropTimesTag) { + dropTimesTag = false; + dropTimes++; + LogUtil.log(TAG_LOG, "复降第:" + dropTimes + "次"); + } + } else { + LogUtil.log(TAG_LOG, "执行位移"); + DroneHelper.getInstance().moveVxVyYawrateHeight(0f, 0f, 0f, -0.3f); + } + + isHeightStableMonitoring = false; + isStartAruco = false; + return; + } + } + } + boolean marker6Found = false; if (!ids.empty()) { trycount = 0; @@ -437,6 +493,10 @@ public class ApronArucoDetect { isStartAruco = false; consecutiveTriggerCount = 0; frameCounter = 0; // 【新增】重置帧计数 + // 【新增】重置高度稳定性监测状态 + isHeightStableMonitoring = false; + lastHeightCheckTime = 0; + lastUltrasonicHeight = 0; } @@ -575,7 +635,7 @@ public class ApronArucoDetect { private void performOperation() { LogUtil.log(TAG_LOG, "快速下拉中..." + handlerCallbackCount); - DroneHelper.getInstance().moveVxVyYawrateHeight(0f, 0f, 0f, -5); + DroneHelper.getInstance().moveVxVyYawrateHeight(0f, 0f, 0f, -5.5); handlerCallbackCount++; } diff --git a/app/src/main/java/com/aros/apron/tools/ApronArucoDetectPort.java b/app/src/main/java/com/aros/apron/tools/ApronArucoDetectPort.java index dc7fa2f4..94d7e8e0 100644 --- a/app/src/main/java/com/aros/apron/tools/ApronArucoDetectPort.java +++ b/app/src/main/java/com/aros/apron/tools/ApronArucoDetectPort.java @@ -77,6 +77,13 @@ public class ApronArucoDetectPort { // 记录上一帧满足的降落条件类型:0=无, 1=单码精准降落(15/17号), 2=几何中心降落 private int lastLandingCondition = 0; + // ========== 【新增】高度稳定性监测 ========== + private long lastHeightCheckTime = 0; + private double lastUltrasonicHeight = 0; + private static final long HEIGHT_STABLE_THRESHOLD = 45000; // 45秒 + private static final double HEIGHT_CHANGE_THRESHOLD = 1; // 10厘米 + private boolean isHeightStableMonitoring = false; + // ========== 标准方法 ========== public int getCheckThrowingErrorsTimes() { return checkThrowingErrorsTimes; } public void setCheckThrowingErrorsTimes(int v) { checkThrowingErrorsTimes = v; } @@ -170,10 +177,10 @@ public class ApronArucoDetectPort { if(isDoublePayload){ if (ultHeight <=5) { - LENS_OFFSET_X=-125; + LENS_OFFSET_X=-130; LENS_OFFSET_Y=120; }else if(ultHeight<10){ - LENS_OFFSET_X=-85; + LENS_OFFSET_X=-90; LENS_OFFSET_Y=80; } else if (ultHeight<20) { LENS_OFFSET_X=-70; @@ -214,6 +221,51 @@ public class ApronArucoDetectPort { int ultHeight=Movement.getInstance().getUltrasonicHeight(); + // ========== 【新增】高度稳定性监测 ========== + if (ultHeight > 0) { + if (!isHeightStableMonitoring) { + // 开始监测 + isHeightStableMonitoring = true; + lastHeightCheckTime = System.currentTimeMillis(); + lastUltrasonicHeight = ultHeight; + LogUtil.log(TAG_LOG, "开始监测高度稳定性,基准高度: " + ultHeight + " 分米"); + } else { + // 检查高度变化 + long currentTime = System.currentTimeMillis(); + double heightChange = Math.abs(ultHeight - lastUltrasonicHeight); + + if (heightChange > HEIGHT_CHANGE_THRESHOLD) { + // 高度有明显变化,重置计时器 + lastHeightCheckTime = currentTime; + lastUltrasonicHeight = ultHeight; + LogUtil.log(TAG_LOG, "高度变化: " + heightChange + " 分米,重置计时器"); + } else if (currentTime - lastHeightCheckTime > HEIGHT_STABLE_THRESHOLD) { + + if (ultHeight<= 20) { + DroneHelper.getInstance().moveVxVyYawrateHeight(0f, 0f, 0f, 3f); + if (dropTimes > Integer.parseInt(AMSConfig.getInstance().getAlternateLandingTimes())) { + LogUtil.log(TAG_LOG, "超过复降限制,去备降点"); + AlternateLandingManager.getInstance().startTaskProcess(null); + Movement.getInstance().setAlternate(true); + return; + } + if (dropTimesTag) { + dropTimesTag = false; + dropTimes++; + LogUtil.log(TAG_LOG, "复降第:" + dropTimes + "次"); + } + } else { + LogUtil.log(TAG_LOG, "执行位移"); + DroneHelper.getInstance().moveVxVyYawrateHeight(0f, 0f, 0f, -0.3f); + } + + isHeightStableMonitoring = false; + isStartAruco = false; + return; + } + } + } + if (!ids.empty()) { trycount = 0; arucoNotFoundTag = false; @@ -796,6 +848,10 @@ public class ApronArucoDetectPort { isYawAligned = false; currentLandingMode = 0; lastLandingCondition = 0; + // 【新增】重置高度稳定性监测状态 + isHeightStableMonitoring = false; + lastHeightCheckTime = 0; + lastUltrasonicHeight = 0; } private int handlerCallbackCount = 0; @@ -814,7 +870,7 @@ public class ApronArucoDetectPort { private void performOperation() { LogUtil.log(TAG_LOG, String.format("【执行移动】速降 vz=-4 count=%d/20", handlerCallbackCount)); - DroneHelper.getInstance().moveVxVyYawrateHeight(0f, 0f, 0f, -5); + DroneHelper.getInstance().moveVxVyYawrateHeight(0f, 0f, 0f, -5.5); handlerCallbackCount++; } diff --git a/app/src/main/java/com/aros/apron/tools/DroneHelper.java b/app/src/main/java/com/aros/apron/tools/DroneHelper.java index d1ccb150..1c10cf53 100644 --- a/app/src/main/java/com/aros/apron/tools/DroneHelper.java +++ b/app/src/main/java/com/aros/apron/tools/DroneHelper.java @@ -24,6 +24,8 @@ import dji.sdk.keyvalue.value.flightcontroller.VirtualStickFlightControlParam; import dji.sdk.keyvalue.value.flightcontroller.YawControlMode; import dji.sdk.keyvalue.value.gimbal.GimbalAngleRotation; import dji.sdk.keyvalue.value.gimbal.GimbalAngleRotationMode; +import dji.sdk.keyvalue.value.gimbal.GimbalMode; +import dji.sdk.keyvalue.value.gimbal.GimbalResetType; import dji.v5.common.callback.CommonCallbacks; import dji.v5.common.error.IDJIError; import dji.v5.manager.KeyManager; @@ -48,6 +50,7 @@ public class DroneHelper { public static DroneHelper getInstance() { return DroneHelperHolder.INSTANCE; } + private boolean isExitInProgress = false; // 新增标志 // DroneHelper.java @@ -158,22 +161,23 @@ public class DroneHelper { } - public void setCameraFocusMode(){ + public void setCameraFocusMode() { Boolean cameraConnect = KeyManager.getInstance().getValue(KeyTools.createKey(CameraKey. KeyConnection, ComponentIndexType.PORT_1)); - if (cameraConnect!=null&&cameraConnect) { + if (cameraConnect != null && cameraConnect) { KeyManager.getInstance().setValue(KeyTools.createCameraKey(CameraKey.KeyCameraFocusMode, ComponentIndexType.PORT_1, CameraLensType.CAMERA_LENS_WIDE), CameraFocusMode.AFC, new CommonCallbacks.CompletionCallback() { @Override public void onSuccess() { - LogUtil.log(TAG, "设置对焦模式自动对焦"); + LogUtil.log(TAG, "设置对焦模式自动对焦"); } + @Override public void onFailure(@NonNull IDJIError idjiError) { - LogUtil.log(TAG, "设置对焦模式自动对焦失败:"+new Gson().toJson(idjiError)); + LogUtil.log(TAG, "设置对焦模式自动对焦失败:" + new Gson().toJson(idjiError)); } }); - }else { + } else { LogUtil.log(TAG, "相机未连接"); } } @@ -181,10 +185,10 @@ public class DroneHelper { private int setGimbalPitchDegreeFailTimes = 0; private boolean isGimbalPitchDegree = false; - public void setGimbalPitchdown(){ + public void setGimbalPitchdown() { Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(GimbalKey. KeyConnection, ComponentIndexType.PORT_1)); - if (isConnect!=null&&isConnect) { + if (isConnect != null && isConnect) { GimbalAngleRotation rotation = new GimbalAngleRotation(); rotation.setMode(GimbalAngleRotationMode.ABSOLUTE_ANGLE); rotation.setYaw(0.0); @@ -212,7 +216,7 @@ public class DroneHelper { // PayloadWidgetManager.getInstance().sendMsgToLeftPayload("#TPPG2wPTZ0A76"); Boolean isConnect = KeyManager.getInstance().getValue(KeyTools.createKey(GimbalKey. KeyConnection, ComponentIndexType.PORT_1)); - if (isConnect!=null&&isConnect) { + if (isConnect != null && isConnect) { GimbalAngleRotation rotation = new GimbalAngleRotation(); rotation.setMode(GimbalAngleRotationMode.ABSOLUTE_ANGLE); rotation.setYaw(0.0); @@ -222,8 +226,8 @@ public class DroneHelper { @Override public void onSuccess(EmptyMsg emptyMsg) { LogUtil.log(TAG, "云台朝下"); - isGimbalPitchDegree=true; - setGimbalPitchDegreeFailTimes=0; + isGimbalPitchDegree = true; + setGimbalPitchDegreeFailTimes = 0; } @Override @@ -239,8 +243,9 @@ public class DroneHelper { retryGimbalPitchDegree(); } } - private void retryGimbalPitchDegree(){ - if (!isGimbalPitchDegree){ + + private void retryGimbalPitchDegree() { + if (!isGimbalPitchDegree) { new Handler().postDelayed(new Runnable() { @Override public void run() { @@ -265,10 +270,12 @@ public class DroneHelper { virtualStickFlightControlParam.setVerticalThrottle(mThrottle);//上下 sendMovementCommand(virtualStickFlightControlParam); } + public boolean shouldExecute = true; + public void sendMovementCommand(VirtualStickFlightControlParam param) { // if (shouldExecute) { - VirtualStickManager.getInstance().sendVirtualStickAdvancedParam(param); + VirtualStickManager.getInstance().sendVirtualStickAdvancedParam(param); // } // shouldExecute = !shouldExecute; } diff --git a/app/src/main/java/com/aros/apron/tools/PreferenceUtils.java b/app/src/main/java/com/aros/apron/tools/PreferenceUtils.java index 656dd7d5..01b892ed 100644 --- a/app/src/main/java/com/aros/apron/tools/PreferenceUtils.java +++ b/app/src/main/java/com/aros/apron/tools/PreferenceUtils.java @@ -30,6 +30,16 @@ public class PreferenceUtils extends BasePreference { private String TRIGGER_TO_ALTERNATE_POINT = "trigger_to_alternate_point";//是否需要触发crash后继续降落 private String FIRST_MISSION_RECEIVED = "first_mission_received";//是否第一次收到航线指令 + private String waylinename; //航线名字 + + public String getWaylinename() { + return waylinename; + } + + public void setWaylinename(String waylinename) { + this.waylinename = waylinename; + } + //AMS配置清单 private String HAVA_RTK = "have_rtk"; private String SATELLITE_SYSTEM = "satellite_system"; diff --git a/app/src/main/java/com/aros/apron/tools/SimplePortScanner.java b/app/src/main/java/com/aros/apron/tools/SimplePortScanner.java index 162f7b42..35269e06 100644 --- a/app/src/main/java/com/aros/apron/tools/SimplePortScanner.java +++ b/app/src/main/java/com/aros/apron/tools/SimplePortScanner.java @@ -2,26 +2,71 @@ package com.aros.apron.tools; import android.os.Handler; import android.os.Looper; +import android.util.Log; + +import com.aros.apron.manager.StreamManager; + import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; -import java.util.Timer; -import java.util.TimerTask; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; /** - * 极简版:每3秒检测一次本地8554端口是否开启 - * 参数别改:回调已强制切到主线程,可直接操作UI + * 极简版:每 3 秒检测一次本地 8554 端口是否开启 + * 参数别改:回调已强制切到主线程,可直接操作 UI */ public class SimplePortScanner { + private static final String TAG = "SimplePortScanner"; private static final int CHECK_PORT = 8554; private static final String LOCAL_HOST = "127.0.0.1"; + + // 连续关闭次数,超过阈值后重启推流 + private int closedCount = 0; + private static final int MAX_CLOSED_COUNT = 3; // 连续 3 次关闭后重启 private static final long SCAN_INTERVAL = 3000L; private static final int CONNECT_TIMEOUT = 500; - private Timer scanTimer; private OnPortCheckListener checkListener; - // 主线程 Handler,用于切换回调到UI线程 + // 主线程 Handler,用于切换回调到 UI 线程和定时扫描 private final Handler mainHandler = new Handler(Looper.getMainLooper()); + // 后台线程池,用于执行网络请求 + private final ExecutorService executor = Executors.newSingleThreadExecutor(); + + // 扫描任务 + private final Runnable scanRunnable = new Runnable() { + @Override + public void run() { + // 在后台线程执行网络请求 + executor.execute(() -> { + final boolean isOpen = checkPort(LOCAL_HOST, CHECK_PORT); + // 结果贴回主线程 + mainHandler.post(() -> { + if (isOpen) { + closedCount = 0; // 重置计数 + if (checkListener != null) { + checkListener.onPortOpen(); + } + } else { + closedCount++; + Log.i(TAG, "端口关闭次数:" + closedCount + "/" + MAX_CLOSED_COUNT); + if (closedCount >= MAX_CLOSED_COUNT) { + Log.i(TAG, "端口连续关闭 " + closedCount + " 次,尝试重启 RTSP 推流"); + closedCount = 0; // 重置计数 + // 先重置状态,让 startLiveWithRTSP 能真正执行 + StreamManager.getInstance().resetStreamState(); + StreamManager.getInstance().startLiveWithRTSP(); + } + if (checkListener != null) { + checkListener.onPortClosed(); + } + } + // 延迟 3 秒后继续扫描 + mainHandler.postDelayed(this, SCAN_INTERVAL); + }); + }); + } + }; public interface OnPortCheckListener { void onPortOpen(); @@ -44,30 +89,13 @@ public class SimplePortScanner { public void startScan() { stopScan(); - scanTimer = new Timer(); - scanTimer.scheduleAtFixedRate(new TimerTask() { - @Override - public void run() { - final boolean isOpen = checkPort(LOCAL_HOST, CHECK_PORT); - // 关键修改:切到主线程回调 - mainHandler.post(() -> { - if (checkListener != null) { - if (isOpen) { - checkListener.onPortOpen(); - } else { - checkListener.onPortClosed(); - } - } - }); - } - }, 0, SCAN_INTERVAL); + closedCount = 0; // 重置计数 + // 立即执行一次,然后延迟 3 秒循环 + mainHandler.post(scanRunnable); } public void stopScan() { - if (scanTimer != null) { - scanTimer.cancel(); - scanTimer = null; - } + mainHandler.removeCallbacks(scanRunnable); } private boolean checkPort(String host, int port) { @@ -78,4 +106,4 @@ public class SimplePortScanner { return false; } } -} \ No newline at end of file +} diff --git a/app/src/main/res/layout-land/activity_main.xml b/app/src/main/res/layout-land/activity_main.xml index 9bd4daec..39f407e0 100644 --- a/app/src/main/res/layout-land/activity_main.xml +++ b/app/src/main/res/layout-land/activity_main.xml @@ -299,29 +299,22 @@ tools:ignore="MissingConstraints">