diff --git a/app/build.gradle b/app/build.gradle
index 6ce823b..9589003 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -71,6 +71,8 @@ dependencies {
implementation 'com.squareup.okhttp3:okhttp:4.10.0'
implementation 'com.squareup.okio:okio:3.2.0'
+ implementation 'com.google.code.gson:gson:2.10.1'
+
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a366c75..f5c1a85 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -8,7 +8,8 @@
-
+
@@ -57,6 +58,7 @@
diff --git a/app/src/main/java/com/example/longyi_groundstation/Login/Activity/LoginActivity.java b/app/src/main/java/com/example/longyi_groundstation/Login/Activity/LoginActivity.java
index 1b2ae02..5b72078 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Login/Activity/LoginActivity.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Login/Activity/LoginActivity.java
@@ -98,12 +98,7 @@ public class LoginActivity extends AppCompatActivity {
}
});
-// allView.rb_bt1.setOnClickListener(v -> {
-// type = 0;
-// });
-// allView.rb_bt2.setOnClickListener(v -> {
-// type = 1;
-// });
+
}
@@ -114,4 +109,6 @@ public class LoginActivity extends AppCompatActivity {
}
+
+
}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/longyi_groundstation/Login/Void/UrlVoid.java b/app/src/main/java/com/example/longyi_groundstation/Login/Void/UrlVoid.java
new file mode 100644
index 0000000..fa34b65
--- /dev/null
+++ b/app/src/main/java/com/example/longyi_groundstation/Login/Void/UrlVoid.java
@@ -0,0 +1,63 @@
+package com.example.longyi_groundstation.Login.Void;
+
+import static androidx.core.content.ContextCompat.startActivity;
+import static com.example.longyi_groundstation.Util.Http.HttpUrl.LOGIN;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+
+import com.example.longyi_groundstation.Funcation.Activity.FuncationActivity;
+import com.example.longyi_groundstation.Util.Http.HttpUtil;
+import com.example.longyi_groundstation.Util.SharedPreferencesTool;
+
+import org.json.JSONObject;
+
+import java.io.IOException;
+
+import okhttp3.Call;
+import okhttp3.Response;
+
+public class UrlVoid {
+
+ public static HttpUtil httpUtil = new HttpUtil();
+
+ private void Login(Activity activity, EditText et_username, EditText et_password) {
+ httpUtil.postForm(
+ LOGIN,
+ "mobile=" + et_username.getText().toString() +
+ "&password=" + et_password.getText().toString(),
+ null, new okhttp3.Callback() {
+ @Override
+ public void onFailure(@NonNull Call call, @NonNull IOException e) {
+
+ }
+
+ @Override
+ public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ String json = response.body().string();
+ JSONObject jsonObject = new JSONObject(json);
+ if (jsonObject.getInt("code") == 1) {
+ SharedPreferencesTool.saveLogin(activity, jsonObject.getJSONObject("data"));
+ activity.startActivity(new Intent(activity, FuncationActivity.class));
+ activity.finish();
+ } else {
+ Toast.makeText(activity, "账号密码错误", Toast.LENGTH_SHORT).show();
+ }
+ } catch (Exception e) {
+ Toast.makeText(activity, "网络解析错误", Toast.LENGTH_SHORT).show();
+ }
+ }
+ });
+ }
+ });
+ }
+
+}
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/Activity/MainActivity.java b/app/src/main/java/com/example/longyi_groundstation/Main/Activity/MainActivity.java
index 26b8022..987e0f8 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Main/Activity/MainActivity.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/Activity/MainActivity.java
@@ -69,6 +69,7 @@ import com.example.longyi_groundstation.Main.Adapter.TypeAdapter;
import com.example.longyi_groundstation.Main.Base.CreateLink;
import com.example.longyi_groundstation.Main.Base.LogItem;
import com.example.longyi_groundstation.Main.Base.Msg;
+import com.example.longyi_groundstation.Main.Click.MainClick;
import com.example.longyi_groundstation.Main.Service.MyBoundService;
import com.example.longyi_groundstation.Main.Setting.Activity.SettingActivity;
import com.example.longyi_groundstation.Main.View.BombingDialog;
@@ -89,6 +90,7 @@ import com.example.longyi_groundstation.Main.Void.CoordinateConverter;
import com.example.longyi_groundstation.Main.Void.FlyVoid;
import com.example.longyi_groundstation.Main.Void.FpvGestureHandler;
import com.example.longyi_groundstation.Main.Void.KeDaTTS;
+import com.example.longyi_groundstation.Main.Void.LidarDataParser;
import com.example.longyi_groundstation.Main.Void.MapVoid;
import com.example.longyi_groundstation.Main.Void.MyReceiver;
import com.example.longyi_groundstation.Main.Void.MyTool;
@@ -131,21 +133,18 @@ public class MainActivity extends AppCompatActivity {
//地图方法
private MapVoid mapVoid;
//广播接收器
- private MyReceiver myReceiver_ATTITUDE, myReceiver_GPS_RAW_INT, myReceiver_GLOBAL_POSITION_INT,
- myReceiver_POWER_STATUS, myReceiver_SYS_STATUS, myReceiver_STATUSTEXT,
- myReceiver_HEARTBEAT, myReceiver_VFR_HUD, myReceiver_MISSION_REQUEST, myReceiver_MISSION_ACK,
- myReceiver_MISSION_CURRENT;
+ private MyReceiver myReceiver_ATTITUDE, myReceiver_GPS_RAW_INT, myReceiver_GLOBAL_POSITION_INT, myReceiver_POWER_STATUS, myReceiver_SYS_STATUS, myReceiver_STATUSTEXT, myReceiver_HEARTBEAT, myReceiver_VFR_HUD, myReceiver_MISSION_REQUEST, myReceiver_MISSION_ACK, myReceiver_MISSION_CURRENT;
//所有组件
private AllView allView;
private ArrayList typeList = new ArrayList<>();
private TypeAdapter typeAdapter;
- private TakeOffDialog takeOffDialog;//起飞弹窗
- private TurnBackDialog turnBackDialog;//返航弹窗
- private LandDialog landDialog;//降落弹窗
- private BombingDialog bombingDialog;//投弹弹窗
- private PointFlyDialog pointFlyDialog;//指点飞行弹窗
+ public TakeOffDialog takeOffDialog;//起飞弹窗
+ public TurnBackDialog turnBackDialog;//返航弹窗
+ public LandDialog landDialog;//降落弹窗
+ public BombingDialog bombingDialog;//投弹弹窗
+ public PointFlyDialog pointFlyDialog;//指点飞行弹窗
public static StartExecuteDialog startExecuteDialog;//开始执行弹窗
- private SaveLinkNameDialog saveLinkNameDialog;//二次确认路线名称弹窗
+ public SaveLinkNameDialog saveLinkNameDialog;//二次确认路线名称弹窗
private ArrayList LogItemList = new ArrayList<>();
private LogAdapter adapter;
private FPV_Void fpvVoid = new FPV_Void();
@@ -154,7 +153,7 @@ public class MainActivity extends AppCompatActivity {
private Marker mainMarker;
private FlyVoid flyVoid = new FlyVoid();
private boolean islocation = true;//是否第一次定位
- private LatLng homeLatLng = null;
+ public static LatLng homeLatLng = null;
private FpvGestureHandler fpvGestureHandler; // 云台手势类
private TcpClientUtil tcpClient;//云台连接类
@@ -174,6 +173,10 @@ public class MainActivity extends AppCompatActivity {
private AllLinkAdapter allLinkAdapter;
private SQLClass sqlClass;
private List linkListInfoList;
+ public static double[] doubles;
+ private Marker orangeMarker = null;//指点飞行图标
+ private int isAddOrEdit = 0;//0:添加 1:编辑
+ private Marker selectMarker;//当前选中的航点marker
@Override
@@ -187,11 +190,19 @@ public class MainActivity extends AppCompatActivity {
return insets;
});
+ // 关键初始化保留在主线程
initData();
initView();
initReceiver();
+
+ // 异步初始化非关键组件
+ new Thread(() -> {
+ LidarDataParser.startHeightUpdate(allView.tv_height);
+ mapVoid.startFlightTracking();
+ }).start();
+
+ // 用户交互相关的初始化保留在主线程
initOnClick();
- mapVoid.startFlightTracking();
}
@@ -364,8 +375,10 @@ public class MainActivity extends AppCompatActivity {
typeAdapter = new TypeAdapter(typeList);
allView.rv_type_list.setAdapter(typeAdapter);
- // 设置视频路径
- fpvVoid.setupFpvWidget(allView.fpvWidget, "rtsp://192.168.144.119/live");
+ // 延迟初始化FPV视频流
+ allView.fpvWidget.post(() -> {
+ fpvVoid.setupFpvWidget(allView.fpvWidget, "rtsp://192.168.144.119/live");
+ });
// 初始化FPV手势处理
//起飞弹窗
@@ -425,15 +438,15 @@ public class MainActivity extends AppCompatActivity {
//广播接收-ATTITUDE
myReceiver_ATTITUDE.setATTITUDEListener(data -> {
// 这里可以更新 UI 或刷新数据
- Log.d(TAG, "收到新数据ATTITUDE:" +MyReceiver.ATTITUDE_json.optDouble("yaw"));
+// Log.d(TAG, "收到新数据ATTITUDE:" +MyReceiver.ATTITUDE_json.optDouble("yaw"));
// allView.tv_connect.setText("已连接");
// 示例:更新 typeList 数据并刷新 RecyclerView
if (data != null) {
- flyVoid.setAttitude(getApplicationContext(), allView, MyReceiver.ATTITUDE_json.optDouble("roll"), MyReceiver.ATTITUDE_json.optDouble("pitch"),(int) Math.round(MyReceiver.ATTITUDE_json.optDouble("yaw") * 57.3));
+ flyVoid.setAttitude(getApplicationContext(), allView, MyReceiver.ATTITUDE_json.optDouble("roll"), MyReceiver.ATTITUDE_json.optDouble("pitch"), (int) Math.round(MyReceiver.ATTITUDE_json.optDouble("yaw") * 57.3));
}
//地图上飞机的朝向
- mainMarker.setRotateAngle( (int) Math.round(MyReceiver.ATTITUDE_json.optDouble("yaw")* 57.3) * -1);
+ mainMarker.setRotateAngle((int) Math.round(MyReceiver.ATTITUDE_json.optDouble("yaw") * 57.3) * -1);
allView.tv_yaw.setText((int) Math.round(MyReceiver.ATTITUDE_json.optDouble("yaw") * 57.3) + "°");
mainMarker.setVisible(true);
@@ -455,20 +468,14 @@ public class MainActivity extends AppCompatActivity {
// Log.d(TAG, "收到新数据GLOBAL:" + data.toString());
//要把经纬度转换成高德经纬度
- double[] doubles = CoordinateConverter.wgs84ToGcj02(
- (MyReceiver.GLOBAL_POSITION_INT_json.optDouble("lon", 0) / 10000000),
- (MyReceiver.GLOBAL_POSITION_INT_json.optDouble("lat", 0) / 10000000));
+ doubles = CoordinateConverter.wgs84ToGcj02((MyReceiver.GLOBAL_POSITION_INT_json.optDouble("lon", 0) / 10000000), (MyReceiver.GLOBAL_POSITION_INT_json.optDouble("lat", 0) / 10000000));
if (doubles[1] != 0) {
//获取到位置后移动视角到当前位置
if (islocation) {
// 移动视图到Marker点
- mapVoid.aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
- new LatLng(
- MyReceiver.GLOBAL_POSITION_INT_json.optDouble("lat", 0) / 10000000,
- MyReceiver.GLOBAL_POSITION_INT_json.optDouble("lon", 0) / 10000000),
- 15)); // 15是缩放级别
+ mapVoid.aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(MyReceiver.GLOBAL_POSITION_INT_json.optDouble("lat", 0) / 10000000, MyReceiver.GLOBAL_POSITION_INT_json.optDouble("lon", 0) / 10000000), 15)); // 15是缩放级别
islocation = false;
homeLatLng = new LatLng(doubles[1], doubles[0]);
}
@@ -488,11 +495,6 @@ public class MainActivity extends AppCompatActivity {
// 添加更多字段...
typeAdapter.notifyDataSetChanged();
- if (FlyVoid.parseSerialData != null) {
-// allView.tv_height.setText(Math.round((MyReceiver.GLOBAL_POSITION_INT_json.optDouble("relative_alt") / 100) / 10.0) + "m");
-// Toast.makeText(this, flyVoid.parseSerialData[0]+"", Toast.LENGTH_SHORT).show();
- allView.tv_height.setText(flyVoid.parseSerialData[0] + "m");
- }
}
//如果有相同的点位就不添加到列表里面去
@@ -513,14 +515,14 @@ public class MainActivity extends AppCompatActivity {
});
- //广播接收-setPowrStatuslistener
- myReceiver_POWER_STATUS.setPowrStatuslistener(data -> {
- // 这里可以更新 UI 或刷新数据
-// Log.d(TAG, "收到新数据POWER_STATUS:" + data.toString());
-// allView.tv_power.setText(
-// MyReceiver.POWER_STATUS_json.optDouble("Vcc") / 100
-// + " V");
- });
+// //广播接收-setPowrStatuslistener
+// myReceiver_POWER_STATUS.setPowrStatuslistener(data -> {
+// // 这里可以更新 UI 或刷新数据
+//// Log.d(TAG, "收到新数据POWER_STATUS:" + data.toString());
+//// allView.tv_power.setText(
+//// MyReceiver.POWER_STATUS_json.optDouble("Vcc") / 100
+//// + " V");
+// });
//广播接收-setSysStatuslistener
myReceiver_SYS_STATUS.setSysStatuslistener(data -> {
@@ -533,11 +535,7 @@ public class MainActivity extends AppCompatActivity {
myReceiver_STATUSTEXT.setStatustextlistener(data -> {
// 这里可以更新 UI 或刷新数据
if (MyReceiver.STATUSTEXT_json.optInt("severity") <= 5) {
- LogItemList.add(0, new LogItem(
- MyReceiver.STATUSTEXT_json.optString("text"),
- ContrastTool.findMostSimilarMatch(MyReceiver.STATUSTEXT_json.optString("text")),
- new Date(),
- MyReceiver.STATUSTEXT_json.optInt("severity")));
+ LogItemList.add(0, new LogItem(MyReceiver.STATUSTEXT_json.optString("text"), ContrastTool.findMostSimilarMatch(MyReceiver.STATUSTEXT_json.optString("text")), new Date(), MyReceiver.STATUSTEXT_json.optInt("severity")));
adapter.setList(LogItemList);
allView.iv_error.setVisibility(VISIBLE);
}
@@ -551,7 +549,7 @@ public class MainActivity extends AppCompatActivity {
isUnlock = Tool.getDecToFirstBin(MyReceiver.HEARTBEAT_json.optString("base_mode")).equals("1");
if (allView.ll_link_start.getVisibility() == VISIBLE) {
- Log.d(TAG, "myReceiver_HEARTBEAT: " + data.toString());
+// Log.d(TAG, "myReceiver_HEARTBEAT: " + data.toString());
//判断飞控是否解锁
if (Tool.getDecToFirstBin(MyReceiver.HEARTBEAT_json.optString("base_mode")).equals("1")) {
//已解锁
@@ -589,7 +587,7 @@ public class MainActivity extends AppCompatActivity {
allView.tv_connect.setText("定点模式");
break;
case 6:
- allView.tv_connect.setText("返航模式");
+ allView.tv_connect.setText("返航");
break;
case 7:
allView.tv_connect.setText("环绕模式");
@@ -624,33 +622,27 @@ public class MainActivity extends AppCompatActivity {
// 1
// )));
if (data.optDouble("throttle") > 0) {
- typeList.set(2, new Msg("throttle", String.format("%.1f", MyTool.getThrottle(
- Double.parseDouble(FlyVoid.paramList.get("MOT_SPIN_MIN").getParam_value()),
- Double.parseDouble(FlyVoid.paramList.get("MOT_SPIN_MAX").getParam_value()),
- Double.parseDouble(FlyVoid.paramList.get("MOT_THST_EXPO").getParam_value()),
- data.optDouble("throttle") / 100,
- 1
- ) * 100) + "%", true));
+ typeList.set(2, new Msg("throttle", String.format("%.1f", MyTool.getThrottle(Double.parseDouble(FlyVoid.paramList.get("MOT_SPIN_MIN").getParam_value()), Double.parseDouble(FlyVoid.paramList.get("MOT_SPIN_MAX").getParam_value()), Double.parseDouble(FlyVoid.paramList.get("MOT_THST_EXPO").getParam_value()), data.optDouble("throttle") / 100, 1) * 100) + "%", true));
} else {
typeList.set(2, new Msg("throttle", "0%", true));
}
});
- //广播接收-setMissionAcklistener
- myReceiver_MISSION_REQUEST.setMissionRequestlistener(data -> {
-// Log.d(TAG, "myReceiver_MISSION_REQUEST: "+data.toString());
- });
-
+// //广播接收-setMissionAcklistener
+// myReceiver_MISSION_REQUEST.setMissionRequestlistener(data -> {
+//// Log.d(TAG, "myReceiver_MISSION_REQUEST: "+data.toString());
+// });
+//
//广播接收-setMissionAcklistener
myReceiver_MISSION_ACK.setMissionAcklistener(data -> {
Log.d(TAG, "myReceiver_MISSION_ACK: " + data.toString());
});
-
- //广播接收-setMissionAcklistener
- myReceiver_MISSION_CURRENT.setMissionCurrentlistener(data -> {
- Log.d(TAG, "myReceiver_MISSION_CURRENT: " + data.toString());
- allView.tv_test1.setText(data.optInt("seq") + "");
- });
+//
+// //广播接收-setMissionAcklistener
+// myReceiver_MISSION_CURRENT.setMissionCurrentlistener(data -> {
+//// Log.d(TAG, "myReceiver_MISSION_CURRENT: " + data.toString());
+// allView.tv_test1.setText(data.optInt("seq") + "");
+// });
}
@@ -662,799 +654,197 @@ public class MainActivity extends AppCompatActivity {
*/
@SuppressLint({"NotifyDataSetChanged", "SetTextI18n", "DefaultLocale", "ClickableViewAccessibility"})
private void initOnClick() {
+ // 创建MainClick实例
+ MainClick mainClick = new MainClick(this, allView, mapVoid, flyVoid, tcpClient,
+ waypointMarkers, waypointPositions, createLinkList, selectedLinkList,
+ uploadLinkList, createLinkAdapter, allLinkAdapter, sqlClass, mainMarker);
- //点击切换窗口显示
- allView.v_mainDisplay.setOnClickListener(v -> {
- if (mainDisplay == 1) {
- mainDisplay = 2;
- MyTool.setViewWH(this, allView.map, 150, 95, 3);
- MyTool.setViewWH(this, allView.fpvWidget, 1920, 1200, 0);
- mapVoid.allView.map.setElevation(5f);
- mapVoid.allView.fpvWidget.setElevation(1f);
- allView.map.setBackgroundResource(R.drawable.x80202020_4round_3stroke_bg);
- allView.fpvWidget.setBackgroundColor(Color.parseColor("#ffffff"));
- allView.map.setPadding(6, 6, 6, 6);
- allView.fpvWidget.setPadding(0, 0, 0, 0);
-// allView.map.setVisibility(GONE);
-// allView.map_s.setVisibility(VISIBLE);
-// allView.fpvWidget.setVisibility(VISIBLE);
-// allView.fpvWidget_s.setVisibility(GONE);
- allView.ll_left_error_layout.setVisibility(GONE);
- allView.ll_ptz_ctrl.setVisibility(VISIBLE);
- allView.ll_ptz_fun.setVisibility(VISIBLE);
- } else {
- mainDisplay = 1;
- MyTool.setViewWH(this, allView.fpvWidget, 150, 95, 3);
- MyTool.setViewWH(this, allView.map, 1920, 1200, 0);
- mapVoid.allView.fpvWidget.setElevation(5f);
- mapVoid.allView.map.setElevation(1f);
- allView.fpvWidget.setBackgroundResource(R.drawable.x80202020_4round_3stroke_bg);
- allView.map.setBackgroundColor(Color.parseColor("#ffffff"));
- allView.fpvWidget.setPadding(6, 6, 6, 6);
- allView.map.setPadding(0, 0, 0, 0);
-// allView.map.setVisibility(GONE);
-// allView.map_s.setVisibility(VISIBLE);
-// allView.fpvWidget.setVisibility(VISIBLE);
-// allView.fpvWidget_s.setVisibility(GONE);
- allView.ll_left_error_layout.setVisibility(GONE);
- allView.ll_ptz_ctrl.setVisibility(GONE);
- allView.ll_ptz_fun.setVisibility(GONE);
+ // 设置MainClick的各种状态
+ mainClick.setIsUnlock(isUnlock);
+ mainClick.setIsAdviseFly(isAdviseFly);
+ mainClick.setIsSetLink(isSetLink);
+ mainClick.setMainDisplay(mainDisplay);
+ mainClick.setIsAddOrEdit(isAddOrEdit);
- }
- });
+ // 为所有普通点击事件设置监听器
+ allView.ll_create_link_layout.setOnClickListener(mainClick);
+ allView.ll_all_link_layout.setOnClickListener(mainClick);
+ allView.v_mainDisplay.setOnClickListener(mainClick);
+ allView.iv_error.setOnClickListener(mainClick);
+ allView.ll_location_me.setOnClickListener(mainClick);
+ allView.ll_turn_back.setOnClickListener(mainClick);
+ allView.ll_lift_off.setOnClickListener(mainClick);
+ allView.ll_icon_land.setOnClickListener(mainClick);
+ allView.ll_setting.setOnClickListener(mainClick);
+ allView.ll_link_start_fun1.setOnClickListener(mainClick);
+ allView.ll_link_start_fun2.setOnClickListener(mainClick);
+ allView.ll_link_start_back.setOnClickListener(mainClick);
+ allView.ll_left_open.setOnClickListener(mainClick);
+ allView.ll_link.setOnClickListener(mainClick);
+ allView.ll_title.setOnClickListener(mainClick);
+ allView.ll_clear.setOnClickListener(mainClick);
+ allView.tv_add_link.setOnClickListener(mainClick);
+ allView.ll_map.setOnClickListener(mainClick);
+ allView.ll_link_save.setOnClickListener(mainClick);
+ allView.tv_link_fun1.setOnClickListener(mainClick);
+ allView.tv_link_fun2.setOnClickListener(mainClick);
+ allView.ll_link_back.setOnClickListener(mainClick);
+ allView.ll_execute_line.setOnClickListener(mainClick);
+ allView.ll_bombing.setOnClickListener(mainClick);
+ allView.ll_shout.setOnClickListener(mainClick);
+ allView.ll_hook.setOnClickListener(mainClick);
+ allView.ll_searchlight.setOnClickListener(mainClick);
+ allView.ll_PTZ_one_center.setOnClickListener(mainClick);
+ allView.ll_PTZ_one_bottom.setOnClickListener(mainClick);
+ allView.iv_open_link_list.setOnClickListener(mainClick);
+ allView.ll_clear_fly_line.setOnClickListener(mainClick);
- //点击异常窗口
- allView.iv_error.setOnClickListener(v -> {
+ // 为四个方向按钮设置统一的点击监听器
+ View.OnClickListener markerMoveClickListener = mainClick.getMarkerMoveClickListener();
+ allView.iv_marker_top.setOnClickListener(markerMoveClickListener);
+ allView.iv_marker_bottom.setOnClickListener(markerMoveClickListener);
+ allView.iv_marker_left.setOnClickListener(markerMoveClickListener);
+ allView.iv_marker_right.setOnClickListener(markerMoveClickListener);
- if (allView.ll_left_error_layout.getVisibility() == VISIBLE) {
- allView.ll_left_error_layout.setVisibility(GONE);
- } else {
- allView.ll_left_error_layout.setVisibility(VISIBLE);
- }
- });
-
- //点击定位到当前位置按钮
- allView.ll_location_me.setOnClickListener(v -> {
- if (MyReceiver.GLOBAL_POSITION_INT_json.optDouble("lat", 0) / 10000000 != 0) {
- // 移动视图到Marker点
- mapVoid.aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(MyReceiver.GLOBAL_POSITION_INT_json.optDouble("lat", 0) / 10000000, MyReceiver.GLOBAL_POSITION_INT_json.optDouble("lon", 0) / 10000000), 15)); // 15是缩放级别
- mainMarker.setVisible(true);
- }
- });
-
- //返航按钮
- allView.ll_turn_back.setOnClickListener(v -> {
- turnBackDialog.show();
- });
-
- // 起飞按钮
- allView.ll_lift_off.setOnClickListener(v -> {
- takeOffDialog.show();
- });
-
- // 降落按钮
- allView.ll_icon_land.setOnClickListener(v -> {
- landDialog.show();
- });
-
- //进设置页面
- allView.ll_setting.setOnClickListener(v -> {
-// Toast.makeText(this, "维护中..", Toast.LENGTH_SHORT).show();
- Intent intent = new Intent(this, SettingActivity.class);
- startActivity(intent);
- });
-
- //航线执行-上传航线
- allView.ll_link_start_fun1.setOnClickListener(v -> {
- // 添加航线发送功能
- if (selectedLinkList.size() > 0) {
- // 调用FlyVoid中的方法发送航线到飞控
- flyVoid.sendMissionToFlightController(this,
- selectedLinkList,
- allView.et_start_execute_height.getText().toString());
- // 清除当前地图上的所有航点和航线
-// clearWaypoints();
- allView.v_mainDisplay.setVisibility(VISIBLE);
- allView.ll_open_layout.setVisibility(VISIBLE);
- allView.ll_text.setVisibility(VISIBLE);
- allView.ll_link_start.setVisibility(GONE);
- allView.ll_all_link_layout.setVisibility(GONE);
- allView.fpvWidget.setVisibility(VISIBLE);
- uploadLinkList.addAll(selectedLinkList);
- allView.ll_assistance_layout.setVisibility(VISIBLE);
- } else {
- Toast.makeText(this, "请选择航线", Toast.LENGTH_SHORT).show();
- }
- });
- //开始执行
- allView.ll_link_start_fun2.setOnClickListener(v -> {
- // 开始执行
- if (selectedLinkList != null) {
- // 调用FlyVoid中的方法发送航线到飞控
- //flyVoid.requestMissionStart(0,0);
- if (isUnlock) {
- startExecuteDialog.show();
- } else {
- Toast.makeText(this, "请先解锁", Toast.LENGTH_SHORT).show();
- }
-
- } else {
- Toast.makeText(this, "请先选择航线", Toast.LENGTH_SHORT).show();
- }
-
- });
-
- //航线执行-退出
- allView.ll_link_start_back.setOnClickListener(v -> {
- //判断是否选择了航线
- if (uploadLinkList != null) {
- // 清除当前地图上的所有航点和航线
- clearWaypoints();
- // 在地图上显示航线-之前上传的航线
- displayRouteOnMap(uploadLinkList);
- }
- allView.v_mainDisplay.setVisibility(VISIBLE);
- allView.ll_open_layout.setVisibility(VISIBLE);
- allView.ll_text.setVisibility(VISIBLE);
- allView.ll_link_start.setVisibility(GONE);
- allView.ll_all_link_layout.setVisibility(GONE);
- allView.fpvWidget.setVisibility(VISIBLE);
- allView.ll_assistance_layout.setVisibility(VISIBLE);
- isAdviseFly = true;
- });
-
- allView.ll_left_open.setOnClickListener(v -> {
- if (allView.ll_function_layout.getVisibility() == VISIBLE) {
- allView.ll_function_layout.setVisibility(GONE);
- } else {
- allView.ll_function_layout.setVisibility(VISIBLE);
- }
- });
-
- //清除所有航线的方法
- allView.ll_clear.setOnClickListener(v -> {
- uploadLinkList.clear();
- // 清除所有航点和航线
- clearWaypoints();
- // 在地图上显示航线-清除选中点在更新地图
- displayRouteOnMap(uploadLinkList);
- Toast.makeText(this, "已清除", Toast.LENGTH_SHORT).show();
- });
-
- //添加航线跳转
- allView.tv_add_link.setOnClickListener(v -> {
- // 清除所有航点和航线
- clearWaypoints();
- isSetLink = true;
- allView.ll_all_link_layout.setVisibility(GONE);
- allView.ll_link_start.setVisibility(GONE);
- allView.v_mainDisplay.setVisibility(GONE);
- allView.ll_open_layout.setVisibility(GONE);
- allView.ll_text.setVisibility(GONE);
- allView.ll_link.setVisibility(VISIBLE);
- allView.ll_create_link_layout.setVisibility(VISIBLE);
- allView.fpvWidget.setVisibility(GONE);
- });
-
- //航线规划
- allView.ll_map.setOnClickListener(v -> {
- // 清除所有航点和航线
- clearWaypoints();
- isAdviseFly = false;
- allView.ll_all_link_layout.setVisibility(VISIBLE);
- allView.ll_link_start.setVisibility(VISIBLE);
- allView.v_mainDisplay.setVisibility(GONE);
- allView.ll_open_layout.setVisibility(GONE);
- allView.ll_text.setVisibility(GONE);
- allView.ll_link.setVisibility(GONE);
- allView.ll_create_link_layout.setVisibility(GONE);
- allView.fpvWidget.setVisibility(GONE);
- allView.ll_assistance_layout.setVisibility(GONE);
- });
- //航线规划功能-保存
- allView.ll_link_save.setOnClickListener(v -> {
- if (allView.et_link_name.getText().toString().length() != 0){
- saveLink(null);
- }else {
- saveLinkNameDialog.show();
- }
-
- });
- // 航线规划功能-1:反转航点顺序
- allView.tv_link_fun1.setOnClickListener(v -> {
- // 创建确认对话框
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle("反转航点顺序");
- builder.setMessage("确定要反转当前航点的顺序吗?");
-
- builder.setPositiveButton("确定", (dialog, which) -> {
- // 反转航点位置列表
- java.util.Collections.reverse(waypointPositions);
-
- // 反转航点标记列表
- java.util.Collections.reverse(waypointMarkers);
-
- // 反转createLinkList列表
- java.util.Collections.reverse(createLinkList);
-
- // 重新编号航点标记
- renumberWaypoints();
-
- // 更新航线显示
- updateFlightPath();
-
- dialog.dismiss();
- });
-
- builder.setNegativeButton("取消", (dialog, which) -> {
- dialog.dismiss();
- });
-
- AlertDialog dialog = builder.create();
- dialog.show();
- });
- // 航线规划功能-2:清除所有线航
- allView.tv_link_fun2.setOnClickListener(v -> {
- // 创建确认对话框
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle("清除所有航点");
- builder.setMessage("确定要清除所有航点和航线吗?");
-
- builder.setPositiveButton("确定", (dialog, which) -> {
- // 清除所有航点和航线
- clearWaypoints();
- dialog.dismiss();
- });
-
- builder.setNegativeButton("取消", (dialog, which) -> {
- dialog.dismiss();
- });
-
- AlertDialog dialog = builder.create();
- dialog.show();
- });
- //航线规划功能-退出
- allView.ll_link_back.setOnClickListener(v -> {
- if (createLinkList.size() > 0) {
- // 创建确认对话框
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle("退出");
- builder.setMessage("确定要退出嘛?退出前的航线不会保存");
-
- builder.setPositiveButton("确定", (dialog, which) -> {
- // 清除所有航点和航线
- clearWaypoints();
- isSetLink = false;
- allView.ll_all_link_layout.setVisibility(VISIBLE);
- allView.ll_link_start.setVisibility(VISIBLE);
- allView.v_mainDisplay.setVisibility(GONE);
- allView.ll_open_layout.setVisibility(GONE);
- allView.ll_text.setVisibility(GONE);
- allView.ll_link.setVisibility(GONE);
- allView.ll_create_link_layout.setVisibility(GONE);
- allView.fpvWidget.setVisibility(GONE);
- displayRouteOnMap(selectedLinkList);
- dialog.dismiss();
- // 在地图上显示航线-之前上传的航线
- displayRouteOnMap(selectedLinkList);
-
- });
-
- builder.setNegativeButton("取消", (dialog, which) -> {
- dialog.dismiss();
- });
-
- AlertDialog dialog = builder.create();
- dialog.show();
- } else {
- // 清除所有航点和航线
- clearWaypoints();
- isSetLink = false;
- allView.ll_all_link_layout.setVisibility(VISIBLE);
- allView.ll_link_start.setVisibility(VISIBLE);
- allView.v_mainDisplay.setVisibility(GONE);
- allView.ll_open_layout.setVisibility(GONE);
- allView.ll_text.setVisibility(GONE);
- allView.ll_link.setVisibility(GONE);
- allView.ll_create_link_layout.setVisibility(GONE);
- allView.fpvWidget.setVisibility(GONE);
- }
- });
-
- allView.ll_execute_line.setOnClickListener(v -> {
- startExecuteDialog.show();
- });
- allView.ll_bombing.setOnClickListener(v -> {
- bombingDialog.show();
-// Toast.makeText(this, "正在研发..", Toast.LENGTH_SHORT).show();
- });
- allView.ll_shout.setOnClickListener(v -> {
- Toast.makeText(this, "正在研发..", Toast.LENGTH_SHORT).show();
- });
- allView.ll_hook.setOnClickListener(v -> {
- Toast.makeText(this, "正在研发..", Toast.LENGTH_SHORT).show();
- });
- allView.ll_searchlight.setOnClickListener(v -> {
- Toast.makeText(this, "正在研发..", Toast.LENGTH_SHORT).show();
- });
- //初始化FPV手势处理
+ // 初始化FPV手势处理
fpvGestureHandler = new FpvGestureHandler(allView.fpvWidget);
- fpvGestureHandler.setOnFpvGestureListener(new FpvGestureHandler.OnFpvGestureListener() {
- // 添加一个标志位来跟踪是否已经处理过滑动
- private boolean isSwiping = false;
- private String lastDirection = "";
+ fpvGestureHandler.setOnFpvGestureListener(mainClick.getFpvGestureListener());
- @Override
- public void onTap(float x, float y) {
- // 处理单击事件
- Log.d(TAG, "FPV单击: x=" + x + ", y=" + y);
- // 获取FPV控件的宽度和高度
- int fpvWidth = allView.fpvWidget.getWidth();
- int fpvHeight = allView.fpvWidget.getHeight();
-
- // 将坐标转换为0x00-0xff范围内的值
- // X方向: 从左(0x00)到右(0xff)
- // Y方向: 从上(0x00)到下(0xff)
- byte convertedX = (byte) Math.max(0x00, Math.min(0xFF, Math.round((x / fpvWidth) * 255)));
- byte convertedY = (byte) Math.max(0x00, Math.min(0xFF, Math.round((y / fpvHeight) * 255)));
-
- if (!tcpClient.isConnected()) {
- Toast.makeText(getApplicationContext(), "未连接到服务器", Toast.LENGTH_SHORT).show();
- } else {
- // 发送指点
- byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x10, 0x00, convertedX, convertedY,
- Protocol.calculateCheckCode((byte) 0x01, (byte) 0x10, (byte) 0x00, convertedX, convertedY)};
- tcpClient.sendBytes(testData);
- }
- }
-
- @Override
- public void onDoubleTap(float x, float y) {
- // 处理双击事件
- Log.d(TAG, "FPV双击: x=" + x + ", y=" + y);
- // 在这里添加您的双击处理逻辑
- }
-
- @Override
- public void onLongPress(float x, float y) {
- // 处理长按事件
- Log.d(TAG, "FPV长按: x=" + x + ", y=" + y);
- // 在这里添加您的长按处理逻辑
- }
-
- @Override
- public void onSwipe(float startX, float startY, float endX, float endY, float distanceX, float distanceY) {
- // 处理滑动事件
-// Log.d(TAG, "FPV滑动: startX=" + startX + ", startY=" + startY +
-// ", endX=" + endX + ", endY=" + endY +
-// ", distanceX=" + distanceX + ", distanceY=" + distanceY);
-
- // 判断滑动方向
- String currentDirection;
- if (Math.abs(distanceX) > Math.abs(distanceY)) {
- // 水平滑动
- if (distanceX > 0) {
- // 向右滑动
- currentDirection = "right";
-// Log.d(TAG, "FPV向右滑动");
- } else {
- // 向左滑动
- currentDirection = "left";
-// Log.d(TAG, "FPV向左滑动");
- }
- } else {
- // 垂直滑动
- if (distanceY > 0) {
- // 向下滑动
- currentDirection = "down";
-// Log.d(TAG, "FPV向下滑动");
- } else {
- // 向上滑动
- currentDirection = "up";
-// Log.d(TAG, "FPV向上滑动");
- }
- }
-
- // 如果方向改变或者刚开始滑动,则更新方向并处理
- if (!isSwiping || !lastDirection.equals(currentDirection)) {
- isSwiping = true;
- lastDirection = currentDirection;
- Log.d(TAG, "FPV向" + currentDirection + "滑动");
- // 在这里添加您的滑动处理逻辑
- switch (currentDirection) {
- case "up":
- if (!tcpClient.isConnected()) {
- Toast.makeText(getApplicationContext(), "未连接到服务器", Toast.LENGTH_SHORT).show();
- break;
- } else {
- // 发送左转数据
- byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x08, 0x00, (byte) 0xFF, 0x08};
- tcpClient.sendBytes(testData);
- }
- break;
-
- case "down":
- if (!tcpClient.isConnected()) {
- Toast.makeText(getApplicationContext(), "未连接到服务器", Toast.LENGTH_SHORT).show();
- break;
- } else {
- // 发送左转数据
- byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x10, 0x00, (byte) 0xFF, 0x10};
- tcpClient.sendBytes(testData);
- }
- break;
-
- case "left":
- if (!tcpClient.isConnected()) {
- Toast.makeText(getApplicationContext(), "未连接到服务器", Toast.LENGTH_SHORT).show();
- break;
- } else {
- // 发送左转数据
- byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x04, (byte) 0xFF, 0x00, 0x04};
- tcpClient.sendBytes(testData);
- }
- break;
-
- case "right":
- // 停止数据
- if (!tcpClient.isConnected()) {
- Toast.makeText(getApplicationContext(), "未连接到服务器", Toast.LENGTH_SHORT).show();
- break;
- } else {
- // 发送左转数据
- byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x02, (byte) 0xFF, 0x00, 0x02};
- tcpClient.sendBytes(testData);
- }
-
- }
- }
- }
-
- @Override
- public void onSwipeUp() {
- // 向上滑动的专门处理方法
-// Log.d(TAG, "FPV向上滑动事件");
- }
-
- @Override
- public void onSwipeDown() {
- // 向下滑动的专门处理方法
-// Log.d(TAG, "FPV向下滑动事件");
- }
-
- @Override
- public void onSwipeLeft() {
- // 向左滑动的专门处理方法
-// Log.d(TAG, "FPV向左滑动事件");
-
- }
-
- @Override
- public void onSwipeRight() {
- // 向右滑动的专门处理方法
-// Log.d(TAG, "FPV向右滑动事件");
- }
-
- @Override
- public void onZoom(float scaleFactor) {
- // 处理缩放事件
- Log.d(TAG, "FPV缩放: scaleFactor=" + scaleFactor);
- // 在这里添加您的缩放处理逻辑
- }
-
- @Override
- public void onSwipeEnd() {
- // 滑动结束(抬起)事件
- Log.d(TAG, "FPV滑动结束(手指抬起)");
- // 重置标志位,以便下一次滑动可以被处理
- isSwiping = false;
- lastDirection = "";
- // 发送停止数据
- byte[] testData1 = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01};
- tcpClient.sendBytes(testData1);
- }
- });
-
- // 为iv_ptz_top添加按下和抬起事件
- allView.iv_ptz_top.setOnTouchListener((v, event) -> {
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- // 按下事件
- Log.d("PTZ", "iv_ptz_top被按下");
- if (!tcpClient.isConnected()) {
- Toast.makeText(this, "未连接到服务器", Toast.LENGTH_SHORT).show();
- break;
- } else {
- // 发送左转数据
- byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x08, 0x00, (byte) 0xFF, 0x08};
- tcpClient.sendBytes(testData);
- }
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- if (!tcpClient.isConnected()) {
- Toast.makeText(this, "未连接到服务器", Toast.LENGTH_SHORT).show();
- break;
- } else {
- // 发送停止数据
- byte[] testData1 = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01};
- tcpClient.sendBytes(testData1);
- }
- break;
- }
- return true; // 返回true表示处理了触摸事件
- });
-
- // 为iv_ptz_left添加按下和抬起事件
- allView.iv_ptz_left.setOnTouchListener((v, event) -> {
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- // 按下事件
- Log.d("PTZ", "iv_ptz_left被按下");
- if (!tcpClient.isConnected()) {
- Toast.makeText(this, "未连接到服务器", Toast.LENGTH_SHORT).show();
- break;
- } else {
- // 发送左转数据
- byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x04, (byte) 0xFF, 0x00, 0x04};
- tcpClient.sendBytes(testData);
- }
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- // 抬起或取消事件
- Log.d("PTZ", "iv_ptz_left被释放");
- if (!tcpClient.isConnected()) {
- Toast.makeText(this, "未连接到服务器", Toast.LENGTH_SHORT).show();
- break;
- } else {
- // 发送停止数据
- byte[] testData1 = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01};
- tcpClient.sendBytes(testData1);
- }
-
- // 在这里添加抬起时需要执行的代码
- // 例如停止云台转动
- break;
- }
- return true; // 返回true表示处理了触摸事件
- });
-
- // 为iv_ptz_right添加按下和抬起事件
- allView.iv_ptz_right.setOnTouchListener((v, event) -> {
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- // 按下事件
- Log.d("PTZ", "iv_ptz_right被按下");
- if (!tcpClient.isConnected()) {
- Toast.makeText(this, "未连接到服务器", Toast.LENGTH_SHORT).show();
- break;
- } else {
- // 发送左转数据
- byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x02, (byte) 0xFF, 0x00, 0x02};
- tcpClient.sendBytes(testData);
- }
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- // 抬起或取消事件
- Log.d("PTZ", "iv_ptz_right被释放");
- if (!tcpClient.isConnected()) {
- Toast.makeText(this, "未连接到服务器", Toast.LENGTH_SHORT).show();
- break;
- } else {
- // 发送停止数据
- byte[] testData1 = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01};
- tcpClient.sendBytes(testData1);
- }
- break;
- }
- return true; // 返回true表示处理了触摸事件
- });
-
- // 为iv_ptz_bottom添加按下和抬起事件
- allView.iv_ptz_bottom.setOnTouchListener((v, event) -> {
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- // 按下事件
- Log.d("PTZ", "iv_ptz_bottom被按下");
- if (!tcpClient.isConnected()) {
- Toast.makeText(this, "未连接到服务器", Toast.LENGTH_SHORT).show();
- break;
- } else {
- // 发送左转数据
- byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x10, 0x00, (byte) 0xFF, 0x10};
- tcpClient.sendBytes(testData);
- }
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- if (!tcpClient.isConnected()) {
- Toast.makeText(this, "未连接到服务器", Toast.LENGTH_SHORT).show();
- break;
- } else {
- // 发送停止数据
- byte[] testData1 = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01};
- tcpClient.sendBytes(testData1);
- }
- break;
- }
- return true; // 返回true表示处理了触摸事件
- });
-
- //一键回中
- allView.ll_PTZ_one_center.setOnClickListener(v -> {
- // 发送左转数据
- byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x13, 0x03, 0x00, 0x00, 0x17};
- tcpClient.sendBytes(testData);
- });
-
- //一键向下
- allView.ll_PTZ_one_bottom.setOnClickListener(v -> {
- // 发送左转数据
- byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x13, 0x02, 0x00, 0x00, 0x16};
- tcpClient.sendBytes(testData);
- });
-
- // 为ll_PTZ_amplify添加按下和抬起事件
- allView.ll_PTZ_amplify.setOnTouchListener((v, event) -> {
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- // 按下事件
- Log.d("PTZ", "ll_PTZ_amplify被按下");
- if (!tcpClient.isConnected()) {
- Toast.makeText(this, "未连接到服务器", Toast.LENGTH_SHORT).show();
- break;
- } else {
- // 发送变倍数据
- byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x40, 0x04, 0x00, 0x45};
- tcpClient.sendBytes(testData);
- }
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- if (!tcpClient.isConnected()) {
- Toast.makeText(this, "未连接到服务器", Toast.LENGTH_SHORT).show();
- break;
- } else {
- // 发送停止数据
- byte[] testData1 = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x60, 0x00, 0x00, 0x61};
- tcpClient.sendBytes(testData1);
- }
- break;
- }
- return true; // 返回true表示处理了触摸事件
- });
-
- // 为ll_PTZ_reduce添加按下和抬起事件
- allView.ll_PTZ_reduce.setOnTouchListener((v, event) -> {
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- // 按下事件
- Log.d("PTZ", "ll_PTZ_reduce被按下");
- if (!tcpClient.isConnected()) {
- Toast.makeText(this, "未连接到服务器", Toast.LENGTH_SHORT).show();
- break;
- } else {
- // 发送变倍数据
- byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x20, 0x04, 0x00, 0x25};
- tcpClient.sendBytes(testData);
- }
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- if (!tcpClient.isConnected()) {
- Toast.makeText(this, "未连接到服务器", Toast.LENGTH_SHORT).show();
- break;
- } else {
- // 发送停止数据
- byte[] testData1 = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x60, 0x00, 0x00, 0x61};
- tcpClient.sendBytes(testData1);
- }
- break;
- }
- return true; // 返回true表示处理了触摸事件
- });
+ // 为PTZ控件添加触摸事件
+ allView.iv_ptz_top.setOnTouchListener(mainClick.getPTZTouchListener());
+ allView.iv_ptz_left.setOnTouchListener(mainClick.getPTZTouchListener());
+ allView.iv_ptz_right.setOnTouchListener(mainClick.getPTZTouchListener());
+ allView.iv_ptz_bottom.setOnTouchListener(mainClick.getPTZTouchListener());
+ allView.ll_PTZ_amplify.setOnTouchListener(mainClick.getPTZTouchListener());
+ allView.ll_PTZ_reduce.setOnTouchListener(mainClick.getPTZTouchListener());
// 设置地图点击监听器以添加航点
- allView.map.getMap().setOnMapClickListener(latLng -> {
- if (isSetLink) {
-// Log.d("setOnMapClickListener", latLng.toString()+"++"+isSetLink);
- addWaypoint(latLng);
- }
- });
+ allView.map.getMap().setOnMapClickListener(mainClick.getMapClickListener());
- //地图长按
- allView.map.getMap().setOnMapLongClickListener(latLng -> {
- if (isAdviseFly) {
- pointFlyDialog.setLatLng(latLng);
- pointFlyDialog.show();
- }
- });
+ // 地图长按指点飞行
+ allView.map.getMap().setOnMapLongClickListener(mainClick.getMapLongClickListener());
- // 设置标记点击监听器以删除航点
- allView.map.getMap().setOnMarkerClickListener(marker -> {
- if (isSetLink) {
- // 检查是否是航点标记
- int index = findWaypointMarkerIndex(marker);
- if (index != -1) {
- // 显示删除确认对话框
- showDeleteWaypointDialog(index, marker);
- return true; // 消费点击事件
- }
- }
-
- return false; // 不消费点击事件
- });
+ // 设置标记点击监听器 -- 航点移动
+ allView.map.getMap().setOnMarkerClickListener(mainClick.getMarkerClickListener());
// 设置标记的标题始终显示
- allView.map.getMap().setOnMapLoadedListener(() -> {
- if (isSetLink) {
- // 地图加载完成后,确保所有航点标题可见
- for (Marker marker : waypointMarkers) {
- marker.showInfoWindow();
- }
- }
-
- });
+ allView.map.getMap().setOnMapLoadedListener(mainClick.getMapLoadedListener());
// 设置删除监听器
createLinkAdapter.setOnItemClickListener(new CreateLinkAdapter.OnItemClickListener() {
@Override
public void onDeleteClick(int position) {
- // 删除对应的航点
removeWaypointByIndex(position);
}
});
- //根据输入的文字模糊查询(名字)搜索框
- allView.et_link_search.addTextChangedListener(new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- // 不需要实现
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- // 实时查询
- filterLinkList(s.toString());
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- // 不需要实现
- }
- });
-
- //清除飞行轨迹
- allView.ll_clear_fly_line.setOnClickListener(v -> {
- if (mapVoid.isTracking){
- mapVoid.isTracking = false;
- mapVoid.clearFlightTrack();
- mapVoid.stopFlightTracking();
- }else {
- mapVoid.startFlightTracking();
- }
-
- });
-
- //开启|关闭航线点位
- allView.iv_open_link_list.setOnClickListener(v -> {
- if (allView.ll_create_link_item_layout.getVisibility() == View.GONE){
- allView.ll_create_link_item_layout.setVisibility(View.VISIBLE);
- }else {
- allView.ll_create_link_item_layout.setVisibility(View.GONE);
- }
- });
-
+ // 根据输入的文字模糊查询(名字)搜索框
+ allView.et_link_search.addTextChangedListener(mainClick.getTextWatcher());
}
+
+
+
+ // 在 MainActivity 中添加以下公共方法
+
+ public void updateFlightPath() {
+ if (flightPathPolyline != null) {
+ flightPathPolyline.remove();
+ flightPathPolyline = null;
+ }
+
+ if (waypointPositions.size() > 1) {
+ flightPathPolyline = allView.map.getMap().addPolyline(new PolylineOptions()
+ .addAll(waypointPositions).width(6).color(Color.parseColor("#FFEB3B")));
+ }
+ }
+
+ public void displayRouteOnMap(ArrayList createLinkList) {
+ for (int i = 0; i < createLinkList.size(); i++) {
+ CreateLink createLink = createLinkList.get(i);
+ LatLng latLng = createLink.getLatLng();
+ if (latLng == null) continue;
+
+ View markerView = getLayoutInflater().inflate(R.layout.custom_marker_layout, null);
+ TextView markerText = markerView.findViewById(R.id.marker_text);
+ markerText.setText(createLink.getName());
+
+ markerView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
+ markerView.layout(0, 0, markerView.getMeasuredWidth(), markerView.getMeasuredHeight());
+ markerView.buildDrawingCache();
+ Bitmap markerBitmap = markerView.getDrawingCache();
+
+ MarkerOptions markerOptions = new MarkerOptions().position(latLng)
+ .icon(BitmapDescriptorFactory.fromBitmap(markerBitmap)).draggable(false);
+
+ Marker marker = allView.map.getMap().addMarker(markerOptions);
+
+ waypointMarkers.add(marker);
+ waypointPositions.add(latLng);
+
+ CreateLink newCreateLink = new CreateLink(createLink.getName(), createLink.getHeight(),
+ createLink.getSpeed(), createLink.getWaypointIndex(), latLng, createLink.getStop_time(),
+ createLink.isBom1_show(), createLink.isBom2_show());
+ this.createLinkList.add(newCreateLink);
+ }
+
+ createLinkAdapter.setCreateLinkList(this.createLinkList);
+ updateFlightPath();
+
+ if (!waypointPositions.isEmpty()) {
+ LatLng firstWaypoint = waypointPositions.get(0);
+ allView.map.getMap().moveCamera(CameraUpdateFactory.newLatLngZoom(firstWaypoint, 15));
+ }
+ }
+
+ public int findWaypointMarkerIndex(Marker marker) {
+ return waypointMarkers.indexOf(marker);
+ }
+
+ public void renumberWaypoints() {
+ for (int i = 0; i < waypointMarkers.size(); i++) {
+ Bitmap markerBitmap = createCustomMarkerBitmap((i + 1) + "");
+ waypointMarkers.get(i).setIcon(BitmapDescriptorFactory.fromBitmap(markerBitmap));
+
+ if (i < createLinkList.size()) {
+ createLinkList.get(i).setName((i + 1) + "");
+ }
+ }
+
+ createLinkAdapter.setCreateLinkList(createLinkList);
+ }
+
+ public Bitmap createCustomMarkerBitmap(String text) {
+ View markerView = getLayoutInflater().inflate(R.layout.custom_marker_layout, null);
+ TextView markerText = markerView.findViewById(R.id.marker_text);
+ markerText.setText(text);
+
+ markerView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
+ markerView.layout(0, 0, markerView.getMeasuredWidth(), markerView.getMeasuredHeight());
+ markerView.buildDrawingCache();
+ return markerView.getDrawingCache();
+ }
+
+ public void removeWaypointByIndex(int position) {
+ if (position >= 0 && position < waypointMarkers.size()) {
+ waypointMarkers.get(position).remove();
+ waypointMarkers.remove(position);
+ waypointPositions.remove(position);
+ createLinkList.remove(position);
+
+ createLinkAdapter.setCreateLinkList(createLinkList);
+ renumberWaypoints();
+ updateFlightPath();
+ }
+ }
+
+
/**
* 方法:保存航线
*
* @cuijingzhou
*/
- public void saveLink( String linkName) {
+ public void saveLink(String linkName) {
// 初始化数据库
SQLClass sqlClass = new SQLClass(this);
// 添加一个CreateLink列表
@@ -1462,15 +852,38 @@ public class MainActivity extends AppCompatActivity {
if (createLinkList.size() > 0) {
createLinkLists.addAll(createLinkList);
boolean success;
- if (linkName == null){
- // 添加CreateLink对象到列表中
- if (allView.et_link_name.getText().toString().length() != 0) {
- success = sqlClass.addCreateLinkList(allView.et_link_name.getText().toString(), createLinkLists);
+
+ if (isAddOrEdit == 0) { // 添加模式
+ if (linkName == null) {
+ // 添加CreateLink对象到列表中
+ if (allView.et_link_name.getText().toString().length() != 0) {
+ success = sqlClass.addCreateLinkList(allView.et_link_name.getText().toString(), createLinkLists);
+ } else {
+ success = sqlClass.addCreateLinkList("航线-" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), createLinkLists);
+ }
} else {
- success = sqlClass.addCreateLinkList("航线-" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), createLinkLists);
+ success = sqlClass.addCreateLinkList(linkName, createLinkLists);
}
- }else {
- success = sqlClass.addCreateLinkList(linkName, createLinkLists);
+ } else { // 编辑模式
+ if (allLinkAdapter.getSelectLinkListInfo() != -1){
+ // 获取当前编辑的航线ID(需要您根据实际情况调整)
+ int currentLinkId = allLinkAdapter.getSelectLinkListInfo(); // 这个方法需要您实现 todo
+ if (linkName == null) {
+ if (allView.et_link_name.getText().toString().length() != 0) {
+ success = sqlClass.updateCreateLinkList(currentLinkId, allView.et_link_name.getText().toString(), createLinkLists);
+ } else {
+ success = sqlClass.updateCreateLinkList(
+ currentLinkId,
+ "航线-" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), createLinkLists);
+ }
+ } else {
+ success = sqlClass.updateCreateLinkList(currentLinkId, linkName, createLinkLists);
+ }
+ }else {
+ Toast.makeText(this, "获取列表错误", Toast.LENGTH_SHORT).show();
+ success = false;
+ }
+
}
if (success) {
@@ -1489,161 +902,11 @@ public class MainActivity extends AppCompatActivity {
// 在地图上显示航线-之前选中的航线
displayRouteOnMap(selectedLinkList);
refreshLinkList();//刷新航线列表
- Toast.makeText(this, "航线保存成功", Toast.LENGTH_SHORT).show();
+ Toast.makeText(this, isAddOrEdit == 0 ? "航线保存成功" : "航线更新成功", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(this, "请先添加航点", Toast.LENGTH_SHORT).show();
}
-
-
-
- }
-
- // 添加过滤方法
- private void filterLinkList(String query) {
- if (sqlClass != null && allLinkAdapter != null) {
- if (query.isEmpty()) {
- // 如果查询为空,显示所有数据
- List allList = sqlClass.getAllLinkListInfo();
- allLinkAdapter.updateDataList(allList);
- } else {
- // 根据输入文字模糊查询
- List filteredList = new ArrayList<>();
- List fullList = sqlClass.getAllLinkListInfo();
-
- for (SQLClass.LinkListInfo item : fullList) {
- // 模糊匹配航线名称
- if (item.getListName().toLowerCase().contains(query.toLowerCase())) {
- filteredList.add(item);
- }
- }
-
- allLinkAdapter.updateDataList(filteredList);
- }
- }
- }
-
- /**
- * 显示删除航点确认对话框
- *
- * @param index 航点索引
- * @param marker 航点标记
- */
- private void showDeleteWaypointDialog(int index, Marker marker) {
- // 创建自定义对话框
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle("删除航点");
- builder.setMessage("确定要删除航点" + (index + 1) + "吗?");
-
- builder.setPositiveButton("确定", (dialog, which) -> {
- // 删除航点时同时删除对应的列表项
- removeWaypointByIndex(index);
- dialog.dismiss();
- });
-
- builder.setNegativeButton("取消", (dialog, which) -> {
- dialog.dismiss();
- });
-
- AlertDialog dialog = builder.create();
- dialog.show();
- }
-
-
- // 修改 addWaypoint 方法
- private void addWaypoint(LatLng latLng) {
- // 创建自定义标记视图
- View markerView = getLayoutInflater().inflate(R.layout.custom_marker_layout, null);
- @SuppressLint({"MissingInflatedId", "LocalSuppress"}) TextView markerText = markerView.findViewById(R.id.marker_text);
- markerText.setText( "" + (waypointMarkers.size() + 1));
-
- // 将视图转换为Bitmap
- markerView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
- markerView.layout(0, 0, markerView.getMeasuredWidth(), markerView.getMeasuredHeight());
- markerView.buildDrawingCache();
- Bitmap markerBitmap = markerView.getDrawingCache();
-
- // 创建标记选项
- MarkerOptions markerOptions = new MarkerOptions()
- .position(latLng)
- .icon(BitmapDescriptorFactory.fromBitmap(markerBitmap))
- .draggable(false);
-
- // 添加标记到地图
- Marker marker = allView.map.getMap().addMarker(markerOptions);
-
- waypointMarkers.add(marker);
- waypointPositions.add(latLng);
-
- // 添加到列表
- CreateLink createLink = new CreateLink(
- waypointMarkers.size()+"",
- 30,
- 10,
- waypointMarkers.size() - 1,
- latLng,
- true,
- true
- );
- createLinkList.add(createLink);
- createLinkAdapter.setCreateLinkList(createLinkList);
-
- // 更新航线
- updateFlightPath();
- }
-
- // 添加新的方法
- private void removeWaypointByIndex(int position) {
- if (position >= 0 && position < waypointMarkers.size()) {
- // 移除标记
- waypointMarkers.get(position).remove();
- waypointMarkers.remove(position);
- waypointPositions.remove(position);
- createLinkList.remove(position);
-
- // 更新适配器
- createLinkAdapter.setCreateLinkList(createLinkList);
-
- // 重新编号剩余的航点
- renumberWaypoints();
-
- // 更新航线
- updateFlightPath();
- }
- }
-
- // 修改 renumberWaypoints 方法以同步更新列表项
- private void renumberWaypoints() {
- for (int i = 0; i < waypointMarkers.size(); i++) {
- // 创建新的自定义标记Bitmap
- Bitmap markerBitmap = createCustomMarkerBitmap( (i + 1)+"");
- // 更新标记图标
- waypointMarkers.get(i).setIcon(BitmapDescriptorFactory.fromBitmap(markerBitmap));
-
- // 更新列表项名称
- if (i < createLinkList.size()) {
- createLinkList.get(i).setName( (i + 1)+"");
- }
- }
-
- createLinkAdapter.setCreateLinkList(createLinkList);
- }
-
- /**
- * 创建自定义标记Bitmap
- *
- * @param text 标记文字
- * @return Bitmap
- */
- private Bitmap createCustomMarkerBitmap(String text) {
- View markerView = getLayoutInflater().inflate(R.layout.custom_marker_layout, null);
- @SuppressLint({"MissingInflatedId", "LocalSuppress"}) TextView markerText = markerView.findViewById(R.id.marker_text);
- markerText.setText(text);
-
- markerView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
- markerView.layout(0, 0, markerView.getMeasuredWidth(), markerView.getMeasuredHeight());
- markerView.buildDrawingCache();
- return markerView.getDrawingCache();
}
@@ -1668,77 +931,77 @@ public class MainActivity extends AppCompatActivity {
}
}
-
- /**
- * 根据标记查找航点索引
- *
- * @param marker 标记对象
- * @return 航点索引,未找到返回-1
- */
- private int findWaypointMarkerIndex(Marker marker) {
- return waypointMarkers.indexOf(marker);
- }
-
-
- /**
- * 更新航线显示
- */
- private void updateFlightPath() {
- // 如果已有航线,先移除
- if (flightPathPolyline != null) {
- flightPathPolyline.remove();
- flightPathPolyline = null;
- }
-
- // 只有当航点数量大于1时才绘制航线
- if (waypointPositions.size() > 1) {
- flightPathPolyline = allView.map.getMap().addPolyline(new PolylineOptions()
- .addAll(waypointPositions)
- .width(6)
- .color(Color.parseColor("#FFEB3B")));
- }
- }
-
- /**
- * 获取所有航点的经纬度列表(按顺序)
- *
- * @return 航点经纬度列表
- */
- public List getWaypointPositions() {
- return new ArrayList<>(waypointPositions);
- }
-
-
private void setupAllLinkList() {
// 初始化数据库
sqlClass = new SQLClass(this);
- // 获取所有航线列表信息
- linkListInfoList = sqlClass.getAllLinkListInfo();
+ try {
+ // 获取所有航线列表信息
+ linkListInfoList = sqlClass.getAllLinkListInfo();
- // 设置适配器
- allLinkAdapter = new AllLinkAdapter(this, linkListInfoList, sqlClass);
- allView.rv_all_link_list.setLayoutManager(new LinearLayoutManager(this));
- allView.rv_all_link_list.setAdapter(allLinkAdapter);
+ // 设置适配器
+ allLinkAdapter = new AllLinkAdapter(this, linkListInfoList, sqlClass);
+ allView.rv_all_link_list.setLayoutManager(new LinearLayoutManager(this));
+ allView.rv_all_link_list.setAdapter(allLinkAdapter);
- // 设置item点击监听器(可选)
- allLinkAdapter.setOnItemClickListener(new AllLinkAdapter.OnItemClickListener() {
- @Override
- public void onItemClick(int listId, int position) {
- // 清除所有航点和航线
- clearWaypoints();
- // 从数据库中获取选中的航线数据
- selectedLinkList = sqlClass.getCreateLinkList(listId);
- if (selectedLinkList.size() > 0) {
+ // 设置item点击监听器(可选)
+ allLinkAdapter.setOnItemClickListener(new AllLinkAdapter.OnItemClickListener() {
+ @Override
+ public void onItemClick(int listId, int position) {
+ // 清除所有航点和航线
+ clearWaypoints();
+ // 从数据库中获取选中的航线数据
+ selectedLinkList = sqlClass.getCreateLinkList(listId);
+ if (selectedLinkList.size() > 0) {
// Toast.makeText(MainActivity.this, "已加载航线: " + linkListInfoList.get(position).getListName(),
// Toast.LENGTH_SHORT).show();
- // 在地图上显示航线
- displayRouteOnMap(selectedLinkList);
- } else {
- Toast.makeText(MainActivity.this, "加载航线失败", Toast.LENGTH_SHORT).show();
+ // 在地图上显示航线
+ displayRouteOnMap(selectedLinkList);
+ } else {
+// Toast.makeText(MainActivity.this, "加载航线失败", Toast.LENGTH_SHORT).show();
+ }
}
- }
- });
+ });
+
+ // 设置item点击监听器(可选)
+ allLinkAdapter.setOnItemEditClickListener(new AllLinkAdapter.OnItemEditClickListener() {
+ @Override
+ public void onItemEditClick(int listId, int position) {
+ isAddOrEdit = 1;
+
+ // 清除所有航点和航线
+ clearWaypoints();
+
+ // 从数据库中获取选中的航线数据
+ selectedLinkList.addAll(sqlClass.getCreateLinkList(listId));
+ if (selectedLinkList.size() > 0) {
+// Toast.makeText(MainActivity.this, "已加载航线: " + linkListInfoList.get(position).getListName(),
+// Toast.LENGTH_SHORT).show();
+ // 更新适配器
+ createLinkAdapter.setCreateLinkList(selectedLinkList);
+ // 在地图上显示航线
+ displayRouteOnMap(selectedLinkList);
+ isSetLink = true;
+ allView.ll_all_link_layout.setVisibility(GONE);
+ allView.ll_link_start.setVisibility(GONE);
+ allView.v_mainDisplay.setVisibility(GONE);
+ allView.ll_open_layout.setVisibility(GONE);
+ allView.ll_text.setVisibility(GONE);
+ allView.ll_link.setVisibility(VISIBLE);
+ allView.ll_create_link_layout.setVisibility(VISIBLE);
+ allView.fpvWidget.setVisibility(GONE);
+ allView.et_link_name.setText(sqlClass.getAllLinkListInfo().get( position).getListName());
+ } else {
+// Toast.makeText(MainActivity.this, "加载航线失败", Toast.LENGTH_SHORT).show();
+ }
+ }
+ });
+
+
+ } catch (Exception e) {
+ Log.d("cjz-数据库异常", "" + e);
+ }
+
}
// 如果需要刷新数据,可以调用此方法
@@ -1747,72 +1010,7 @@ public class MainActivity extends AppCompatActivity {
List updatedList = sqlClass.getAllLinkListInfo();
allLinkAdapter.updateDataList(updatedList);
}
- }
-
-
- /**
- * 在地图上显示航线
- *
- * @param createLinkList 航线数据列表
- */
- private void displayRouteOnMap(ArrayList createLinkList) {
-
- // 遍历航线数据并在地图上显示
- for (int i = 0; i < createLinkList.size(); i++) {
- CreateLink createLink = createLinkList.get(i);
-
- // 获取航点坐标
- LatLng latLng = createLink.getLatLng();
- if (latLng == null) continue;
-
- // 创建自定义标记视图
- View markerView = getLayoutInflater().inflate(R.layout.custom_marker_layout, null);
- TextView markerText = markerView.findViewById(R.id.marker_text);
- markerText.setText(createLink.getName());
-
- // 将视图转换为Bitmap
- markerView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
- markerView.layout(0, 0, markerView.getMeasuredWidth(), markerView.getMeasuredHeight());
- markerView.buildDrawingCache();
- Bitmap markerBitmap = markerView.getDrawingCache();
-
- // 创建标记选项
- MarkerOptions markerOptions = new MarkerOptions()
- .position(latLng)
- .icon(BitmapDescriptorFactory.fromBitmap(markerBitmap))
- .draggable(false);
-
- // 添加标记到地图
- Marker marker = allView.map.getMap().addMarker(markerOptions);
-
- // 添加到航点列表
- waypointMarkers.add(marker);
- waypointPositions.add(latLng);
-
- // 更新CreateLink列表(用于适配器显示)
- CreateLink newCreateLink = new CreateLink(
- createLink.getName(),
- createLink.getHeight(),
- createLink.getSpeed(),
- createLink.getWaypointIndex(),
- latLng,
- createLink.isBom1_show(),
- createLink.isBom2_show()
- );
- this.createLinkList.add(newCreateLink);
- }
-
- // 更新适配器
- createLinkAdapter.setCreateLinkList(this.createLinkList);
-
- // 更新航线显示
- updateFlightPath();
-
- // 如果有航点,将地图中心移动到第一个航点
- if (!waypointPositions.isEmpty()) {
- LatLng firstWaypoint = waypointPositions.get(0);
- allView.map.getMap().moveCamera(CameraUpdateFactory.newLatLngZoom(firstWaypoint, 15));
- }
+ linkListInfoList = sqlClass.getAllLinkListInfo();
}
@Override
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/Adapter/AllLinkAdapter.java b/app/src/main/java/com/example/longyi_groundstation/Main/Adapter/AllLinkAdapter.java
index dcb805d..6f0599b 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Main/Adapter/AllLinkAdapter.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/Adapter/AllLinkAdapter.java
@@ -30,6 +30,7 @@ public class AllLinkAdapter extends RecyclerView.Adapter linkListInfoList;
private SQLClass sqlClass;
private OnItemClickListener onItemClickListener;
+ private OnItemEditClickListener onItemEditClickListener;
public AllLinkAdapter(Context context, List linkListInfoList, SQLClass sqlClass) {
this.context = context;
@@ -73,6 +74,14 @@ public class AllLinkAdapter extends RecyclerView.Adapter updatedList = sqlClass.getAllLinkListInfo();
updateDataList(updatedList);
});
+
+ // 点击编辑按钮
+ holder.tv_edit.setOnClickListener(v -> {
+ if (onItemEditClickListener != null) {
+ setSelects(position);
+ onItemEditClickListener.onItemEditClick(linkListInfo.getListId(), position);
+ }
+ });
// 设置整个item的点击事件
holder.itemView.setOnClickListener(v -> {
@@ -99,6 +108,16 @@ public class AllLinkAdapter extends RecyclerView.Adapter parent, View view, int positions, long id) {
+// Log.d("onItemSelected", positions+"");
+// holder.tv_turn.setText(parent.getItemAtPosition(positions).toString());
+// if (positions == 0) {
+// holder.et_turn_time.setText("0");
+// createLinkList.get(position).setStop_time(0);
+// notifyDataSetChanged();
+// } else {
+// holder.et_turn_time.setText("1");
+// createLinkList.get(position).setStop_time(1);
+// }
+// }
+//
+// @Override
+// public void onNothingSelected(AdapterView> parent) {
+// // 什么都不做
+// Log.d("onItemSelected", "11");
+// }
+// });
+
+ holder.et_turn_time.setText(createLink.getStop_time() + "");
+ holder.et_speed.setText(createLink.getSpeed() + "");
+
+
+ //投弹是否显示
+ if (createLink.isBom1_show()) {
+ holder.ll_bom_layout1.setVisibility(View.VISIBLE);
+ } else {
+ holder.ll_bom_layout1.setVisibility(View.GONE);
+ }
+ if (createLink.isBom2_show()) {
+ holder.ll_bom_layout2.setVisibility(View.VISIBLE);
+ } else {
+ holder.ll_bom_layout2.setVisibility(View.GONE);
+ }
+
+ //投弹高度
+ holder.et_bom1.setText(createLink.getBom1_height() + "");
+ holder.et_bom2.setText(createLink.getBom2_height() + "");
+
+ if (!createLink.isBom1_show() && !createLink.isBom2_show()) {
+ holder.tv_null_data.setVisibility(View.VISIBLE);
+ } else {
+ holder.tv_null_data.setVisibility(View.GONE);
+ }
+
+
+ if (createLink.isBom1_select()) {
+ holder.tv_bom_text1.setBackgroundResource(R.drawable.ff029a45_4round_1stroke_bg);
+ holder.iv_bom1.setImageResource(R.mipmap.icon_select_link_yes);
+// ll_bom_height_layout1.setVisibility(View.VISIBLE);
+ } else {
+ holder.tv_bom_text1.setBackgroundResource(R.drawable.b2101010_4round_1stroke_bg);
+ holder.iv_bom1.setImageResource(R.mipmap.icon_select_link_no);
+// ll_bom_height_layout1.setVisibility(View.INVISIBLE);
+ }
+
+ if (createLink.isBom2_select()) {
+ holder.tv_bom_text2.setBackgroundResource(R.drawable.ff029a45_4round_1stroke_bg);
+ holder.iv_bom2.setImageResource(R.mipmap.icon_select_link_yes);
+// ll_bom_height_layout2.setVisibility(View.VISIBLE);
+ } else {
+ holder.tv_bom_text2.setBackgroundResource(R.drawable.b2101010_4round_1stroke_bg);
+ holder.iv_bom2.setImageResource(R.mipmap.icon_select_link_no);
+// ll_bom_height_layout2.setVisibility(View.INVISIBLE);
+ }
+
+
+ holder.tvDel.setOnClickListener(v -> {
+ if (onItemClickListener != null) {
+ onItemClickListener.onDeleteClick(position);
+ }
+ });
+
+ // 为停留时间输入框添加实时监听事件
+ holder.et_turn_time.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ try {
+ if (s.length() > 0){
+ createLinkList.get(position).setStop_time(Integer.parseInt(s.toString()));
+ }else {
+ createLinkList.get(position).setStop_time(0);
+ }
+ }catch (Exception e){
+ Log.d("不用理会", "afterTextChanged: ");
+ }
+
+ }
+ });
+
+
+ // 为停留时间输入框添加实时监听事件
+ holder.etHeight.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ try {
+ if (s.length() > 0){
+ createLinkList.get(position).setHeight(Integer.parseInt(s.toString()));
+ }else {
+ createLinkList.get(position).setHeight(0);
+ }
+ }catch (Exception e){
+ Log.d("不用理会", "afterTextChanged: ");
+ }
+
+ }
+ });
+
+ // 为停留时间输入框添加实时监听事件
+ holder.et_lat.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ try {
+ if (s.length() > 0){
+ Log.d("afterTextChanged", "afterTextChanged: "+s);
+ // 更新CreateLink中的LatLng对象
+ double newLat = Double.parseDouble(s.toString());
+ double newLng = createLinkList.get(position).getLatLng().longitude;
+ createLinkList.get(position).setLatLng(new com.amap.api.maps.model.LatLng(newLat, newLng));
+ }else {
+ createLinkList.get(position).setLatLng(new com.amap.api.maps.model.LatLng(0, createLinkList.get(position).getLatLng().longitude));
+ }
+ } catch (Exception e){
+ Log.d("不用理会", "afterTextChanged: ");
+ }
+
+
+ }
+ });
+
+ // 为停留时间输入框添加实时监听事件
+ holder.et_lon.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ try {
+ if (s.length() > 0){
+ Log.d("afterTextChanged", "afterTextChanged: "+s);
+ // 更新CreateLink中的LatLng对象
+ double newLng = Double.parseDouble(s.toString());
+ double newLat = createLinkList.get(position).getLatLng().latitude;
+ createLinkList.get(position).setLatLng(new com.amap.api.maps.model.LatLng(newLat, newLng));
+ }else {
+ createLinkList.get(position).setLatLng(new com.amap.api.maps.model.LatLng(createLinkList.get(position).getLatLng().latitude, 0));
+ }
+ }catch (Exception e){
+ Log.d("不用理会", "afterTextChanged: ");
+ }
+
+
+ }
+ });
+
+
+ // 为停留时间输入框添加实时监听事件
+ holder.et_speed.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ try{
+ if (s.length() > 0){
+ createLinkList.get(position).setSpeed(Double.parseDouble(s.toString()));
+ }else {
+ createLinkList.get(position).setSpeed(0);
+ }
+ }catch (Exception e){
+ Log.d("不用理会", "afterTextChanged: ");
+ }
+
+ }
+ });
+
+ //展开
+ holder.tv_expand.setOnClickListener(v -> {
+ if (holder.ll_expand.getVisibility() == View.VISIBLE) {
+ holder.ll_expand.setVisibility(View.GONE);
+ holder.tv_expand.setText("展开");
+ } else {
+ holder.ll_expand.setVisibility(View.VISIBLE);
+ holder.tv_expand.setText("收起");
+ }
+ });
+
+ //投弹选中1
+ holder.ll_bom_layout1.setOnClickListener(v -> {
+ if (createLinkList.get(position).isBom1_select()) {
+ // 取消选中状态
+ holder.tv_bom_text1.setBackgroundResource(R.drawable.b2101010_4round_1stroke_bg);
+ holder.iv_bom1.setImageResource(R.mipmap.icon_select_link_no);
+ } else {
+ // 设置当前项为选中状态
+ holder.tv_bom_text1.setBackgroundResource(R.drawable.ff029a45_4round_1stroke_bg);
+ holder.iv_bom1.setImageResource(R.mipmap.icon_select_link_yes);
+ }
+ // 选中状态 - 先取消其他所有项的选中状态
+ clearAllSelectionsExcept(position, 1); // 1表示bom1
+ });
+
+ //投弹选中2
+ holder.ll_bom_layout2.setOnClickListener(v -> {
+ if (createLinkList.get(position).isBom2_select()) {
+ // 取消选中状态
+ holder.tv_bom_text2.setBackgroundResource(R.drawable.b2101010_4round_1stroke_bg);
+ holder.iv_bom2.setImageResource(R.mipmap.icon_select_link_no);
+
+ } else {
+ // 设置当前项为选中状态
+ holder.tv_bom_text2.setBackgroundResource(R.drawable.ff029a45_4round_1stroke_bg);
+ holder.iv_bom2.setImageResource(R.mipmap.icon_select_link_yes);
+ }
+ // 选中状态 - 先取消其他所有项的选中状态
+ clearAllSelectionsExcept(position, 2); // 2表示bom2
+ });
+
+
+ }
+
+ /**
+ * 清除除指定位置和类型外的所有显示状态
+ *
+ * @param currentPosition 当前项的位置
+ * @param type 1表示bom1,2表示bom2
+ */
+ private void clearAllSelectionsExcept(int currentPosition, int type) {
+ // bom1
+ if (type == 1) {
+ //如果当前项是选中状态,则取消所有bom1的选中状态并显示出来
+ if (createLinkList.get(currentPosition).isBom1_select()) {
+ for (int i = 0; i < createLinkList.size(); i++) {
+ CreateLink link = createLinkList.get(i);
+ link.setBom1_show(true);
+ link.setBom1_select(false);
+ }
+ isExpand.set(0, true);
+ }
+ //如果当前项不是选中状态,则取消除了当前项其它所有bom1的选中状态并隐藏
+ else {
+ for (int i = 0; i < createLinkList.size(); i++) {
+ CreateLink link = createLinkList.get(i);
+ if (i == currentPosition) {
+ link.setBom1_show(true);
+ link.setBom1_select(true);
+ } else {
+ link.setBom1_show(false);
+ link.setBom1_select(false);
+ }
+ }
+ isExpand.set(0, false);
+ }
+
+ }
+ //bom2
+ else {
+ if (createLinkList.get(currentPosition).isBom2_select()) {
+ for (int i = 0; i < createLinkList.size(); i++) {
+ CreateLink link = createLinkList.get(i);
+ link.setBom2_show(true);
+ link.setBom2_select(false);
+ }
+ isExpand.set(1, true);
+ }
+ //如果当前项不是选中状态,则取消除了当前项其它所有bom2的选中状态并隐藏
+ else {
+ for (int i = 0; i < createLinkList.size(); i++) {
+ CreateLink link = createLinkList.get(i);
+ if (i == currentPosition) {
+ link.setBom2_show(true);
+ link.setBom2_select(true);
+ } else {
+ link.setBom2_show(false);
+ link.setBom2_select(false);
+ }
+ }
+ isExpand.set(1, false);
+ }
+ }
+
+ notifyDataSetChanged();
}
@Override
@@ -73,14 +396,13 @@ public class CreateLinkAdapter extends RecyclerView.Adapter linkAdapter = new ArrayAdapter<>(content,
- android.R.layout.simple_spinner_item, linkOptions);
- linkAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- sp_turn.setAdapter(linkAdapter);
-
-
-
- //投弹是否显示
- if (createLink.isBom1_show()){
- ll_bom_layout1.setVisibility(View.VISIBLE);
- }else {
- ll_bom_layout1.setVisibility(View.GONE);
- }
- if (createLink.isBom2_show()){
- ll_bom_layout2.setVisibility(View.VISIBLE);
- }else {
- ll_bom_layout2.setVisibility(View.GONE);
- }
-
- //投弹高度
- et_bom1.setText(createLink.getBom1_height() + "");
- et_bom2.setText(createLink.getBom2_height() + "");
-
- if (!createLink.isBom1_show() && !createLink.isBom2_show()){
- tv_null_data.setVisibility(View.VISIBLE);
- }else {
- tv_null_data.setVisibility(View.GONE);
- }
-
-
- if (createLink.isBom1_select()) {
- tv_bom_text1.setBackgroundResource(R.drawable.ff029a45_2round_1stroke_bg);
- iv_bom1.setImageResource(R.mipmap.icon_select_link_yes);
-// ll_bom_height_layout1.setVisibility(View.VISIBLE);
- } else {
- tv_bom_text1.setBackgroundResource(R.drawable.b2101010_4round_1stroke_bg);
- iv_bom1.setImageResource(R.mipmap.icon_select_link_no);
-// ll_bom_height_layout1.setVisibility(View.INVISIBLE);
- }
-
- if (createLink.isBom2_select()) {
- tv_bom_text2.setBackgroundResource(R.drawable.ff029a45_2round_1stroke_bg);
- iv_bom2.setImageResource(R.mipmap.icon_select_link_yes);
-// ll_bom_height_layout2.setVisibility(View.VISIBLE);
- } else {
- tv_bom_text2.setBackgroundResource(R.drawable.b2101010_4round_1stroke_bg);
- iv_bom2.setImageResource(R.mipmap.icon_select_link_no);
-// ll_bom_height_layout2.setVisibility(View.INVISIBLE);
- }
-
-
- tvDel.setOnClickListener(v -> {
- if (onItemClickListener != null) {
- onItemClickListener.onDeleteClick(position);
- }
- });
-
- // 可以添加文本变化监听器来更新数据
- etHeight.setOnFocusChangeListener((v, hasFocus) -> {
- if (!hasFocus) {
- try {
- createLink.setHeight(Double.parseDouble(etHeight.getText().toString()));
- } catch (NumberFormatException e) {
- etHeight.setText(String.valueOf((int) createLink.getHeight()));
- }
- }
- });
-
- // 为Spinner设置选择监听器
- sp_turn.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
- @Override
- public void onItemSelected(AdapterView> parent, View view, int position, long id) {
- tv_turn.setText(parent.getItemAtPosition(position).toString());
-
- }
-
- @Override
- public void onNothingSelected(AdapterView> parent) {
- // 什么都不做
- }
- });
-
- rl_turn.setOnClickListener(v -> {
- showCustomDropdown(rl_turn, tv_turn,ll_turn);
- });
-
- //长按弹出窗口
- tv_expand.setOnClickListener(v -> {
- if (ll_expand.getVisibility() == View.VISIBLE) {
- ll_expand.setVisibility(View.GONE);
- tv_expand.setText("展开");
- } else {
- ll_expand.setVisibility(View.VISIBLE);
- tv_expand.setText("收起");
- }
- });
-
- //投弹选中1
- ll_bom_layout1.setOnClickListener(v -> {
- if (createLink.isBom1_select()) {
- // 取消选中状态
- tv_bom_text1.setBackgroundResource(R.drawable.b2101010_4round_1stroke_bg);
- iv_bom1.setImageResource(R.mipmap.icon_select_link_no);
- } else {
- // 设置当前项为选中状态
- tv_bom_text1.setBackgroundResource(R.drawable.ff029a45_2round_1stroke_bg);
- iv_bom1.setImageResource(R.mipmap.icon_select_link_yes);
- }
- // 选中状态 - 先取消其他所有项的选中状态
- clearAllSelectionsExcept(position, 1); // 1表示bom1
- });
-
- //投弹选中2
- ll_bom_layout2.setOnClickListener(v -> {
- if (createLink.isBom2_select()) {
- // 取消选中状态
- tv_bom_text2.setBackgroundResource(R.drawable.b2101010_4round_1stroke_bg);
- iv_bom2.setImageResource(R.mipmap.icon_select_link_no);
-
- } else {
- // 设置当前项为选中状态
- tv_bom_text2.setBackgroundResource(R.drawable.ff029a45_2round_1stroke_bg);
- iv_bom2.setImageResource(R.mipmap.icon_select_link_yes);
- }
- // 选中状态 - 先取消其他所有项的选中状态
- clearAllSelectionsExcept(position, 2); // 2表示bom2
- });
-
- }
-
- /**
- * 清除除指定位置和类型外的所有显示状态
- * @param currentPosition 当前项的位置
- * @param type 1表示bom1,2表示bom2
- */
- private void clearAllSelectionsExcept(int currentPosition, int type) {
- // bom1
- if (type == 1){
- //如果当前项是选中状态,则取消所有bom1的选中状态并显示出来
- if (createLinkList.get(currentPosition).isBom1_select()){
- for (int i = 0; i < createLinkList.size(); i++) {
- CreateLink link = createLinkList.get(i);
- link.setBom1_show(true);
- link.setBom1_select(false);
- }
- isExpand.set(0,true);
- }
- //如果当前项不是选中状态,则取消除了当前项其它所有bom1的选中状态并隐藏
- else {
- for (int i = 0; i < createLinkList.size(); i++) {
- CreateLink link = createLinkList.get(i);
- if (i == currentPosition){
- link.setBom1_show(true);
- link.setBom1_select(true);
- }else {
- link.setBom1_show(false);
- link.setBom1_select(false);
- }
- }
- isExpand.set(0,false);
- }
-
- }
- //bom2
- else {
- if (createLinkList.get(currentPosition).isBom2_select()){
- for (int i = 0; i < createLinkList.size(); i++) {
- CreateLink link = createLinkList.get(i);
- link.setBom2_show(true);
- link.setBom2_select(false);
- }
- isExpand.set(1,true);
- }
- //如果当前项不是选中状态,则取消除了当前项其它所有bom2的选中状态并隐藏
- else {
- for ( int i = 0; i < createLinkList.size(); i++) {
- CreateLink link = createLinkList.get(i);
- if (i == currentPosition){
- link.setBom2_show(true);
- link.setBom2_select(true);
- }else {
- link.setBom2_show(false);
- link.setBom2_select(false);
- }
- }
- isExpand.set(1,false);
- }
- }
-
- notifyDataSetChanged();
- }
}
- //转弯方式选择弹窗
- private void showCustomDropdown(RelativeLayout anchor, TextView tv_turn,LinearLayout ll_turn) {
- String[] options = {"协调转弯", "到点转弯"};
- AlertDialog.Builder builder = new AlertDialog.Builder(content);
- builder.setItems(options, (dialog, which) -> {
- tv_turn.setText(options[which]);
- if (which == 1){
- ll_turn.setVisibility(View.VISIBLE);
- }else {
- ll_turn.setVisibility(View.GONE);
- }
- // 更新选中状态
- });
- builder.show();
- }
-
-
}
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/Base/CreateLink.java b/app/src/main/java/com/example/longyi_groundstation/Main/Base/CreateLink.java
index bea35e4..7153fe9 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Main/Base/CreateLink.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/Base/CreateLink.java
@@ -9,6 +9,7 @@ public class CreateLink {
private double speed;//速度
private int waypointIndex;//航点索引
private LatLng latLng;//点经纬度
+ private int stop_time;//停留时间
private boolean bom1_select;//弹道1选择
private boolean bom1_show;//弹道1是否显示
private int bom1_height;//弹道1投弹高度
@@ -18,14 +19,16 @@ public class CreateLink {
public CreateLink(String name, double height, double speed, int waypointIndex, LatLng latLng
- ,boolean bom1_show,boolean bom2_show) {
+ ,int stop_time,boolean bom1_show,boolean bom2_show) {
this.name = name;
this.height = height;
this.speed = speed;
this.waypointIndex = waypointIndex;
this.latLng = latLng;
+ this.stop_time = stop_time;
this.bom1_show = bom1_show;
this.bom2_show = bom2_show;
+
}
public CreateLink(String name, double height, double speed, int waypointIndex, LatLng latLng) {
@@ -123,4 +126,12 @@ public class CreateLink {
public void setBom2_show(boolean bom2_show) {
this.bom2_show = bom2_show;
}
+
+ public int getStop_time() {
+ return stop_time;
+ }
+
+ public void setStop_time(int stop_time) {
+ this.stop_time = stop_time;
+ }
}
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/Click/MainClick.java b/app/src/main/java/com/example/longyi_groundstation/Main/Click/MainClick.java
new file mode 100644
index 0000000..1c3a883
--- /dev/null
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/Click/MainClick.java
@@ -0,0 +1,1022 @@
+package com.example.longyi_groundstation.Main.Click;
+
+import android.Manifest;
+import android.annotation.SuppressLint;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.amap.api.maps.CameraUpdateFactory;
+import com.amap.api.maps.model.BitmapDescriptorFactory;
+import com.amap.api.maps.model.LatLng;
+import com.amap.api.maps.model.Marker;
+import com.amap.api.maps.model.MarkerOptions;
+import com.amap.api.maps.model.PolylineOptions;
+import com.example.longyi_groundstation.Main.Activity.MainActivity;
+import com.example.longyi_groundstation.Main.Adapter.AllLinkAdapter;
+import com.example.longyi_groundstation.Main.Adapter.CreateLinkAdapter;
+import com.example.longyi_groundstation.Main.Base.CreateLink;
+import com.example.longyi_groundstation.Main.Service.MyBoundService;
+import com.example.longyi_groundstation.Main.Setting.Activity.SettingActivity;
+import com.example.longyi_groundstation.Main.Void.AllView;
+import com.example.longyi_groundstation.Main.Void.CoordinateConverter;
+import com.example.longyi_groundstation.Main.Void.FlyVoid;
+import com.example.longyi_groundstation.Main.Void.FpvGestureHandler;
+import com.example.longyi_groundstation.Main.Void.KeDaTTS;
+import com.example.longyi_groundstation.Main.Void.LidarDataParser;
+import com.example.longyi_groundstation.Main.Void.MapVoid;
+import com.example.longyi_groundstation.Main.Void.MyReceiver;
+import com.example.longyi_groundstation.Main.Void.MyTool;
+import com.example.longyi_groundstation.Main.Void.SQLClass;
+import com.example.longyi_groundstation.Main.Void.XiangTuo.Protocol;
+import com.example.longyi_groundstation.Main.Void.XiangTuo.TcpClientUtil;
+import com.example.longyi_groundstation.R;
+import com.example.longyi_groundstation.Util.Tool;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static android.view.View.GONE;
+import static android.view.View.VISIBLE;
+import static com.example.longyi_groundstation.MAVLink.enums.MAV_CMD.MAV_CMD_NAV_LAND;
+import static com.example.longyi_groundstation.MAVLink.enums.MAV_CMD.MAV_CMD_NAV_RETURN_TO_LAUNCH;
+import static com.example.longyi_groundstation.MAVLink.enums.MAV_CMD.MAV_CMD_NAV_TAKEOFF;
+
+public class MainClick implements View.OnClickListener {
+ private MainActivity mainActivity;
+ private AllView allView;
+ private MapVoid mapVoid;
+ private FlyVoid flyVoid;
+ private TcpClientUtil tcpClient;
+ private FpvGestureHandler fpvGestureHandler;
+
+ // 航线相关
+ private List waypointMarkers;
+ private List waypointPositions;
+ private List createLinkList;
+ private List selectedLinkList;
+ private List uploadLinkList;
+ private CreateLinkAdapter createLinkAdapter;
+ private AllLinkAdapter allLinkAdapter;
+ private SQLClass sqlClass;
+ private Marker selectMarker;
+ private Marker mainMarker;
+ private Marker orangeMarker;
+
+ // 其他变量
+ private int mainDisplay;
+ private boolean isSetLink;
+ private boolean isAdviseFly;
+ private boolean isUnlock;
+ private int isAddOrEdit;
+
+ public MainClick(MainActivity mainActivity, AllView allView, MapVoid mapVoid, FlyVoid flyVoid,
+ TcpClientUtil tcpClient, List waypointMarkers, List waypointPositions,
+ List createLinkList, List selectedLinkList,
+ List uploadLinkList, CreateLinkAdapter createLinkAdapter,
+ AllLinkAdapter allLinkAdapter, SQLClass sqlClass, Marker mainMarker) {
+ this.mainActivity = mainActivity;
+ this.allView = allView;
+ this.mapVoid = mapVoid;
+ this.flyVoid = flyVoid;
+ this.tcpClient = tcpClient;
+ this.waypointMarkers = waypointMarkers;
+ this.waypointPositions = waypointPositions;
+ this.createLinkList = createLinkList;
+ this.selectedLinkList = selectedLinkList;
+ this.uploadLinkList = uploadLinkList;
+ this.createLinkAdapter = createLinkAdapter;
+ this.allLinkAdapter = allLinkAdapter;
+ this.sqlClass = sqlClass;
+ this.mainMarker = mainMarker;
+ this.mainDisplay = 1;
+ this.isSetLink = false;
+ this.isAdviseFly = true;
+ this.isUnlock = false;
+ this.isAddOrEdit = 0;
+ }
+
+ // 设置器方法
+ public void setSelectMarker(Marker selectMarker) {
+ this.selectMarker = selectMarker;
+ }
+
+ public void setOrangeMarker(Marker orangeMarker) {
+ this.orangeMarker = orangeMarker;
+ }
+
+ public void setMainDisplay(int mainDisplay) {
+ this.mainDisplay = mainDisplay;
+ }
+
+ public void setIsSetLink(boolean isSetLink) {
+ this.isSetLink = isSetLink;
+ }
+
+ public void setIsAdviseFly(boolean isAdviseFly) {
+ this.isAdviseFly = isAdviseFly;
+ }
+
+ public void setIsUnlock(boolean isUnlock) {
+ this.isUnlock = isUnlock;
+ }
+
+ public void setIsAddOrEdit(int isAddOrEdit) {
+ this.isAddOrEdit = isAddOrEdit;
+ }
+
+ @Override
+ public void onClick(View v) {
+ int id = v.getId();
+
+ if (id == allView.ll_create_link_layout.getId()) {
+ Log.d("MainClick", "防止误触: ");
+ } else if (id == allView.ll_all_link_layout.getId()) {
+ Log.d("MainClick", "防止误触: ");
+ } else if (id == allView.v_mainDisplay.getId()) {
+ handleMainDisplayClick();
+ } else if (id == allView.iv_error.getId()) {
+ handleErrorMessageClick();
+ } else if (id == allView.ll_location_me.getId()) {
+ handleLocationMeClick();
+ } else if (id == allView.ll_turn_back.getId()) {
+ mainActivity.turnBackDialog.show();
+ } else if (id == allView.ll_lift_off.getId()) {
+ mainActivity.takeOffDialog.show();
+ } else if (id == allView.ll_icon_land.getId()) {
+ mainActivity.landDialog.show();
+ } else if (id == allView.ll_setting.getId()) {
+ handleSettingClick();
+ } else if (id == allView.ll_link_start_fun1.getId()) {
+ handleUploadMissionClick();
+ } else if (id == allView.ll_link_start_fun2.getId()) {
+ handleStartExecuteClick();
+ } else if (id == allView.ll_link_start_back.getId()) {
+ handleMissionBackClick();
+ } else if (id == allView.ll_left_open.getId()) {
+ handleLeftOpenClick();
+ } else if (id == allView.ll_link.getId()) {
+ Log.d("MainClick", "防止下层误触");
+ } else if (id == allView.ll_title.getId()) {
+ Log.d("MainClick", "防止下层误触");
+ } else if (id == allView.ll_clear.getId()) {
+ handleClearClick();
+ } else if (id == allView.tv_add_link.getId()) {
+ handleAddLinkClick();
+ } else if (id == allView.ll_map.getId()) {
+ handleMapClick();
+ } else if (id == allView.ll_link_save.getId()) {
+ handleSaveLinkClick();
+ } else if (id == allView.tv_link_fun1.getId()) {
+ handleReverseWaypointsClick();
+ } else if (id == allView.tv_link_fun2.getId()) {
+ handleClearAllWaypointsClick();
+ } else if (id == allView.ll_link_back.getId()) {
+ handleLinkBackClick();
+ } else if (id == allView.ll_execute_line.getId()) {
+ mainActivity.startExecuteDialog.show();
+ } else if (id == allView.ll_bombing.getId()) {
+ mainActivity.bombingDialog.show();
+ } else if (id == allView.ll_shout.getId()) {
+ Toast.makeText(mainActivity, "正在研发..", Toast.LENGTH_SHORT).show();
+ } else if (id == allView.ll_hook.getId()) {
+ Toast.makeText(mainActivity, "正在研发..", Toast.LENGTH_SHORT).show();
+ } else if (id == allView.ll_searchlight.getId()) {
+ Toast.makeText(mainActivity, "正在研发..", Toast.LENGTH_SHORT).show();
+ } else if (id == allView.ll_PTZ_one_center.getId()) {
+ handlePTZCenterClick();
+ } else if (id == allView.ll_PTZ_one_bottom.getId()) {
+ handlePTZBottomClick();
+ } else if (id == allView.iv_open_link_list.getId()) {
+ handleOpenLinkListClick();
+ } else if (id == allView.ll_clear_fly_line.getId()) {
+ handleClearFlyLineClick();
+ }
+ }
+
+ // 处理主显示切换点击
+ private void handleMainDisplayClick() {
+ if (mainDisplay == 1) {
+ mainDisplay = 2;
+ MyTool.setViewWH(mainActivity, allView.map, 150, 95, 3);
+ MyTool.setViewWH(mainActivity, allView.fpvWidget, 1920, 1200, 0);
+ mapVoid.allView.map.setElevation(5f);
+ mapVoid.allView.fpvWidget.setElevation(1f);
+ allView.map.setBackgroundResource(R.drawable.x80202020_4round_3stroke_bg);
+ allView.fpvWidget.setBackgroundColor(Color.parseColor("#ffffff"));
+ allView.map.setPadding(6, 6, 6, 6);
+ allView.fpvWidget.setPadding(0, 0, 0, 0);
+ allView.ll_left_error_layout.setVisibility(GONE);
+ allView.ll_ptz_ctrl.setVisibility(VISIBLE);
+ allView.ll_ptz_fun.setVisibility(VISIBLE);
+ } else {
+ mainDisplay = 1;
+ MyTool.setViewWH(mainActivity, allView.fpvWidget, 150, 95, 3);
+ MyTool.setViewWH(mainActivity, allView.map, 1920, 1200, 0);
+ mapVoid.allView.fpvWidget.setElevation(5f);
+ mapVoid.allView.map.setElevation(1f);
+ allView.fpvWidget.setBackgroundResource(R.drawable.x80202020_4round_3stroke_bg);
+ allView.map.setBackgroundColor(Color.parseColor("#ffffff"));
+ allView.fpvWidget.setPadding(6, 6, 6, 6);
+ allView.map.setPadding(0, 0, 0, 0);
+ allView.ll_left_error_layout.setVisibility(GONE);
+ allView.ll_ptz_ctrl.setVisibility(GONE);
+ allView.ll_ptz_fun.setVisibility(GONE);
+ }
+ }
+
+ // 处理错误信息点击
+ private void handleErrorMessageClick() {
+ if (allView.ll_left_error_layout.getVisibility() == VISIBLE) {
+ allView.ll_left_error_layout.setVisibility(GONE);
+ } else {
+ allView.ll_left_error_layout.setVisibility(VISIBLE);
+ }
+ }
+
+ // 处理定位到当前位置点击
+ private void handleLocationMeClick() {
+ if (MyReceiver.GLOBAL_POSITION_INT_json.optDouble("lat", 0) / 10000000 != 0) {
+ mapVoid.aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
+ new LatLng(MyReceiver.GLOBAL_POSITION_INT_json.optDouble("lat", 0) / 10000000,
+ MyReceiver.GLOBAL_POSITION_INT_json.optDouble("lon", 0) / 10000000), 15));
+ mainMarker.setVisible(true);
+ }
+ }
+
+ // 处理设置点击
+ private void handleSettingClick() {
+ if (MyBoundService.type == 0) {
+ if (MyBoundService.serialHelper != null) {
+ Intent intent = new Intent(mainActivity, SettingActivity.class);
+ mainActivity.startActivity(intent);
+ } else {
+ Toast.makeText(mainActivity, "串口连接失败", Toast.LENGTH_SHORT).show();
+ }
+ } else if (MyBoundService.type == 1) {
+ if (MyBoundService.serverSocket != null) {
+ Intent intent = new Intent(mainActivity, SettingActivity.class);
+ mainActivity.startActivity(intent);
+ } else {
+ Toast.makeText(mainActivity, "UDP连接失败", Toast.LENGTH_SHORT).show();
+ }
+ }
+ }
+
+ // 处理上传航线点击
+ private void handleUploadMissionClick() {
+ if (selectedLinkList.size() > 0) {
+ isAdviseFly = true;
+ flyVoid.creatDataList(mainActivity, (ArrayList) selectedLinkList, allView.et_start_execute_height.getText().toString());
+ allView.v_mainDisplay.setVisibility(VISIBLE);
+ allView.ll_open_layout.setVisibility(VISIBLE);
+ allView.ll_text.setVisibility(VISIBLE);
+ allView.ll_link_start.setVisibility(GONE);
+ allView.ll_all_link_layout.setVisibility(GONE);
+ allView.fpvWidget.setVisibility(VISIBLE);
+ uploadLinkList.addAll(selectedLinkList);
+ allView.ll_assistance_layout.setVisibility(VISIBLE);
+ } else {
+ Toast.makeText(mainActivity, "请选择航线", Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ // 处理开始执行点击
+ private void handleStartExecuteClick() {
+ if (selectedLinkList != null) {
+ if (isUnlock) {
+ mainActivity.startExecuteDialog.show();
+ } else {
+ Toast.makeText(mainActivity, "请先解锁", Toast.LENGTH_SHORT).show();
+ }
+ } else {
+ Toast.makeText(mainActivity, "请先选择航线", Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ // 处理航线退出点击
+ private void handleMissionBackClick() {
+ if (uploadLinkList != null) {
+ clearWaypoints();
+ displayRouteOnMap((ArrayList) uploadLinkList);
+ }
+ allView.v_mainDisplay.setVisibility(VISIBLE);
+ allView.ll_open_layout.setVisibility(VISIBLE);
+ allView.ll_text.setVisibility(VISIBLE);
+ allView.ll_link_start.setVisibility(GONE);
+ allView.ll_all_link_layout.setVisibility(GONE);
+ allView.fpvWidget.setVisibility(VISIBLE);
+ allView.ll_assistance_layout.setVisibility(VISIBLE);
+ isAdviseFly = true;
+ }
+
+ // 处理左侧打开点击
+ private void handleLeftOpenClick() {
+ if (allView.ll_function_layout.getVisibility() == VISIBLE) {
+ allView.ll_function_layout.setVisibility(GONE);
+ } else {
+ allView.ll_function_layout.setVisibility(VISIBLE);
+ }
+ }
+
+ // 处理清除点击
+ private void handleClearClick() {
+ try {
+ uploadLinkList.clear();
+ clearWaypoints();
+ displayRouteOnMap((ArrayList) uploadLinkList);
+ if (orangeMarker != null) {
+ orangeMarker.remove();
+ }
+ } catch (Exception e) {
+ Log.d("MainClick", "handleClearClick: " + e);
+ }
+ Toast.makeText(mainActivity, "已清除", Toast.LENGTH_SHORT).show();
+ }
+
+ // 处理添加航线点击
+ private void handleAddLinkClick() {
+ isAddOrEdit = 0;
+ clearWaypoints();
+ isSetLink = true;
+ allView.ll_all_link_layout.setVisibility(GONE);
+ allView.ll_link_start.setVisibility(GONE);
+ allView.v_mainDisplay.setVisibility(GONE);
+ allView.ll_open_layout.setVisibility(GONE);
+ allView.ll_text.setVisibility(GONE);
+ allView.ll_link.setVisibility(VISIBLE);
+ allView.ll_create_link_layout.setVisibility(VISIBLE);
+ allView.fpvWidget.setVisibility(GONE);
+ }
+
+ // 处理航线规划点击
+ private void handleMapClick() {
+ clearWaypoints();
+ isAdviseFly = false;
+ allView.ll_all_link_layout.setVisibility(VISIBLE);
+ allView.ll_link_start.setVisibility(VISIBLE);
+ allView.v_mainDisplay.setVisibility(GONE);
+ allView.ll_open_layout.setVisibility(GONE);
+ allView.ll_text.setVisibility(GONE);
+ allView.ll_link.setVisibility(GONE);
+ allView.ll_create_link_layout.setVisibility(GONE);
+ allView.fpvWidget.setVisibility(GONE);
+ allView.ll_assistance_layout.setVisibility(GONE);
+ }
+
+ // 处理保存航线点击
+ private void handleSaveLinkClick() {
+ if (allView.et_link_name.getText().toString().length() != 0) {
+ saveLink(null);
+ } else {
+ mainActivity.saveLinkNameDialog.show();
+ }
+ }
+
+ // 处理反转航点顺序点击
+ private void handleReverseWaypointsClick() {
+ AlertDialog.Builder builder = new AlertDialog.Builder(mainActivity);
+ builder.setTitle("反转航点顺序");
+ builder.setMessage("确定要反转当前航点的顺序吗?");
+
+ builder.setPositiveButton("确定", (dialog, which) -> {
+ java.util.Collections.reverse(waypointPositions);
+ java.util.Collections.reverse(waypointMarkers);
+ java.util.Collections.reverse(createLinkList);
+ renumberWaypoints();
+ updateFlightPath();
+ dialog.dismiss();
+ });
+
+ builder.setNegativeButton("取消", (dialog, which) -> {
+ dialog.dismiss();
+ });
+
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ }
+
+ // 处理清除所有航点点击
+ private void handleClearAllWaypointsClick() {
+ AlertDialog.Builder builder = new AlertDialog.Builder(mainActivity);
+ builder.setTitle("清除所有航点");
+ builder.setMessage("确定要清除所有航点和航线吗?");
+
+ builder.setPositiveButton("确定", (dialog, which) -> {
+ clearWaypoints();
+ dialog.dismiss();
+ });
+
+ builder.setNegativeButton("取消", (dialog, which) -> {
+ dialog.dismiss();
+ });
+
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ }
+
+ // 处理航线规划退出点击
+ private void handleLinkBackClick() {
+ if (createLinkList.size() > 0) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(mainActivity);
+ builder.setTitle("退出");
+ builder.setMessage("确定要退出嘛?退出前的航线不会保存");
+
+ builder.setPositiveButton("确定", (dialog, which) -> {
+ clearWaypoints();
+ isSetLink = false;
+ allView.ll_all_link_layout.setVisibility(VISIBLE);
+ allView.ll_link_start.setVisibility(VISIBLE);
+ allView.v_mainDisplay.setVisibility(GONE);
+ allView.ll_open_layout.setVisibility(GONE);
+ allView.ll_text.setVisibility(GONE);
+ allView.ll_link.setVisibility(GONE);
+ allView.ll_create_link_layout.setVisibility(GONE);
+ allView.fpvWidget.setVisibility(GONE);
+ displayRouteOnMap((ArrayList) selectedLinkList);
+ dialog.dismiss();
+ displayRouteOnMap((ArrayList) selectedLinkList);
+ });
+
+ builder.setNegativeButton("取消", (dialog, which) -> {
+ dialog.dismiss();
+ });
+
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ } else {
+ clearWaypoints();
+ isSetLink = false;
+ allView.ll_all_link_layout.setVisibility(VISIBLE);
+ allView.ll_link_start.setVisibility(VISIBLE);
+ allView.v_mainDisplay.setVisibility(GONE);
+ allView.ll_open_layout.setVisibility(GONE);
+ allView.ll_text.setVisibility(GONE);
+ allView.ll_link.setVisibility(GONE);
+ allView.ll_create_link_layout.setVisibility(GONE);
+ allView.fpvWidget.setVisibility(GONE);
+ }
+ }
+
+ // 处理云台回中点击
+ private void handlePTZCenterClick() {
+ byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x13, 0x03, 0x00, 0x00, 0x17};
+ tcpClient.sendBytes(testData);
+ }
+
+ // 处理云台向下点击
+ private void handlePTZBottomClick() {
+ byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x13, 0x02, 0x00, 0x00, 0x16};
+ tcpClient.sendBytes(testData);
+ }
+
+ // 处理开启/关闭航线点位点击
+ private void handleOpenLinkListClick() {
+ if (allView.ll_create_link_item_layout.getVisibility() == View.GONE) {
+ allView.ll_create_link_item_layout.setVisibility(View.VISIBLE);
+ } else {
+ allView.ll_create_link_item_layout.setVisibility(View.GONE);
+ }
+ }
+
+ // 处理清除飞行轨迹点击
+ private void handleClearFlyLineClick() {
+ if (mapVoid.isTracking) {
+ mapVoid.isTracking = false;
+ mapVoid.clearFlightTrack();
+ mapVoid.stopFlightTracking();
+ } else {
+ mapVoid.startFlightTracking();
+ }
+ }
+
+ // 保存航线方法
+ private void saveLink(String linkName) {
+ ArrayList createLinkLists = new ArrayList<>();
+ if (createLinkList.size() > 0) {
+ createLinkLists.addAll(createLinkList);
+ boolean success;
+
+ if (isAddOrEdit == 0) { // 添加模式
+ if (linkName == null) {
+ if (allView.et_link_name.getText().toString().length() != 0) {
+ success = sqlClass.addCreateLinkList(allView.et_link_name.getText().toString(), createLinkLists);
+ } else {
+ success = sqlClass.addCreateLinkList("航线-" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), createLinkLists);
+ }
+ } else {
+ success = sqlClass.addCreateLinkList(linkName, createLinkLists);
+ }
+ } else { // 编辑模式
+ if (allLinkAdapter.getSelectLinkListInfo() != -1) {
+ int currentLinkId = allLinkAdapter.getSelectLinkListInfo();
+ if (linkName == null) {
+ if (allView.et_link_name.getText().toString().length() != 0) {
+ success = sqlClass.updateCreateLinkList(currentLinkId, allView.et_link_name.getText().toString(), createLinkLists);
+ } else {
+ success = sqlClass.updateCreateLinkList(
+ currentLinkId,
+ "航线-" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), createLinkLists);
+ }
+ } else {
+ success = sqlClass.updateCreateLinkList(currentLinkId, linkName, createLinkLists);
+ }
+ } else {
+ Toast.makeText(mainActivity, "获取列表错误", Toast.LENGTH_SHORT).show();
+ success = false;
+ }
+ }
+
+ if (success) {
+ clearWaypoints();
+ isSetLink = false;
+ allView.ll_all_link_layout.setVisibility(VISIBLE);
+ allView.ll_link_start.setVisibility(VISIBLE);
+ allView.v_mainDisplay.setVisibility(GONE);
+ allView.ll_open_layout.setVisibility(GONE);
+ allView.ll_text.setVisibility(GONE);
+ allView.ll_link.setVisibility(GONE);
+ allView.ll_create_link_layout.setVisibility(GONE);
+ allView.fpvWidget.setVisibility(GONE);
+ allView.et_link_name.setText("");
+ displayRouteOnMap((ArrayList) selectedLinkList);
+ refreshLinkList();
+ Toast.makeText(mainActivity, isAddOrEdit == 0 ? "航线保存成功" : "航线更新成功", Toast.LENGTH_SHORT).show();
+ }
+ } else {
+ Toast.makeText(mainActivity, "请先添加航点", Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ // 刷新航线列表
+ private void refreshLinkList() {
+ if (sqlClass != null && allLinkAdapter != null) {
+ List updatedList = sqlClass.getAllLinkListInfo();
+ allLinkAdapter.updateDataList(updatedList);
+ }
+ }
+
+ // 清除航点
+ private void clearWaypoints() {
+ for (Marker marker : waypointMarkers) {
+ if (marker != null) {
+ marker.remove();
+ }
+ }
+ waypointMarkers.clear();
+ waypointPositions.clear();
+ createLinkList.clear();
+ selectedLinkList.clear();
+ createLinkAdapter.setCreateLinkList(createLinkList);
+ }
+
+ // 重新编号航点
+ private void renumberWaypoints() {
+ for (int i = 0; i < waypointMarkers.size(); i++) {
+ Bitmap markerBitmap = createCustomMarkerBitmap((i + 1) + "");
+ waypointMarkers.get(i).setIcon(BitmapDescriptorFactory.fromBitmap(markerBitmap));
+ if (i < createLinkList.size()) {
+ createLinkList.get(i).setName((i + 1) + "");
+ }
+ }
+ createLinkAdapter.setCreateLinkList(createLinkList);
+ }
+
+ // 创建自定义标记Bitmap
+ private Bitmap createCustomMarkerBitmap(String text) {
+ View markerView = mainActivity.getLayoutInflater().inflate(R.layout.custom_marker_layout, null);
+ TextView markerText = markerView.findViewById(R.id.marker_text);
+ markerText.setText(text);
+
+ markerView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
+ markerView.layout(0, 0, markerView.getMeasuredWidth(), markerView.getMeasuredHeight());
+ markerView.buildDrawingCache();
+ return markerView.getDrawingCache();
+ }
+
+ // 更新航线显示
+ private void updateFlightPath() {
+ // 在MainActivity中实现,因为需要访问flightPathPolyline
+ }
+
+ // 在地图上显示航线
+ private void displayRouteOnMap(ArrayList createLinkList) {
+ // 在MainActivity中实现,因为需要访问this.createLinkList
+ }
+
+ // 添加或更新橘黄色marker
+ public void addOrUpdateOrangeMarker(LatLng latLng) {
+ if (orangeMarker != null) {
+ orangeMarker.remove();
+ }
+ orangeMarker = allView.map.getMap().addMarker(new MarkerOptions().position(latLng)
+ .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE))
+ .title("指点飞行目标点"));
+ }
+
+ // 根据标记查找航点索引
+ private int findWaypointMarkerIndex(Marker marker) {
+ return waypointMarkers.indexOf(marker);
+ }
+
+ // 统一处理四个方向的航点移动点击事件
+ public View.OnClickListener getMarkerMoveClickListener() {
+ return new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ int selectedIndex = findWaypointMarkerIndex(selectMarker);
+ if (selectedIndex == -1) {
+ Toast.makeText(mainActivity, "未选择有效的航点", Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ String distanceStr = allView.et_marker_distance.getText().toString();
+ if (distanceStr.isEmpty()) {
+ Toast.makeText(mainActivity, "请输入移动距离", Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ double distanceInMeters;
+ try {
+ distanceInMeters = Double.parseDouble(distanceStr);
+ } catch (NumberFormatException e) {
+ Toast.makeText(mainActivity, "请输入有效的距离数值", Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ LatLng currentLatLng = selectMarker.getPosition();
+ double latOffset = 0;
+ double lngOffset = 0;
+
+ if (v == allView.iv_marker_top) {
+ latOffset = distanceInMeters / 111320.0;
+ } else if (v == allView.iv_marker_bottom) {
+ latOffset = -distanceInMeters / 111320.0;
+ } else if (v == allView.iv_marker_left) {
+ lngOffset = -distanceInMeters / (111320.0 * Math.cos(Math.toRadians(currentLatLng.latitude)));
+ } else if (v == allView.iv_marker_right) {
+ lngOffset = distanceInMeters / (111320.0 * Math.cos(Math.toRadians(currentLatLng.latitude)));
+ }
+
+ LatLng newLatLng = new LatLng(currentLatLng.latitude + latOffset, currentLatLng.longitude + lngOffset);
+ selectMarker.setPosition(newLatLng);
+ waypointPositions.set(selectedIndex, newLatLng);
+
+ if (selectedIndex < createLinkList.size()) {
+ CreateLink createLink = createLinkList.get(selectedIndex);
+ CreateLink updatedCreateLink = new CreateLink(
+ createLink.getName(),
+ createLink.getHeight(),
+ createLink.getSpeed(),
+ createLink.getWaypointIndex(),
+ newLatLng,
+ createLink.getStop_time(),
+ createLink.isBom1_show(),
+ createLink.isBom2_show()
+ );
+ createLinkList.set(selectedIndex, updatedCreateLink);
+ createLinkAdapter.setCreateLinkList(createLinkList);
+ }
+ }
+ };
+ }
+
+ // 获取FPV手势监听器
+ public FpvGestureHandler.OnFpvGestureListener getFpvGestureListener() {
+ return new FpvGestureHandler.OnFpvGestureListener() {
+ private boolean isSwiping = false;
+ private String lastDirection = "";
+
+ @Override
+ public void onTap(float x, float y) {
+ int fpvWidth = allView.fpvWidget.getWidth();
+ int fpvHeight = allView.fpvWidget.getHeight();
+
+ byte convertedX = (byte) Math.max(0x00, Math.min(0xFF, Math.round((x / fpvWidth) * 255)));
+ byte convertedY = (byte) Math.max(0x00, Math.min(0xFF, Math.round((y / fpvHeight) * 255)));
+
+ if (!tcpClient.isConnected()) {
+ Toast.makeText(mainActivity.getApplicationContext(), "未连接到服务器", Toast.LENGTH_SHORT).show();
+ } else {
+ byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x10, 0x00, convertedX, convertedY, Protocol.calculateCheckCode((byte) 0x01, (byte) 0x10, (byte) 0x00, convertedX, convertedY)};
+ tcpClient.sendBytes(testData);
+ }
+ }
+
+ @Override
+ public void onDoubleTap(float x, float y) {
+ Log.d("MainClick", "FPV双击: x=" + x + ", y=" + y);
+ }
+
+ @Override
+ public void onLongPress(float x, float y) {
+ Log.d("MainClick", "FPV长按: x=" + x + ", y=" + y);
+ }
+
+ @Override
+ public void onSwipe(float startX, float startY, float endX, float endY, float distanceX, float distanceY) {
+ String currentDirection;
+ if (Math.abs(distanceX) > Math.abs(distanceY)) {
+ if (distanceX > 0) {
+ currentDirection = "right";
+ } else {
+ currentDirection = "left";
+ }
+ } else {
+ if (distanceY > 0) {
+ currentDirection = "down";
+ } else {
+ currentDirection = "up";
+ }
+ }
+
+ if (!isSwiping || !lastDirection.equals(currentDirection)) {
+ isSwiping = true;
+ lastDirection = currentDirection;
+ Log.d("MainClick", "FPV向" + currentDirection + "滑动");
+ switch (currentDirection) {
+ case "up":
+ if (!tcpClient.isConnected()) {
+ Toast.makeText(mainActivity.getApplicationContext(), "未连接到服务器", Toast.LENGTH_SHORT).show();
+ break;
+ } else {
+ byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x08, 0x00, (byte) 0xFF, 0x08};
+ tcpClient.sendBytes(testData);
+ }
+ break;
+
+ case "down":
+ if (!tcpClient.isConnected()) {
+ Toast.makeText(mainActivity.getApplicationContext(), "未连接到服务器", Toast.LENGTH_SHORT).show();
+ break;
+ } else {
+ byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x10, 0x00, (byte) 0xFF, 0x10};
+ tcpClient.sendBytes(testData);
+ }
+ break;
+
+ case "left":
+ if (!tcpClient.isConnected()) {
+ Toast.makeText(mainActivity.getApplicationContext(), "未连接到服务器", Toast.LENGTH_SHORT).show();
+ break;
+ } else {
+ byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x04, (byte) 0xFF, 0x00, 0x04};
+ tcpClient.sendBytes(testData);
+ }
+ break;
+
+ case "right":
+ if (!tcpClient.isConnected()) {
+ Toast.makeText(mainActivity.getApplicationContext(), "未连接到服务器", Toast.LENGTH_SHORT).show();
+ break;
+ } else {
+ byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x02, (byte) 0xFF, 0x00, 0x02};
+ tcpClient.sendBytes(testData);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onSwipeUp() {}
+
+ @Override
+ public void onSwipeDown() {}
+
+ @Override
+ public void onSwipeLeft() {}
+
+ @Override
+ public void onSwipeRight() {}
+
+ @Override
+ public void onZoom(float scaleFactor) {
+ Log.d("MainClick", "FPV缩放: scaleFactor=" + scaleFactor);
+ }
+
+ @Override
+ public void onSwipeEnd() {
+ isSwiping = false;
+ lastDirection = "";
+ byte[] testData1 = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01};
+ tcpClient.sendBytes(testData1);
+ }
+ };
+ }
+
+ // 获取PTZ触摸监听器
+ public View.OnTouchListener getPTZTouchListener() {
+ return new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ handlePTZTouchDown(v);
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ handlePTZTouchUp();
+ break;
+ }
+ return true;
+ }
+ };
+ }
+
+ // 处理PTZ触摸按下
+ private void handlePTZTouchDown(View v) {
+ if (v == allView.iv_ptz_top) {
+ Log.d("MainClick", "iv_ptz_top被按下");
+ if (!tcpClient.isConnected()) {
+ Toast.makeText(mainActivity, "未连接到服务器", Toast.LENGTH_SHORT).show();
+ } else {
+ byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x08, 0x00, (byte) 0xFF, 0x08};
+ tcpClient.sendBytes(testData);
+ }
+ } else if (v == allView.iv_ptz_left) {
+ Log.d("MainClick", "iv_ptz_left被按下");
+ if (!tcpClient.isConnected()) {
+ Toast.makeText(mainActivity, "未连接到服务器", Toast.LENGTH_SHORT).show();
+ } else {
+ byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x04, (byte) 0xFF, 0x00, 0x04};
+ tcpClient.sendBytes(testData);
+ }
+ } else if (v == allView.iv_ptz_right) {
+ Log.d("MainClick", "iv_ptz_right被按下");
+ if (!tcpClient.isConnected()) {
+ Toast.makeText(mainActivity, "未连接到服务器", Toast.LENGTH_SHORT).show();
+ } else {
+ byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x02, (byte) 0xFF, 0x00, 0x02};
+ tcpClient.sendBytes(testData);
+ }
+ } else if (v == allView.iv_ptz_bottom) {
+ Log.d("MainClick", "iv_ptz_bottom被按下");
+ if (!tcpClient.isConnected()) {
+ Toast.makeText(mainActivity, "未连接到服务器", Toast.LENGTH_SHORT).show();
+ } else {
+ byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x10, 0x00, (byte) 0xFF, 0x10};
+ tcpClient.sendBytes(testData);
+ }
+ } else if (v == allView.ll_PTZ_amplify) {
+ Log.d("MainClick", "ll_PTZ_amplify被按下");
+ if (!tcpClient.isConnected()) {
+ Toast.makeText(mainActivity, "未连接到服务器", Toast.LENGTH_SHORT).show();
+ } else {
+ byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x40, 0x04, 0x00, 0x45};
+ tcpClient.sendBytes(testData);
+ }
+ } else if (v == allView.ll_PTZ_reduce) {
+ Log.d("MainClick", "ll_PTZ_reduce被按下");
+ if (!tcpClient.isConnected()) {
+ Toast.makeText(mainActivity, "未连接到服务器", Toast.LENGTH_SHORT).show();
+ } else {
+ byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x20, 0x04, 0x00, 0x25};
+ tcpClient.sendBytes(testData);
+ }
+ }
+ }
+
+ // 处理PTZ触摸抬起
+ private void handlePTZTouchUp() {
+ if (!tcpClient.isConnected()) {
+ Toast.makeText(mainActivity, "未连接到服务器", Toast.LENGTH_SHORT).show();
+ } else {
+ byte[] testData1 = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x60, 0x00, 0x00, 0x61};
+ tcpClient.sendBytes(testData1);
+ }
+ }
+
+ // 获取地图点击监听器
+ public com.amap.api.maps.AMap.OnMapClickListener getMapClickListener() {
+ return latLng -> {
+ if (isSetLink) {
+ addWaypoint(latLng);
+ }
+ };
+ }
+
+ // 获取地图长按监听器
+ public com.amap.api.maps.AMap.OnMapLongClickListener getMapLongClickListener() {
+ return latLng -> {
+ if (isAdviseFly) {
+ addOrUpdateOrangeMarker(latLng);
+ mainActivity.pointFlyDialog.setLatLng(latLng);
+ mainActivity.pointFlyDialog.show();
+ } else {
+ Toast.makeText(mainActivity, "当前状态不可使用", Toast.LENGTH_SHORT).show();
+ }
+ };
+ }
+
+ // 获取标记点击监听器
+ public com.amap.api.maps.AMap.OnMarkerClickListener getMarkerClickListener() {
+ return marker -> {
+ if (isSetLink) {
+ int index = findWaypointMarkerIndex(marker);
+ if (index != -1) {
+ selectMarker = marker;
+ allView.rv_create_link_list.smoothScrollToPosition(index);
+ if (allView.ll_marker_ctrl.getVisibility() == View.GONE) {
+ allView.ll_marker_ctrl.setVisibility(VISIBLE);
+ } else {
+ allView.ll_marker_ctrl.setVisibility(GONE);
+ }
+ return true;
+ }
+ }
+ return false;
+ };
+ }
+
+ // 获取地图加载监听器
+ public com.amap.api.maps.AMap.OnMapLoadedListener getMapLoadedListener() {
+ return () -> {
+ if (isSetLink) {
+ for (Marker marker : waypointMarkers) {
+ marker.showInfoWindow();
+ }
+ }
+ };
+ }
+
+ // 获取文本变化监听器
+ public TextWatcher getTextWatcher() {
+ return new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ filterLinkList(s.toString());
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {}
+ };
+ }
+
+ // 添加航点
+ private void addWaypoint(LatLng latLng) {
+ View markerView = mainActivity.getLayoutInflater().inflate(R.layout.custom_marker_layout, null);
+ TextView markerText = markerView.findViewById(R.id.marker_text);
+ markerText.setText("" + (waypointMarkers.size() + 1));
+
+ markerView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
+ markerView.layout(0, 0, markerView.getMeasuredWidth(), markerView.getMeasuredHeight());
+ markerView.buildDrawingCache();
+ Bitmap markerBitmap = markerView.getDrawingCache();
+
+ MarkerOptions markerOptions = new MarkerOptions().position(latLng)
+ .icon(BitmapDescriptorFactory.fromBitmap(markerBitmap)).draggable(false);
+
+ Marker marker = allView.map.getMap().addMarker(markerOptions);
+
+ waypointMarkers.add(marker);
+ waypointPositions.add(latLng);
+
+ CreateLink createLink = new CreateLink(
+ waypointMarkers.size() + "",
+ 20,
+ 3,
+ waypointMarkers.size() - 1,
+ latLng,
+ 0,
+ true,
+ true);
+ createLinkList.add(createLink);
+ createLinkAdapter.setCreateLinkList(createLinkList);
+ }
+
+ // 过滤航线列表
+ private void filterLinkList(String query) {
+ if (sqlClass != null && allLinkAdapter != null) {
+ if (query.isEmpty()) {
+ List allList = sqlClass.getAllLinkListInfo();
+ allLinkAdapter.updateDataList(allList);
+ } else {
+ List filteredList = new ArrayList<>();
+ List fullList = sqlClass.getAllLinkListInfo();
+
+ for (SQLClass.LinkListInfo item : fullList) {
+ if (item.getListName().toLowerCase().contains(query.toLowerCase())) {
+ filteredList.add(item);
+ }
+ }
+
+ allLinkAdapter.updateDataList(filteredList);
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/Service/MyBoundService.java b/app/src/main/java/com/example/longyi_groundstation/Main/Service/MyBoundService.java
index 8e45121..f448fc9 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Main/Service/MyBoundService.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/Service/MyBoundService.java
@@ -41,6 +41,8 @@ import com.example.longyi_groundstation.MAVLink.common.msg_request_data_stream;
import com.example.longyi_groundstation.Main.Base.MLData;
import com.example.longyi_groundstation.Main.Setting.Base.Param;
import com.example.longyi_groundstation.Main.Void.FlyVoid;
+import com.example.longyi_groundstation.Main.Void.HeartbeatManager;
+import com.example.longyi_groundstation.Main.Void.LidarDataParser;
import com.example.longyi_groundstation.Main.Void.LogCat.LogUtil;
import com.example.longyi_groundstation.Main.Void.MyTool;
import com.example.longyi_groundstation.Util.BroadcastUtil;
@@ -116,14 +118,23 @@ public class MyBoundService extends Service {
private Parser parser = new Parser();
private MAVLinkMessage msgOld = null;
+ // 在类成员变量区域添加以下两个标志位
+ private boolean isAttitudeDataRequested = false;
+ private boolean isParamReadListRequested = false;
+ // 在成员变量区域添加
+ private HeartbeatManager heartbeatManager;
+
+
+
private void getData() {
// 启动定时器
paramTimeoutHandler.post(paramTimeoutRunnable);
isRunning = true;
// serialPortFinder = new SerialPortFinder();
- //判断打开方式0:串口 2:UDP
+ //判断打开方式0:串口 1:UDP
if (type == 0) {
serialHelper = new SerialHelper("/dev/ttyHS0", 115200) {
+// serialHelper = new SerialHelper("/dev/ttyHS0", 57600) {
@Override
protected void onDataReceived(final ComBean comBean) {
// Log.d("cuijingzhou", Tool.bytesToHex(comBean.bRec));
@@ -134,10 +145,6 @@ public class MyBoundService extends Service {
};
try {
serialHelper.open();
- // 可以在这里添加回复逻辑
- requestAttitudeData();
- requestParamReadList();
-// wordT1();
} catch (IOException e) {
// throw new RuntimeException(e);
Log.d(TAG, e.toString());
@@ -148,27 +155,19 @@ public class MyBoundService extends Service {
new Thread(() -> {
try {
serverSocket = new DatagramSocket(Integer.parseInt(serverPort));
- // 可以在这里添加回复逻辑
- requestAttitudeData();
- requestParamReadList();
- byte[] buffer = new byte[1024];
+ byte[] buffer = new byte[512];
while (isRunning) {
try {
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
serverSocket.receive(packet);
+ Log.d("cesssss", "接收数据: " + bytesToHex(packet.getData()));
// 获取客户端IP和端口
InetAddress clientAddress = packet.getAddress();
int clientPort = packet.getPort();
// 处理接收到的数据
-// String receivedData = MyTool.bytesToHex(packet.getData(), packet.getLength());
-// Log.e("cuijingzhou-size", packet.getLength()+"");
- String logMsg = "来自 " + clientAddress.getHostAddress() + ":" + clientPort + " 的消息: ";
-// Log.e("cuijingzhou-IP:", logMsg);
-
dataWork(packet.getData(), packet.getLength());
-// requestParamRead();
} catch (Exception e) {
Log.e(TAG, "接收数据错误: " + e.getMessage());
@@ -186,69 +185,87 @@ public class MyBoundService extends Service {
wordT();
}
+ /**
+ * 方法:初始化数据请求,确保只执行一次
+ */
+ private void requestInitialData() {
+ // 请求参数列表(只执行一次)
+ requestParamReadList();
+ // 请求姿态数据(只执行一次)
+ requestAttitudeData();
+ }
+
+
+ private LidarDataParser lidarParser = new LidarDataParser();
+
/**
* 方法:连接串口2,获取高度或一些其他的硬件设施
*
* @cuijingzhou
*/
private void getDataSerial() {
-
- if (type == 0){
- serialHelper2 = new SerialHelper("/dev/ttyHS2", 9600) {
- @Override
- protected void onDataReceived(final ComBean comBean) {
-// Log.d("cuijingzhou", Tool.bytesToHex(comBean.bRec));
- // 接收数据
- byte[] receivedData = comBean.bRec;
- int[] parseSerialData = parseSerialData(receivedData);
- // 保存接收到的数据
- FlyVoid.parseSerialData = parseSerialData;
- Log.d("cuijingzhou_getDataSerial", parseSerialData[0]+"-"+parseSerialData[1]);
-// dataWork(receivedData, receivedData.length);
- }
- };
+ if (type == 0) {
try {
+ serialHelper2 = new SerialHelper("/dev/ttyHS2", 9600) {
+ @Override
+ protected void onDataReceived(final ComBean comBean) {
+ // 接收数据
+ byte[] receivedData = comBean.bRec;
+ int maxLoop = 100; // 最大解析次数,防止耗时过长
+
+ // 200Hz以上高频率调用
+ for (int i = 0; i < receivedData.length && maxLoop > 0; i++) {
+ lidarParser.parseByte(receivedData[i]);
+ maxLoop--;
+ }
+ }
+ };
serialHelper2.open();
-// wordT1();
} catch (IOException e) {
-// throw new RuntimeException(e);
- Log.d(TAG, e.toString());
+ Log.d("getDataSerialE", e.toString());
}
- }else {
+ } else {
new Thread(() -> {
try {
serverSocket2 = new DatagramSocket(13551);
- byte[] buffer = new byte[1024];
+ // 增加缓冲区大小以适应完整数据包
+ byte[] buffer = new byte[10];
while (isRunning) {
try {
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
serverSocket2.receive(packet);
- // 获取客户端IP和端口
- int[] parseSerialData = parseSerialData(packet.getData());
- // 保存接收到的数据
- FlyVoid.parseSerialData = parseSerialData;
- Log.d("cuijingzhou_getDataSerial", parseSerialData[0]+"-"+parseSerialData[1]);
-// Log.e("cuijingzhou-IP:", logMsg);
+ if (packet.getData() != null && packet.getLength() > 0) {
+ // 使用新方法解析数据
+// int maxLoop = 100; // 最大解析次数,防止耗时过长
+ // 200Hz以上高频率调用
+ for (int i = 0; i < packet.getData().length; i++) {
+ lidarParser.parseByte(packet.getData()[i]);
+// maxLoop--;
+ }
+ }
} catch (Exception e) {
- Log.e(TAG, "接收数据错误: " + e.getMessage());
+ Log.d("cuijingzhou_getDataSerial", "处理数据包时出错: " + e.toString());
}
}
} catch (SocketException e) {
- Log.e(TAG, "启动服务端失败: " + e.getMessage());
-
+ Log.d("cuijingzhou_getDataSerial", "启动失败");
} finally {
stopUdpServer();
}
}).start();
}
-
-
}
/**
* 方法:发送请求姿态数据的MAVLink指令
*/
public void requestAttitudeData() {
+ // 确保只执行一次
+ if (isAttitudeDataRequested) {
+ return;
+ }
+ isAttitudeDataRequested = true;
+
// 构造REQUEST_DATA_STREAM消息
msg_request_data_stream request = new msg_request_data_stream();
request.target_system = 1; // 飞机系统ID
@@ -289,6 +306,11 @@ public class MyBoundService extends Service {
* 请求特定参数 (MAVLINK_MSG_ID_PARAM_REQUEST_READ)
*/
public void requestParamReadList() {
+ // 确保只执行一次
+ if (isParamReadListRequested) {
+ return;
+ }
+ isParamReadListRequested = true;
msg_param_request_list request = new msg_param_request_list();
request.target_system = 1; // 飞控系统ID
@@ -323,6 +345,8 @@ public class MyBoundService extends Service {
}
+
+
/**
* 方法:处理返回的mavlink协议(byte[])
* receivedData:字节[]
@@ -336,23 +360,51 @@ public class MyBoundService extends Service {
MAVLinkPacket mavLinkPacket = parser.mavlink_parse_char(receivedData[i]);
if (mavLinkPacket != null) {
MAVLinkMessage msg = mavLinkPacket.unpack();
+
+// new_ts = get_sys_ms;
+// switch (msg.id)
+// {
+// case 0:
+// if (new_ts - id_0_ts > 100 ) {
+// MAV.heartbeat = msg.payload;
+// id_0_ts = new_ts;
+// }
+// break;
+//
+// case 121:
+// id_121_down_sample_count ++;
+// if (id_121_down_sample_count % 10 == 0) {
+// MAV.gps = msg.payload;
+// }
+// break;
+//
+// default:
+// break;
+// }
+
+ if (msg.msgid == 0) {
+// Log.d("msg.msgid", "213");
+// Log.d("msg.msgid", MsgList.get(msg.msgid)+"");
+ requestInitialData();
+ }
//判断当前索引下的数据是否有变动,如过没有变动,就不储存,用一个判断增加性能
if (!msg.toString().equals(MsgList.get(msg.msgid))) {
// Log.d("cuijigzhou_msg_all", msg.toString());
- LogUtil.d("cuijigzhou_msg_all", msg.toString());
-
+// LogUtil.d("cuijigzhou_msg_all", msg.toString());
MsgList.set(msg.msgid, msg.toString());
if (msgOld == null) {
MsgList.set(msg.msgid, msg.toString());
msgOld = msg;
} else {
+// if (msg.msgid == 0) {
+// Log.d("msg.msgid", MsgList.get(msg.msgid));
+// }
//主要是应对STATUSTEXT(253)这样的特殊数据
wordT1(msg);
msgOld = msg;
- if (msg.msgid == MAVLINK_MSG_ID_MISSION_ACK){
- Log.d("msg.msgid", MsgList.get(msg.msgid));
- }
-
+// if (msg.msgid == MAVLINK_MSG_ID_MISSION_ACK) {
+// Log.d("msg.msgid", MsgList.get(msg.msgid));
+// }
}
}
@@ -401,10 +453,6 @@ public class MyBoundService extends Service {
BroadcastUtil.Broadcast_MISSION_CURRENT(getApplication(), MsgList.get(MAVLINK_MSG_ID_MISSION_CURRENT));
}
-
-
-
-
Thread.sleep(50);
}
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Activity/SettingActivity.java b/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Activity/SettingActivity.java
index e2cd36c..56ea1b8 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Activity/SettingActivity.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Activity/SettingActivity.java
@@ -118,13 +118,18 @@ public class SettingActivity extends AppCompatActivity {
private void initView() {
allView = new AllView(this);
- // 只预加载默认的 MotorFragment
+ // 预加载默认的 FoundationFragment 和 SettingsFragment
androidx.fragment.app.FragmentManager fragmentManager = getSupportFragmentManager();
androidx.fragment.app.FragmentTransaction transaction = fragmentManager.beginTransaction();
foundationFragment = new FoundationFragment();
transaction.add(R.id.fragment_container, foundationFragment, "FoundationFragment");
+
+ settingsFragment = new SettingsFragment(); // 同时预加载 SettingsFragment
+ transaction.add(R.id.fragment_container, settingsFragment, "SettingsFragment");
+
transaction.commit();
+
}
/**
@@ -153,10 +158,10 @@ public class SettingActivity extends AppCompatActivity {
private void selectItem(int index) {
for (int i = 0; i < allView.views.size(); i++) {
if (index == i) {
- allView.views.get(i).setBackgroundResource(R.drawable.ff029a45_2round_1stroke_bg);
+ allView.views.get(i).setBackgroundResource(R.drawable.ff029a45_4round_1stroke_bg);
allView.views.get(i).setTextColor(Color.parseColor("#ffffff"));
} else {
- allView.views.get(i).setBackgroundResource(R.drawable.b2303030_4round_1stroke_bg);
+ allView.views.get(i).setBackgroundResource(R.drawable.ffffffff_4round_bg);
allView.views.get(i).setTextColor(Color.parseColor("#303030"));
}
}
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Adapter/MultiSelectAdapter.java b/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Adapter/MultiSelectAdapter.java
index 49be845..8ec08ed 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Adapter/MultiSelectAdapter.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Adapter/MultiSelectAdapter.java
@@ -40,7 +40,7 @@ public class MultiSelectAdapter extends RecyclerView.Adapter {
if (position < paramList.size()) { // 再次检查索引有效性
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Adapter/ParamGroupAdapter.java b/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Adapter/ParamGroupAdapter.java
index 2e3b052..27ce8ce 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Adapter/ParamGroupAdapter.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Adapter/ParamGroupAdapter.java
@@ -9,7 +9,6 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
-import com.example.longyi_groundstation.Main.Setting.Base.Param;
import com.example.longyi_groundstation.Main.Setting.Base.ParamGroup;
import com.example.longyi_groundstation.R;
@@ -46,9 +45,9 @@ public class ParamGroupAdapter extends RecyclerView.Adapter {
setSelect(position);
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/ControlFragment.java b/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/ControlFragment.java
index 0ef10d1..41181a9 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/ControlFragment.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/ControlFragment.java
@@ -81,7 +81,7 @@ public class ControlFragment extends Fragment {
adapter = new ParamGridAdapter(paramItems);
updata();
- // 设置GridLayoutManager,每行显示2个item
+ // 设置GridLayoutManager,每行显示3个item
rv_data.setLayoutManager(new GridLayoutManager(getContext(), 3));
rv_data.setAdapter(adapter);
}
@@ -104,10 +104,10 @@ public class ControlFragment extends Fragment {
//广播接收-RcChannelsRawlistener
mBroadcast_RC_CHANNELS.setRcChannelsRawlistener(data -> {
- Log.d("cuijingzhou_ctrl", data.toString());
+// Log.d("cuijingzhou_ctrl", data.toString());
try {
JSONObject jsonObject = new JSONObject(data.toString());
- for (int i = 0; i < 12; i++){
+ for (int i = 0; i < 14; i++){
paramItems.get(i).setCurrentValue(jsonObject.optString("chan" + (i + 1) + "_raw"));
}
}catch (Exception e){
@@ -236,6 +236,21 @@ public class ControlFragment extends Fragment {
FlyVoid.paramList.get("RC12_TRIM").getParam_value(),
"待定",
"待定"));
+ // 添加数据
+ paramItems.add(new ParamGridAdapter.ParamItem(
+ "通道13",
+ FlyVoid.paramList.get("RC13_MAX").getParam_value(),
+ FlyVoid.paramList.get("RC13_MIN").getParam_value(),
+ FlyVoid.paramList.get("RC13_TRIM").getParam_value(),
+ "待定",
+ "待定"));
+ paramItems.add(new ParamGridAdapter.ParamItem(
+ "通道14",
+ FlyVoid.paramList.get("RC14_MAX").getParam_value(),
+ FlyVoid.paramList.get("RC14_MIN").getParam_value(),
+ FlyVoid.paramList.get("RC14_TRIM").getParam_value(),
+ "待定",
+ "待定"));
}
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/FlyFragment.java b/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/FlyFragment.java
index 04ad716..211e7c5 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/FlyFragment.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/FlyFragment.java
@@ -50,6 +50,7 @@ public class FlyFragment extends Fragment {
if (FlyVoid.isParamUpdateComplete()){
initData();
initView(view);
+ getData();
initOnClick();
}
return view;
@@ -201,7 +202,7 @@ public class FlyFragment extends Fragment {
int progress = seekBar_horizontal_angle.getProgress();
if (progress > 1000) {
seekBar_horizontal_angle.setProgress(progress - 100);
- tv_horizontal_angle.setText(seekBar_horizontal_angle.getProgress() + "cdeg");
+ tv_horizontal_angle.setText((seekBar_horizontal_angle.getProgress() / 100) + "度");
}
});
@@ -209,14 +210,14 @@ public class FlyFragment extends Fragment {
int progress = seekBar_horizontal_angle.getProgress();
if (progress < seekBar_horizontal_angle.getMax()) {
seekBar_horizontal_angle.setProgress(progress + 100);
- tv_horizontal_angle.setText(seekBar_horizontal_angle.getProgress() + "cdeg");
+ tv_horizontal_angle.setText(((seekBar_horizontal_angle.getProgress() / 100)) + "度");
}
});
seekBar_horizontal_angle.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- tv_horizontal_angle.setText(progress + "度");
+ tv_horizontal_angle.setText((progress / 100) + "度");
}
@Override
@@ -271,13 +272,11 @@ public class FlyFragment extends Fragment {
seekBar_decline_speed.setProgress(0);
tv_decline_speed.setText(seekBar_decline_speed.getProgress() + "m/s");
seekBar_horizontal_angle.setProgress(3000);
- tv_horizontal_angle.setText(seekBar_horizontal_angle.getProgress() + "cdeg");
+ tv_horizontal_angle.setText((seekBar_horizontal_angle.getProgress()/100) + "度");
seekBar_rotation_rate.setProgress(2025);
tv_rotation_rate.setText(((double)seekBar_rotation_rate.getProgress()/10) + "度/s");
Toast.makeText(getActivity(), "初始化完成", Toast.LENGTH_SHORT).show();
});
-
-
}
/**
@@ -293,7 +292,7 @@ public class FlyFragment extends Fragment {
seekBar_decline_speed.setProgress(Integer.parseInt(FlyVoid.paramList.get("PILOT_SPEED_DN").getParam_value()));
tv_decline_speed.setText(seekBar_decline_speed.getProgress() + "m/s");
seekBar_horizontal_angle.setProgress(Integer.parseInt(FlyVoid.paramList.get("ANGLE_MAX").getParam_value()));
- tv_horizontal_angle.setText(seekBar_horizontal_angle.getProgress() + "cdeg");
+ tv_horizontal_angle.setText((seekBar_horizontal_angle.getProgress()/100) + "度");
//旋转速率单独运算一下
float rotation_rate = Float.parseFloat(FlyVoid.paramList.get("PILOT_Y_RATE").getParam_value())*10;
seekBar_rotation_rate.setProgress((int) rotation_rate);
@@ -316,6 +315,6 @@ public class FlyFragment extends Fragment {
@Override
public void onStart() {
super.onStart();
- getData();
+
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/FoundationFragment.java b/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/FoundationFragment.java
index 4dc81e7..8a2a81c 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/FoundationFragment.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/FoundationFragment.java
@@ -35,7 +35,7 @@ public class FoundationFragment extends Fragment {
private RelativeLayout rl_low_end,rl_mid_range,rl_high_end;
private Spinner sp_low_end,sp_mid_range,sp_high_end;
private TextView tv_low_end_text,tv_mid_range_text,tv_high_end_text,tv_save;
-
+ private TextView et_speed_text;
private FlyVoid flyVoid = new FlyVoid();
@Override
@@ -75,6 +75,7 @@ public class FoundationFragment extends Fragment {
tv_low_end_text = view.findViewById(R.id.tv_low_end_text);
tv_mid_range_text = view.findViewById(R.id.tv_mid_range_text);
tv_high_end_text = view.findViewById(R.id.tv_high_end_text);
+ et_speed_text = view.findViewById(R.id.et_speed_text);
tv_save = view.findViewById(R.id.tv_save);
initSpinnerData();
initText();
@@ -183,6 +184,12 @@ public class FoundationFragment extends Fragment {
FlyVoid.paramList.get("FLTMODE5").getParam_type());
flyVoid.requestParamSet("FLTMODE6",
getSelectedChannelValue(sp_high_end) + "");
+ Thread.sleep(100);
+
+ flyVoid.requestParamSet("WPNAV_SPEED",
+ et_speed_text.getText().toString(),
+ FlyVoid.paramList.get("WPNAV_SPEED").getParam_type());
+ Thread.sleep(100);
Toast.makeText(requireContext(), "保存成功", Toast.LENGTH_SHORT).show();
}catch (Exception e){
@@ -199,6 +206,7 @@ public class FoundationFragment extends Fragment {
setSelectedChannel(sp_low_end, Integer.parseInt(FlyVoid.paramList.get("FLTMODE1").getParam_value()));
setSelectedChannel(sp_mid_range, Integer.parseInt(FlyVoid.paramList.get("FLTMODE3").getParam_value()));
setSelectedChannel(sp_high_end, Integer.parseInt(FlyVoid.paramList.get("FLTMODE5").getParam_value()));
+ et_speed_text.setText(FlyVoid.paramList.get("WPNAV_SPEED").getParam_value());
}
/**
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/LoadFragment.java b/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/LoadFragment.java
index 4fd66b7..5b83bb6 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/LoadFragment.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/LoadFragment.java
@@ -216,8 +216,6 @@ public class LoadFragment extends Fragment {
// 给flyTextViews里面所有的view添加点击事件:点击后会打开对应的Spinner
initFlyTextViewClickListeners();
-
-
}
/**
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/MotorFragment.java b/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/MotorFragment.java
index f250809..c3c5883 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/MotorFragment.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/MotorFragment.java
@@ -66,9 +66,9 @@ public class MotorFragment extends Fragment {
for (int i = 1; i <= 12; i++) {
if (i <= 6) {
- list.add(new Motor("电机" + i, i, true));
+ list.add(new Motor("" + i, i, true));
} else {
- list.add(new Motor("电机" + i, i, false));
+ list.add(new Motor("" + i, i, false));
}
}
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/SettingsFragment.java b/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/SettingsFragment.java
index a669cc8..537bd19 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/SettingsFragment.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/Setting/Fragment/SettingsFragment.java
@@ -43,6 +43,7 @@ import com.example.longyi_groundstation.R;
import com.google.gson.Gson;
import java.util.ArrayList;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
@@ -428,6 +429,8 @@ public class SettingsFragment extends Fragment {
// 将 Map 中的值转换为 List 并添加到 paramGroupsList
paramGroupsList.addAll(groupMap.values());
+ // 添加这行代码来执行排序
+ sortParamGroupsByName();
// 通知适配器刷新数据
if (!paramGroupsList.isEmpty()) {
@@ -460,6 +463,22 @@ public class SettingsFragment extends Fragment {
});
}
+ /**
+ * 方法:按照参数组名称字母顺序排序
+ *
+ * @cuijingzhou
+ */
+ private void sortParamGroupsByName() {
+ if (paramGroupsList != null && !paramGroupsList.isEmpty()) {
+ paramGroupsList.sort((group1, group2) -> {
+ if (group1 == null || group2 == null) return 0;
+ if (group1.getParam_name() == null || group2.getParam_name() == null) return 0;
+ return group1.getParam_name().compareToIgnoreCase(group2.getParam_name());
+ });
+ }
+ }
+
+
@Override
public void onResume() {
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/View/BombingDialog.java b/app/src/main/java/com/example/longyi_groundstation/Main/View/BombingDialog.java
index cda9ef1..def6e10 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Main/View/BombingDialog.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/View/BombingDialog.java
@@ -85,18 +85,24 @@ public class BombingDialog {
window.setBackgroundDrawableResource(R.drawable.ffffffff_4round_bg);
}
- unlockView.setText("滑动执行");
+ unlockView.setText("滑动确认");
unlockView.setOnUnlockListener(new SlideToUnlockView.OnUnlockListener() {
@Override
public void onUnlock() {
// 发送命令
// flyVoid.sendMavlinkMessage(MyBoundService.type,command);
- flyVoid.requestBombing(et_height.getText().toString());
+ if (et_height.getText().toString().length() > 0){
+ flyVoid.requestBombing(et_height.getText().toString());
+ // 滑动到阈值后触发(如关闭对话框或执行操作)
+ Toast.makeText(context, "操作已确认", Toast.LENGTH_SHORT).show();
+ }else {
+ unlockView.resetProgress();
+ Toast.makeText(context, "请输入高度", Toast.LENGTH_SHORT).show();
+ }
dialog.dismiss();
- // 滑动到阈值后触发(如关闭对话框或执行操作)
- Toast.makeText(context, "操作已确认", Toast.LENGTH_SHORT).show();
MyTool.hideBottomNavigationBar(context);
+
}
});
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/View/PointFlyDialog.java b/app/src/main/java/com/example/longyi_groundstation/Main/View/PointFlyDialog.java
index 57e9097..011d6cf 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Main/View/PointFlyDialog.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/View/PointFlyDialog.java
@@ -8,6 +8,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
+import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
@@ -19,9 +20,8 @@ import com.example.longyi_groundstation.R;
public class PointFlyDialog {
private final Activity context;
- private String title;
- private String message;
- private String positiveButtonText;
+ private String speed;
+ private String height;
private LatLng latLng;
private FlyVoid flyVoid = new FlyVoid();
@@ -29,10 +29,9 @@ public class PointFlyDialog {
public PointFlyDialog(Activity context) {
this.context = context;
- this.title = "错误日志";
- this.message = "";
- this.positiveButtonText = "确定";
- this.latLng = latLng;
+ this.speed = "3";
+ this.height = "30";
+ this.latLng = null;
}
@@ -43,22 +42,18 @@ public class PointFlyDialog {
}
// 设置弹窗标题
- public PointFlyDialog setTitle(String title) {
- this.title = title;
+ public PointFlyDialog setSpeed(String speed) {
+ this.speed = speed;
return this;
}
// 设置弹窗内容
- public PointFlyDialog setMessage(String message) {
- this.message = message;
+ public PointFlyDialog setHeight(String height) {
+ this.height = height;
return this;
}
- // 设置确认按钮文字
- public PointFlyDialog setPositiveButtonText(String text) {
- this.positiveButtonText = text;
- return this;
- }
+
// 显示弹窗
public void show() {
@@ -70,9 +65,22 @@ public class PointFlyDialog {
@SuppressLint({"MissingInflatedId", "LocalSuppress"}) TextView tvMessage = view.findViewById(R.id.tv_message);
// 滑动模块
@SuppressLint({"MissingInflatedId", "LocalSuppress"}) SlideToUnlockView unlockView = view.findViewById(R.id.unlockView);
+ //经度
+ @SuppressLint({"MissingInflatedId", "LocalSuppress"}) EditText et_lon = view.findViewById(R.id.et_lon);
+ //纬度
+ @SuppressLint({"MissingInflatedId", "LocalSuppress"}) EditText et_lat = view.findViewById(R.id.et_lat);
+ //高度
+ @SuppressLint({"MissingInflatedId", "LocalSuppress"}) EditText et_height = view.findViewById(R.id.et_height);
+ //速度
+ @SuppressLint({"MissingInflatedId", "LocalSuppress"}) EditText et_speed = view.findViewById(R.id.et_speed);
+
+
if (latLng != null){
- tvMessage.setText("经度:" + latLng.latitude + "\n纬度:" + latLng.latitude);
+ et_lon.setText(String.valueOf(latLng.longitude));
+ et_lat.setText(String.valueOf(latLng.latitude));
+ et_height.setText(height);
+ et_speed.setText(speed);
}
// 添加日志
@@ -95,8 +103,28 @@ public class PointFlyDialog {
unlockView.setOnUnlockListener(new SlideToUnlockView.OnUnlockListener() {
@Override
public void onUnlock() {
-// // 发送命令
+ if (et_lat.getText().toString().isEmpty() || et_lon.getText().toString().isEmpty()){
+ Toast.makeText(context, "请填写经纬度", Toast.LENGTH_SHORT).show();
+ return;
+ }
+ if (et_height.getText().toString().isEmpty()){
+ Toast.makeText(context, "请填写高度", Toast.LENGTH_SHORT).show();
+ return;
+ }
+ if (Integer.parseInt(et_height.getText().toString()) < 5){
+ Toast.makeText(context, "高度过低", Toast.LENGTH_SHORT).show();
+ return;
+ }
+// // 发送命令
+ flyVoid.adviseFly(
+ context,
+ new LatLng(
+ Double.parseDouble(et_lat.getText().toString()),
+ Double.parseDouble(et_lon.getText().toString()))
+ ,
+ Double.parseDouble(et_height.getText().toString()),
+ Double.parseDouble(et_speed.getText().toString()));
MyTool.hideBottomNavigationBar( context);
dialog.dismiss();
// 滑动到阈值后触发(如关闭对话框或执行操作)
@@ -108,7 +136,6 @@ public class PointFlyDialog {
tvMessage.setOnClickListener(v -> {
dialog.dismiss();
MyTool.hideBottomNavigationBar(context);
-
});
}
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/View/SaveLinkNameDialog.java b/app/src/main/java/com/example/longyi_groundstation/Main/View/SaveLinkNameDialog.java
index 6d918bf..e793b2e 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Main/View/SaveLinkNameDialog.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/View/SaveLinkNameDialog.java
@@ -92,9 +92,6 @@ public class SaveLinkNameDialog {
}else {
context.saveLink(null);
}
-
-
- MyTool.hideBottomNavigationBar( context);
dialog.dismiss();
// 滑动到阈值后触发(如关闭对话框或执行操作)
Toast.makeText(context, "操作已确认", Toast.LENGTH_SHORT).show();
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/Void/AllView.java b/app/src/main/java/com/example/longyi_groundstation/Main/Void/AllView.java
index dea08f1..a714e4c 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Main/Void/AllView.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/Void/AllView.java
@@ -94,14 +94,19 @@ public class AllView {
public ImageView iv_open_link_list;
public LinearLayout ll_clear_fly_line;
public LinearLayout ll_create_link_item_layout;
-
-
+ public ImageView iv_marker_top;
+ public ImageView iv_marker_left;
+ public ImageView iv_marker_right;
+ public ImageView iv_marker_bottom;
+ public LinearLayout ll_marker_ctrl;
+ public EditText et_marker_distance;
// public SlideToUnlockView unlockView;
// public RelativeLayout rl_unlock;
public EditText et_start_execute_height;
+
public AllView(Activity activity) {
this.activity = activity;
init();
@@ -182,6 +187,11 @@ public class AllView {
ll_clear_fly_line = activity.findViewById(R.id.ll_clear_fly_line);
ll_create_link_item_layout = activity.findViewById(R.id.ll_create_link_item_layout);
iv_open_link_list = activity.findViewById(R.id.iv_open_link_list);
-
+ iv_marker_top = activity.findViewById(R.id.iv_marker_top);
+ iv_marker_left = activity.findViewById(R.id.iv_marker_left);
+ iv_marker_right = activity.findViewById(R.id.iv_marker_right);
+ iv_marker_bottom = activity.findViewById(R.id.iv_marker_bottom);
+ ll_marker_ctrl = activity.findViewById(R.id.ll_marker_ctrl);
+ et_marker_distance = activity.findViewById(R.id.et_marker_distance);
}
}
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/Void/FlyVoid.java b/app/src/main/java/com/example/longyi_groundstation/Main/Void/FlyVoid.java
index 4a873ac..c3ae162 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Main/Void/FlyVoid.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/Void/FlyVoid.java
@@ -34,6 +34,7 @@ import com.example.longyi_groundstation.MAVLink.common.msg_mission_request_int;
import com.example.longyi_groundstation.MAVLink.common.msg_mission_request_list;
import com.example.longyi_groundstation.MAVLink.common.msg_param_request_read;
import com.example.longyi_groundstation.MAVLink.common.msg_param_set;
+import com.example.longyi_groundstation.MAVLink.common.msg_set_position_target_global_int;
import com.example.longyi_groundstation.MAVLink.enums.MAV_CMD;
import com.example.longyi_groundstation.MAVLink.enums.MAV_COMPONENT;
import com.example.longyi_groundstation.MAVLink.enums.MAV_FRAME;
@@ -365,113 +366,9 @@ public class FlyVoid {
* @param createLinkList 航线航点列表
* @cuijingzhou
*/
- public void sendMissionToFlightController(Activity context, ArrayList createLinkList, String height) {
- if (createLinkList == null || createLinkList.isEmpty()) {
- return;
- }
- if (height == null){
- height = "10";
- }
-
- // 创建 ProgressDialog
- android.app.ProgressDialog progressDialog = new android.app.ProgressDialog(context);
- progressDialog.setTitle("任务上传中");
- progressDialog.setMessage("正在发送航线到飞控...");
- progressDialog.setProgressStyle(android.app.ProgressDialog.STYLE_HORIZONTAL);
- progressDialog.setCancelable(false); // 设置不可手动关闭
- progressDialog.setMax(100);
- progressDialog.show();
- MsgList.set(MAVLINK_MSG_ID_MISSION_REQUEST,null);
- String finalHeight = height;
- new Thread(() -> {
- try {
- // 2. 发送航点计数
- msg_mission_count count = new msg_mission_count();
- count.target_system = 1;
- count.target_component = 1;
- count.count = createLinkList.size() + 2; // 航点数量
- sendMavlinkMessage(type, count);
-
- Log.d("Missions-count", "--" + ( createLinkList.size() + 2));
-
-// 在FlyVoid.java的sendMissionToFlightController方法中,找到以下代码块并修改:
-
- boolean isOk = true;
- int sentWaypoints = 0;
- int totalWaypoints = createLinkList.size() + 2;
- int lastSeq = -1; // 添加这一行来记录上一次的seq值
-
- while (isOk) {
- try {
- String msgRequest = MsgList.get(MAVLINK_MSG_ID_MISSION_REQUEST);
- if (msgRequest != null) {
- JSONObject jsonObject = new JSONObject(msgRequest);
- int seq = jsonObject.optInt("seq");
-
- // 添加判断:如果seq值没有改变,跳过本次循环
- if (seq == lastSeq) {
- Thread.sleep(100); // 短暂休眠避免过度占用CPU
- continue; // 跳过本次循环
- }
-
- upDataLinkPoint(seq, createLinkList, finalHeight);
- lastSeq = seq; // 更新lastSeq值
- sentWaypoints = seq + 1;
-
- // 更新发送进度
- final int progress = (int) ((sentWaypoints / (float) totalWaypoints) * 92); // 发送占50%进度
- context.runOnUiThread(() -> {
- progressDialog.setProgress(progress);
- });
-
- // 如果当前序号+1大于等于航点总数,则结束循环
- if ((seq + 1) >= createLinkList.size()+2) {
- isOk = false;
- }
- }
-
- // 添加短暂延迟以避免过度占用CPU
- Thread.sleep(100);
- } catch (Exception e) {
- Log.e("Mission", "Error processing mission request: " + e.getMessage());
- // 出错时也退出循环避免无限循环
- isOk = false;
- }
- }
- context.runOnUiThread(() -> {
- progressDialog.setMessage("正在校验航线...");
- });
- Log.d("Missions", "verifyResult");
-
- // 校验点位是否正常上传
- boolean verifyResult = verifyPoint(createLinkList);
-
- // 更新校验进度
- context.runOnUiThread(() -> {
- progressDialog.setProgress(100);
- progressDialog.dismiss();
-
- if (verifyResult) {
- Toast.makeText(context, "航线上传成功", Toast.LENGTH_SHORT).show();
- } else {
- Toast.makeText(context, "航线发送完成但校验失败", Toast.LENGTH_SHORT).show();
- }
-
- });
-
- } catch (Exception e) {
- context.runOnUiThread(() -> {
- progressDialog.dismiss();
- Toast.makeText(context, "航线发送过程中出现错误", Toast.LENGTH_SHORT).show();
- });
- e.printStackTrace();
- }
-
- }).start();
- }
/**
@@ -479,8 +376,94 @@ public class FlyVoid {
*
* @cuijingzhou
* */
- private void creatDataList (ArrayList createLinkList, String height) {
- ArrayList dataList = new ArrayList<>();
+ public static ArrayList createLinkListToFlyList = null;//当前飞行计划
+ public void creatDataList (Activity context,ArrayList createLinkList, String height) {
+ try {
+
+ //转换一下
+ ArrayList list1 = createLinkListToFlyList(createLinkList);
+ Log.d("sss", "creatDataList: ");
+ if (createLinkList == null || createLinkList.isEmpty()) {
+ return;
+ }
+ if (height == null){
+ height = "10";
+ }
+
+// // 创建 ProgressDialog
+// android.app.ProgressDialog progressDialog = new android.app.ProgressDialog(context);
+// progressDialog.setTitle("任务上传中");
+// progressDialog.setMessage("正在发送航线到飞控...");
+// progressDialog.setProgressStyle(android.app.ProgressDialog.STYLE_HORIZONTAL);
+// progressDialog.setCancelable(false); // 设置不可手动关闭
+// progressDialog.setMax(100);
+// progressDialog.show();
+
+ MsgList.set(MAVLINK_MSG_ID_MISSION_REQUEST,null);
+ String finalHeight = height;
+ new Thread(() -> {
+ try {
+ // 2. 发送航点计数
+ msg_mission_count count = new msg_mission_count();
+ count.target_system = 1;
+ count.target_component = 1;
+ count.count = list1.size(); // 航点数量
+ sendMavlinkMessage(type, count);
+
+ Log.d("Missions-count", "--" + ( list1.size()));
+
+ boolean isOk = true;
+ int lastSeq = -1; // 添加这一行来记录上一次的seq值
+
+ while (isOk) {
+ try {
+ String msgRequest = MsgList.get(MAVLINK_MSG_ID_MISSION_REQUEST);
+ if (msgRequest != null) {
+ JSONObject jsonObject = new JSONObject(msgRequest);
+ int seq = jsonObject.optInt("seq");
+
+ // 添加判断:如果seq值没有改变,跳过本次循环
+ if (seq <= lastSeq) {
+ Thread.sleep(100); // 短暂休眠避免过度占用CPU
+ continue; // 跳过本次循环
+ }
+ lastSeq = seq; // 更新lastSeq值
+ // 发送消息请求航点列表
+ sendMavlinkMessage(type, list1.get( lastSeq));
+ // 如果当前序号+1大于等于航点总数,则结束循环
+ if ((lastSeq + 1) >= list1.size()) {
+ Log.d("cjz_航线上传", "上传成功");
+ context.runOnUiThread(() -> {
+ Toast.makeText(context, "上传成功", Toast.LENGTH_SHORT).show();
+ });
+ isOk = false;
+ }
+ }
+
+ // 添加短暂延迟以避免过度占用CPU
+ Thread.sleep(100);
+ } catch (Exception e) {
+ Log.e("Mission", "Error processing mission request: " + e.getMessage());
+ // 出错时也退出循环避免无限循环
+ isOk = false;
+ }
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }).start();
+
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ Log.d("问题1", "creatDataList: "+e);
+ }
+ }
+
+ public ArrayList createLinkListToFlyList(ArrayList createLinkList){
+ ArrayList list1 = new ArrayList<>();
//home点,默认第一个为home点
msg_mission_item_int waypoint = new msg_mission_item_int();
waypoint.target_system = 1; // 无人机系统ID
@@ -497,7 +480,8 @@ public class FlyVoid {
waypoint.x = 0;
waypoint.y = 0;
waypoint.z = 0; // 高度(相对)
- dataList.add(waypoint);
+ list1.add(waypoint);
+
//起飞,将飞机拉起来
msg_mission_item_int waypoint1 = new msg_mission_item_int();
waypoint1.target_system = 1; // 无人机系统ID
@@ -513,103 +497,137 @@ public class FlyVoid {
waypoint1.param4 = 0; // 航向角
waypoint1.x = 0;
waypoint1.y = 0;
- waypoint1.z = Float.parseFloat(height); // 高度(相对)
+ waypoint1.z = Float.parseFloat("10"); // 高度(相对)
waypoint1.mission_type = MAV_MISSION_TYPE.MAV_MISSION_TYPE_MISSION;
+ list1.add(waypoint1);
-// //添加航点
-// for (int i = 0; i < createLinkList.size(); i++) {
-// if (){
-//
-// }
-// }
+ for (int i = 0; i < createLinkList.size(); i++) {
+ CreateLink link = createLinkList.get(i);
+ // 在特定航点前添加速度变化指令
+ msg_mission_item_int speedChange = new msg_mission_item_int();
+ speedChange.target_system = 1;
+ speedChange.target_component = 1;
+ speedChange.seq = list1.size(); // 序号
+ speedChange.frame = MAV_FRAME.MAV_FRAME_GLOBAL_RELATIVE_ALT;
+ speedChange.command = MAV_CMD.MAV_CMD_DO_CHANGE_SPEED;
+ speedChange.current = 0;
+ speedChange.autocontinue = 1;
+ speedChange.param1 = 1; // 地速
+ speedChange.param2 = (float) link.getSpeed(); // 使用CreateLink中的速度值
+ speedChange.param3 = 0; // 不限制推力
+ speedChange.param4 = 0; // 绝对速度
+ speedChange.x = 0;
+ speedChange.y = 0;
+ speedChange.z = Float.parseFloat("10");
+ list1.add(speedChange);
+ //第一个点特殊处理
+ if ( i-1 == -1){
+ msg_mission_item_int command = new msg_mission_item_int();
+ command.target_system = 1;
+ command.target_component = 1;
+ command.seq = list1.size(); // 序号
+ command.frame = MAV_FRAME.MAV_FRAME_GLOBAL_RELATIVE_ALT;
+ command.command = MAV_CMD.MAV_CMD_CONDITION_YAW;
+// 设置偏航参数
+ command.param1 = getYaw(
+ MainActivity.homeLatLng.latitude,
+ MainActivity.homeLatLng.longitude,
+ link.getLatLng().latitude,
+ link.getLatLng().longitude); // 目标偏航角度
+ command.param2 = 0; // 偏航角变化速率
+ command.param3 = 0; // 方向(-1=逆时针,1=顺时针)
+ command.param4 = 0; // 相对或绝对偏航(0=绝对,1=相对)
+ list1.add(command);
+ }
- }
+ if (link.getStop_time() > 0 && i <= createLinkList.size()-1 && i-1 != -1){
+ msg_mission_item_int command = new msg_mission_item_int();
+ command.target_system = 1;
+ command.target_component = 1;
+ command.seq = list1.size(); // 序号
+ command.frame = MAV_FRAME.MAV_FRAME_GLOBAL_RELATIVE_ALT;
+ command.command = MAV_CMD.MAV_CMD_CONDITION_YAW;
+// 设置偏航参数
+ command.param1 = getYaw(
+ createLinkList.get(i-1).getLatLng().latitude,
+ createLinkList.get(i-1).getLatLng().longitude,
+ link.getLatLng().latitude,
+ link.getLatLng().longitude); // 目标偏航角度
+ command.param2 = 0; // 偏航角变化速率
+ command.param3 = 0; // 方向(-1=逆时针,1=顺时针)
+ command.param4 = 0; // 相对或绝对偏航(0=绝对,1=相对)
+ list1.add(command);
+ }
-
-
- /**
- * 方法:给飞控发送点位
- *
- * @cuijingzhou
- */
- private void upDataLinkPoint(int i,ArrayList createLinkList,String height) throws InterruptedException {
-// Log.d("Missions", "--" + i);
-// Log.d("Missions", "myReceiver_MISSION_ACK: ");
- //由于第一个点是home点,所以要从第2个点开始上传
- if (i == 0){
-
- msg_mission_item_int waypoint = new msg_mission_item_int();
- waypoint.target_system = 1; // 无人机系统ID
- waypoint.target_component = 1; // 无人机组件ID
- waypoint.seq = 0; // 航点序号
- waypoint.frame = MAV_FRAME.MAV_FRAME_GLOBAL_RELATIVE_ALT; // 坐标系
- waypoint.command = MAV_CMD.MAV_CMD_NAV_WAYPOINT; // 航点指令
- waypoint.current = 1 ; // 第一个航点设为当前航点
- waypoint.autocontinue = 1; // 自动继续到下一个航点
- waypoint.param1 = 0; // 停留时间(秒)
- waypoint.param2 = 0; // 接受半径(m)
- waypoint.param3 = 0; // 通过半径(m)
- waypoint.param4 = 0; // 航向角
- waypoint.x = 0;
- waypoint.y = 0;
- waypoint.z = 0; // 高度(相对)
- sendMavlinkMessage(type, waypoint);
- Log.d("Missions", i+"--"+ waypoint.toString());
- Thread.sleep(100);
- } else if (i == 1) {
- msg_mission_item_int waypoint1 = new msg_mission_item_int();
- waypoint1.target_system = 1; // 无人机系统ID
- waypoint1.target_component = 1; // 无人机组件ID
- waypoint1.seq = i; // 航点序号
- waypoint1.frame = MAV_FRAME.MAV_FRAME_GLOBAL_RELATIVE_ALT; // 坐标系
- waypoint1.command = MAV_CMD.MAV_CMD_NAV_TAKEOFF; // 航点指令
- waypoint1.current = 0; // 第一个航点设为当前航点
- waypoint1.autocontinue = 1; // 自动继续到下一个航点
- waypoint1.param1 = 0; // 停留时间(秒)
- waypoint1.param2 = 0; // 接受半径(m)
- waypoint1.param3 = 0; // 通过半径(m)
- waypoint1.param4 = 0; // 航向角
- waypoint1.x = 0;
- waypoint1.y = 0;
- waypoint1.z = Float.parseFloat(height); // 高度(相对)
- waypoint1.mission_type = MAV_MISSION_TYPE.MAV_MISSION_TYPE_MISSION;
- sendMavlinkMessage(type, waypoint1);
- Log.d("Missions", i+"--"+ waypoint1.toString());
- Thread.sleep(100);
- }
- //正常上传
- else {
- CreateLink link = createLinkList.get(i-2);
LatLng latLng = link.getLatLng();
double[] doubles = CoordinateConverter.gcj02ToWgs84(latLng.longitude, latLng.latitude);
- if (doubles != null) {
- msg_mission_item_int waypoint = new msg_mission_item_int();
- waypoint.target_system = 1; // 无人机系统ID
- waypoint.target_component = 1; // 无人机组件ID
- waypoint.seq = i; // 航点序号
- waypoint.frame = MAV_FRAME.MAV_FRAME_GLOBAL_RELATIVE_ALT; // 坐标系
- waypoint.command = MAV_CMD.MAV_CMD_NAV_WAYPOINT; // 航点指令
- waypoint.current = 0; // 第一个航点设为当前航点
- waypoint.autocontinue = 1; // 自动继续到下一个航点
- waypoint.param1 = 0; // 停留时间(秒)
- waypoint.param2 = 0; // 接受半径(m)
- waypoint.param3 = 0; // 通过半径(m)
- waypoint.param4 = 0; // 航向角
- waypoint.x = (int) (doubles[1] * 10000000);
- waypoint.y = (int) (doubles[0] * 10000000);
- // 经度
- waypoint.z = (float) link.getHeight(); // 高度(相对)
- sendMavlinkMessage(type, waypoint);
- Log.d("Missions", i+"--"+ waypoint.toString());
- Thread.sleep(100);
- }
+ //点位,其中包含停留时间
+ msg_mission_item_int waypointss = new msg_mission_item_int();
+ waypointss.target_system = 1; // 无人机系统ID
+ waypointss.target_component = 1; // 无人机组件ID
+ waypointss.seq = list1.size(); // 航点序号
+ waypointss.frame = MAV_FRAME.MAV_FRAME_GLOBAL_RELATIVE_ALT; // 坐标系
+ waypointss.command = MAV_CMD.MAV_CMD_NAV_WAYPOINT; // 航点指令
+ waypointss.current = 0; // 第一个航点设为当前航点
+ waypointss.autocontinue = 1; // 自动继续到下一个航点
+ waypointss.param1 = link.getStop_time(); // 停留时间(秒)
+ waypointss.param2 = 0; // 接受半径(m)
+ waypointss.param3 = 0; // 通过半径(m)
+ waypointss.param4 = 0; // 航向角
+ waypointss.x = (int) (doubles[1] * 10000000);
+ waypointss.y = (int) (doubles[0] * 10000000);
+ // 经度
+ waypointss.z = (float) link.getHeight(); // 高度(相对)
+ waypointss.mission_type = MAV_MISSION_TYPE.MAV_MISSION_TYPE_MISSION;
+ list1.add(waypointss);
+
+
}
-
-
+ return list1;
}
+ /**
+ * 方法:计算从当前点到下一个点的方位角(Yaw)
+ * 以正北为0度,顺时针方向为正
+ *
+ * @param currentLat 当前点纬度
+ * @param currentLon 当前点经度
+ * @param nextLat 下一个点纬度
+ * @param nextLon 下一个点经度
+ * @return 方位角(0-360度,正北为0度)
+ */
+ public static float getYaw(double currentLat, double currentLon, double nextLat, double nextLon) {
+ // 将角度转换为弧度
+ double lat1 = Math.toRadians(currentLat);
+ double lon1 = Math.toRadians(currentLon);
+ double lat2 = Math.toRadians(nextLat);
+ double lon2 = Math.toRadians(nextLon);
+
+ // 计算经度差
+ double dLon = lon2 - lon1;
+
+ // 使用球面三角法计算方位角
+ double y = Math.sin(dLon) * Math.cos(lat2);
+ double x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
+ double bearing = Math.atan2(y, x);
+
+ // 将结果从弧度转换为度
+ bearing = Math.toDegrees(bearing);
+
+ // 规范化到0-360度范围
+ bearing = (bearing + 360) % 360;
+
+ return (int) bearing;
+ }
+
+
+
+
+
+
+
/**
* 方法:校验发送的点位是否正确
*
@@ -790,6 +808,73 @@ public class FlyVoid {
}
+ /**
+ * 方法:指点飞行
+ *
+ * @cuijingzhou
+ */
+ public void adviseFly(Activity context, LatLng latLng, double height, double speed) {
+ // 先切换到GUIDED模式
+ setFlightMode(4);
+ // 延时一段时间确保模式切换完成
+ new Thread(() -> {
+ try {
+ Thread.sleep(1000);
+ // 使用 SET_POSITION_TARGET_GLOBAL_INT 消息发送目标位置
+ adviseFlyWithGlobalPosition(latLng, height, speed);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }).start();
+ }
+
+
+ /**
+ * 方法:使用 SET_POSITION_TARGET_GLOBAL_INT 消息进行指点飞行
+ *
+ * @param latLng 目标位置坐标
+ * @param altitude 目标高度
+ * @param speed 目标速度
+ */
+ public void adviseFlyWithGlobalPosition(LatLng latLng, double altitude, double speed) {
+ try {
+ // 转换坐标系 (GCJ02转WGS84)
+ double[] wgs84Coords = CoordinateConverter.gcj02ToWgs84(latLng.longitude, latLng.latitude);
+
+ // 创建 SET_POSITION_TARGET_GLOBAL_INT 消息
+ msg_set_position_target_global_int positionTarget = new msg_set_position_target_global_int();
+ positionTarget.target_system = 1; // 目标系统ID
+ positionTarget.target_component = 1; // 目标组件ID
+ positionTarget.coordinate_frame = MAV_FRAME.MAV_FRAME_GLOBAL_RELATIVE_ALT; // 坐标系
+ positionTarget.type_mask = 0b0000111111111000; // 仅位置控制,速度和加速度不控制
+
+ // 设置目标位置
+ positionTarget.lat_int = (int) (wgs84Coords[1] * 10000000); // 纬度 (单位: 1e-7度)
+ positionTarget.lon_int = (int) (wgs84Coords[0] * 10000000); // 经度 (单位: 1e-7度)
+ positionTarget.alt = (float) altitude; // 高度 (单位: 米)
+
+ // 设置目标速度
+ positionTarget.vx = 0; // X轴速度 (单位: m/s)
+ positionTarget.vy = 0; // Y轴速度 (单位: m/s)
+ positionTarget.vz = 0; // Z轴速度 (单位: m/s)
+
+ // 其他参数设置为0
+ positionTarget.afx = 0;
+ positionTarget.afy = 0;
+ positionTarget.afz = 0;
+ positionTarget.yaw = 0;
+ positionTarget.yaw_rate = 0;
+
+ // 发送消息
+ sendMavlinkMessage(MyBoundService.type, positionTarget);
+
+ } catch (Exception e) {
+ Log.e("FlyVoid", "adviseFlyWithGlobalPosition error: " + e.getMessage());
+ }
+ }
+
+
+
/**
* 方法:切换无人机飞行模式
*
@@ -816,4 +901,35 @@ public class FlyVoid {
}
+ /**
+ * 控制通道
+ * @param servoInstance 舵机编号 (1-8)
+ * @param pwmValue PWM值 (1000-2000微秒)
+ * 使用示例:将第1个舵机设置到中立位置
+ * controlServo(1, 1500);
+ */
+ public void controlServo(int servoInstance, int pwmValue) {
+ // 构造命令
+ msg_command_long command = new msg_command_long();
+
+ command.target_system = 1; // 目标系统ID(飞控)
+ command.target_component = 1; // 目标组件ID
+ command.command = MAV_CMD.MAV_CMD_DO_SET_SERVO; // 设置舵机命令
+ command.confirmation = 0; // 确认位
+
+ // 设置舵机参数
+ command.param1 = servoInstance; // 舵机实例号
+ command.param2 = pwmValue; // PWM值
+ command.param3 = 0; // 保留
+ command.param4 = 0; // 保留
+ command.param5 = 0; // 保留
+ command.param6 = 0; // 保留
+ command.param7 = 0; // 保留
+
+ // 发送命令
+ sendMavlinkMessage(MyBoundService.type, command);
+ }
+
+
+
}
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/Void/HeartbeatManager.java b/app/src/main/java/com/example/longyi_groundstation/Main/Void/HeartbeatManager.java
new file mode 100644
index 0000000..e459632
--- /dev/null
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/Void/HeartbeatManager.java
@@ -0,0 +1,140 @@
+// 新建文件 HeartbeatManager.java
+package com.example.longyi_groundstation.Main.Void;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+
+import com.example.longyi_groundstation.MAVLink.MAVLinkPacket;
+import com.example.longyi_groundstation.MAVLink.minimal.msg_heartbeat;
+
+import java.net.DatagramPacket;
+import java.net.InetAddress;
+
+import tp.xmaihh.serialport.SerialHelper;
+
+/**
+ * 心跳管理器类,用于管理与飞控的心跳通信
+ */
+public class HeartbeatManager {
+ private static final String TAG = "HeartbeatManager";
+ private static final long HEARTBEAT_INTERVAL = 1000; // 心跳间隔1秒
+
+ private Handler heartbeatHandler;
+ private Runnable heartbeatRunnable;
+ private boolean isHeartbeatRunning = false;
+ private int connectionType; // 0: 串口, 1: UDP
+ private SerialHelper serialHelper;
+ private java.net.DatagramSocket serverSocket;
+
+ public HeartbeatManager(int type, SerialHelper serialHelper, java.net.DatagramSocket serverSocket) {
+ this.connectionType = type;
+ this.serialHelper = serialHelper;
+ this.serverSocket = serverSocket;
+ this.heartbeatHandler = new Handler(Looper.getMainLooper());
+ }
+
+ /**
+ * 方法:启动心跳包发送
+ */
+ public void startHeartbeat() {
+ if (!isHeartbeatRunning) {
+ isHeartbeatRunning = true;
+ heartbeatRunnable = new Runnable() {
+ @Override
+ public void run() {
+ if (isHeartbeatRunning) {
+ sendHeartbeat();
+ heartbeatHandler.postDelayed(this, HEARTBEAT_INTERVAL);
+ }
+ }
+ };
+ heartbeatHandler.post(heartbeatRunnable);
+ }
+ }
+
+ /**
+ * 方法:停止心跳包发送
+ */
+ public void stopHeartbeat() {
+ isHeartbeatRunning = false;
+ if (heartbeatHandler != null && heartbeatRunnable != null) {
+ heartbeatHandler.removeCallbacks(heartbeatRunnable);
+ }
+ }
+
+ /**
+ * 方法:发送心跳包到飞控
+ */
+ private void sendHeartbeat() {
+ try {
+ // 创建心跳消息
+ msg_heartbeat heartbeat = new msg_heartbeat();
+
+ // 设置心跳参数
+ heartbeat.type = 6; // GCS类型
+ heartbeat.autopilot = 8; // MAV_AUTOPILOT_INVALID
+ heartbeat.base_mode = 0;
+ heartbeat.custom_mode = 0;
+ heartbeat.system_status = 0; // MAV_STATE_UNINIT
+
+ // 编码为MAVLinkPacket
+ MAVLinkPacket packet = heartbeat.pack();
+
+ // 发送数据(根据连接方式选择)
+ if (connectionType == 0) {
+ // 串口发送
+ if (serialHelper != null) {
+ serialHelper.send(packet.encodePacket());
+ }
+ } else {
+ // UDP发送
+ try {
+ if (serverSocket != null && !serverSocket.isClosed()) {
+ InetAddress targetAddress = InetAddress.getByName("127.0.0.1");
+ int targetPort = 14553; // 默认MAVLink端口
+ DatagramPacket udpPacket = new DatagramPacket(
+ packet.encodePacket(),
+ packet.encodePacket().length,
+ targetAddress,
+ targetPort
+ );
+ serverSocket.send(udpPacket);
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "发送心跳包失败: " + e.getMessage());
+ }
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "构建心跳包失败: " + e.getMessage());
+ }
+ }
+
+ /**
+ * 方法:设置连接类型
+ */
+ public void setConnectionType(int type) {
+ this.connectionType = type;
+ }
+
+ /**
+ * 方法:设置串口助手
+ */
+ public void setSerialHelper(SerialHelper serialHelper) {
+ this.serialHelper = serialHelper;
+ }
+
+ /**
+ * 方法:设置UDP套接字
+ */
+ public void setServerSocket(java.net.DatagramSocket serverSocket) {
+ this.serverSocket = serverSocket;
+ }
+
+ /**
+ * 方法:检查心跳是否正在运行
+ */
+ public boolean isRunning() {
+ return isHeartbeatRunning;
+ }
+}
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/Void/LidarDataParser.java b/app/src/main/java/com/example/longyi_groundstation/Main/Void/LidarDataParser.java
new file mode 100644
index 0000000..7c44f09
--- /dev/null
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/Void/LidarDataParser.java
@@ -0,0 +1,212 @@
+package com.example.longyi_groundstation.Main.Void;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+import android.widget.TextView;
+
+/**
+ * 雷达高度数据解析器
+ * 用于解析以0xFF开头的数据包格式:FF + 高度高字节 + 高度低字节 + 引爆高度 + 校验字节
+ * 支持高频率调用(200Hz以上)和传感器失效监测
+ */
+public class LidarDataParser {
+
+ // 解析状态定义
+ public static final int PARSE_STATE_HEAD = 0; // 等待包头
+ public static final int PARSE_STATE_PAYLOAD = 1; // 接收数据载荷
+ public static final int PARSE_STATE_CHECKSUM = 2; // 校验和检查
+
+ // 协议定义
+ public static final byte PROTOCOL_HEAD = (byte) 0xFF;
+ public static final int PROTOCOL_LENGTH = 5; // 总长度:FF + 2字节高度 + 1字节引爆高度 + 1字节校验
+
+ // 监测相关常量
+ public static final int SENSOR_FAILURE_THRESHOLD = 5; // 失效阈值
+ public static final int UPDATE_INTERVAL = 1000; // 更新间隔(毫秒)
+
+ // 解析状态变量
+ public int parseStep = PARSE_STATE_HEAD; // 当前解析步骤
+ public int packetIndex = 0; // 数据包索引
+ public byte[] packetBuffer = new byte[5]; // 数据包缓冲区
+
+ // 监测相关变量
+ public int invalidCount = 0; // 无效计数
+ public boolean isSensorFailed = false; // 传感器是否失效
+ public static int[] parsedData = null; // 解析后的数据 [雷达高度, 引爆高度]
+
+ // UI更新相关
+ public static Handler uiHandler;
+ public static Runnable updateRunnable;
+ public static boolean isUpdating = false;
+
+ /**
+ * 解析单个字节数据(高频率调用版本)
+ * 建议在200Hz以上频率调用
+ *
+ * @param data 单个接收到的字节
+ * @return 1表示解析成功并更新了数据,0表示未完成解析
+ */
+ public int parseByte(byte data) {
+ int result = 0;
+
+ switch (parseStep) {
+ // 等待包头
+ case PARSE_STATE_HEAD:
+ if (data == PROTOCOL_HEAD) {
+ packetBuffer[packetIndex++] = data;
+ parseStep = PARSE_STATE_PAYLOAD;
+ }
+ break;
+
+ // 接收数据载荷
+ case PARSE_STATE_PAYLOAD:
+ packetBuffer[packetIndex++] = data;
+
+ // 检查是否收到完整数据包
+ if (packetIndex >= PROTOCOL_LENGTH) {
+ parseStep = PARSE_STATE_CHECKSUM;
+ }
+ break;
+
+ // 校验和检查
+ case PARSE_STATE_CHECKSUM:
+ int calculatedChecksum = 0;
+ // 计算前4个字节的校验和(累加求和方式)
+ for (int i = 0; i < 4; i++) {
+ calculatedChecksum += (packetBuffer[i] & 0xFF);
+ }
+ calculatedChecksum &= 0xFF; // 取低8位作为校验和
+
+ // 校验
+ if (calculatedChecksum == (packetBuffer[4] & 0xFF)) {
+ // 解析成功,更新数据
+ int radarHeight = ((packetBuffer[1] & 0xFF) << 8) | (packetBuffer[2] & 0xFF);
+ int triggerHeight = packetBuffer[3] & 0xFF;
+// Log.d("LidarDataParser", radarHeight + "m");
+ // 保存解析结果
+ parsedData = new int[]{radarHeight, triggerHeight};
+
+ // 重置监测计数
+ invalidCount = 0;
+ isSensorFailed = false;
+
+ result = 1;
+ } else {
+ // 校验失败,增加错误计数
+ invalidCount++;
+ checkSensorFailure();
+ }
+
+ // 重置状态,准备接收下一数据包
+ packetIndex = 0;
+ parseStep = PARSE_STATE_HEAD;
+ break;
+ }
+
+ return result;
+ }
+
+ /**
+ * 监测传感器状态
+ * 建议以10Hz频率定期调用
+ */
+ private void checkSensorFailure() {
+ if (invalidCount > SENSOR_FAILURE_THRESHOLD) {
+ isSensorFailed = true;
+ }
+ }
+
+ /**
+ * 获取传感器失效状态
+ *
+ * @return true表示传感器失效,false表示正常
+ */
+ public boolean isSensorFailed() {
+ return isSensorFailed;
+ }
+
+ /**
+ * 获取解析后的数据
+ *
+ * @return int数组,[0]为雷达高度,[1]为引爆高度,如果无有效数据则返回null
+ */
+ public static int[] getParsedData() {
+ return parsedData;
+ }
+
+ /**
+ * 启动高度显示更新线程
+ * 每隔1秒更新TextView显示雷达高度数据
+ *
+ * @param textView 要更新的TextView
+ */
+ public static void startHeightUpdate(TextView textView) {
+ if (isUpdating) {
+ stopHeightUpdate();
+ }
+
+ isUpdating = true;
+ uiHandler = new Handler(Looper.getMainLooper());
+ updateRunnable = new Runnable() {
+ @Override
+ public void run() {
+ if (isUpdating) {
+ int[] data = getParsedData();
+ if (data != null && textView != null) {
+// Log.d("startHeightUpdate", "激光:"+data[0]+"m"+" 引爆:"+data[1]+"m");
+ textView.setText(data[0] + "m");
+ } else if (textView != null) {
+ textView.setText("--");
+ }
+
+ // 每隔1秒更新一次
+ uiHandler.postDelayed(this, UPDATE_INTERVAL);
+ }
+ }
+ };
+
+ // 立即开始更新
+ uiHandler.post(updateRunnable);
+ }
+
+ /**
+ * 停止高度显示更新
+ */
+ public static void stopHeightUpdate() {
+ isUpdating = false;
+ if (uiHandler != null && updateRunnable != null) {
+ uiHandler.removeCallbacks(updateRunnable);
+ uiHandler = null;
+ updateRunnable = null;
+ }
+ }
+
+ /**
+ * 检查是否正在更新UI
+ *
+ * @return true表示正在更新,false表示未更新
+ */
+ public boolean isUpdating() {
+ return isUpdating;
+ }
+
+ /**
+ * 重置传感器状态和解析器状态
+ */
+ public void reset() {
+ invalidCount = 0;
+ isSensorFailed = false;
+ packetIndex = 0;
+ parseStep = PARSE_STATE_HEAD;
+ parsedData = null;
+ }
+
+ /**
+ * 增加无效计数(用于外部监测调用)
+ */
+ public void incrementInvalidCount() {
+ invalidCount++;
+ checkSensorFailure();
+ }
+}
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/Void/LogCat/LogUtil.java b/app/src/main/java/com/example/longyi_groundstation/Main/Void/LogCat/LogUtil.java
index a9efc8d..067514c 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Main/Void/LogCat/LogUtil.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/Void/LogCat/LogUtil.java
@@ -6,10 +6,10 @@ import android.util.Log;
public class LogUtil {
public static void d(String tag, String msg) {
// 正常打印日志
-// Log.d(tag, msg);
+ Log.d(tag, msg);
// 保存日志到文件
- LogManager.getInstance().saveLog(tag, msg);
+// LogManager.getInstance().saveLog(tag, msg);
}
// 可以添加其他级别的日志方法 (e, w, i等)
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/Void/MapVoid.java b/app/src/main/java/com/example/longyi_groundstation/Main/Void/MapVoid.java
index 50152d4..d1a237e 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Main/Void/MapVoid.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/Void/MapVoid.java
@@ -163,7 +163,7 @@ public class MapVoid {
}
} catch (Exception e) {
// e.printStackTrace();
- Log.d(TAG, "error: "+e);
+ Log.d("cui_error", "error: "+e);
// 2秒后再次执行
flightTrackHandler.postDelayed(this, 600);
}
@@ -194,17 +194,17 @@ public class MapVoid {
flightTrackPolyline.remove();
}
- // 控制轨迹点数量不超过20个
- if (flightTrackPoints.size() > 2048) {
- flightTrackPoints.remove(0); // 删除最后一个点
- }
-
List sparsePoints = new ArrayList<>();
// 每5个点取1个点,减少点密度
- for (int i = 0; i < flightTrackPoints.size(); i += 5) {
+ for (int i = 0; i < flightTrackPoints.size(); i++) {
sparsePoints.add(flightTrackPoints.get(i));
}
+ // 控制轨迹点数量不超过20个
+ if (flightTrackPoints.size() > 300) {
+ flightTrackPoints.remove(0); // 删除最后一个点
+ }
+
flightTrackPolyline = allView.map.getMap().addPolyline(new PolylineOptions()
.addAll(sparsePoints)
.width(12)
@@ -230,6 +230,33 @@ public class MapVoid {
flightTrackPoints.clear();
}
+ /**
+ * 计算两个带高度的坐标点之间的直线距离(单位:厘米,返回整数)
+ * @param latLng1 第一个坐标点(包含纬度、经度)
+ * @param altitude1 第一个点的高度(米)
+ * @param latLng2 第二个坐标点(包含纬度、经度)
+ * @param altitude2 第二个点的高度(米)
+ * @return 距离(厘米,整数)
+ */
+ public static int calculateDistanceWithAltitudeInCm(LatLng latLng1, double altitude1,
+ LatLng latLng2, double altitude2) {
+ if (latLng1 == null || latLng2 == null) {
+ return 0;
+ }
+
+ // 计算水平距离(米)
+ double horizontalDistance = AMapUtils.calculateLineDistance(latLng1, latLng2);
+
+ // 计算高度差(米)
+ double altitudeDifference = Math.abs(altitude2 - altitude1);
+
+ // 使用三维勾股定理计算直线距离(米)
+ double straightDistance = Math.sqrt(horizontalDistance * horizontalDistance +
+ altitudeDifference * altitudeDifference);
+
+ // 转换为厘米并返回整数
+ return (int) Math.round(straightDistance * 100);
+ }
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/Void/SQLClass.java b/app/src/main/java/com/example/longyi_groundstation/Main/Void/SQLClass.java
index fbee95f..769728b 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Main/Void/SQLClass.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/Void/SQLClass.java
@@ -47,7 +47,7 @@ public class SQLClass extends SQLiteOpenHelper {
// 数据库名称和版本
private static final String DATABASE_NAME = "create_link_list.db";
- private static final int DATABASE_VERSION = 1;
+ private static final int DATABASE_VERSION = 4; // 更新版本号以支持stop_time字段
// 主表 - 存储列表信息
private static final String TABLE_LINK_LIST = "link_list";
@@ -65,9 +65,15 @@ public class SQLClass extends SQLiteOpenHelper {
private static final String COLUMN_WAYPOINT_INDEX = "waypoint_index";
private static final String COLUMN_LATITUDE = "latitude";
private static final String COLUMN_LONGITUDE = "longitude";
- private static final String COLUMN_BOM1_SELECT = "bom1_select";
- private static final String COLUMN_BOM2_SELECT = "bom2_select";
+ // CreateLink类中的字段
+ private static final String COLUMN_BOM1_SELECT = "bom1_select";
+ private static final String COLUMN_BOM1_SHOW = "bom1_show";
+ private static final String COLUMN_BOM1_HEIGHT = "bom1_height";
+ private static final String COLUMN_BOM2_SELECT = "bom2_select";
+ private static final String COLUMN_BOM2_SHOW = "bom2_show";
+ private static final String COLUMN_BOM2_HEIGHT = "bom2_height";
+ private static final String COLUMN_STOP_TIME = "stop_time"; // 新增字段
private static final String COLUMN_ITEM_ORDER = "item_order"; // 项在列表中的顺序
@@ -78,7 +84,7 @@ public class SQLClass extends SQLiteOpenHelper {
COLUMN_LIST_NAME + " TEXT NOT NULL, " +
COLUMN_CREATED_TIME + " INTEGER NOT NULL)";
- // 创建详情表的SQL语句
+ // 创建详情表的SQL语句(包含所有字段)
private static final String CREATE_ITEMS_TABLE_SQL =
"CREATE TABLE " + TABLE_LINK_ITEMS + " (" +
COLUMN_ITEM_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
@@ -89,6 +95,13 @@ public class SQLClass extends SQLiteOpenHelper {
COLUMN_WAYPOINT_INDEX + " INTEGER NOT NULL, " +
COLUMN_LATITUDE + " REAL, " +
COLUMN_LONGITUDE + " REAL, " +
+ COLUMN_BOM1_SELECT + " INTEGER DEFAULT 0, " +
+ COLUMN_BOM1_SHOW + " INTEGER DEFAULT 0, " +
+ COLUMN_BOM1_HEIGHT + " INTEGER DEFAULT 0, " +
+ COLUMN_BOM2_SELECT + " INTEGER DEFAULT 0, " +
+ COLUMN_BOM2_SHOW + " INTEGER DEFAULT 0, " +
+ COLUMN_BOM2_HEIGHT + " INTEGER DEFAULT 0, " +
+ COLUMN_STOP_TIME + " INTEGER DEFAULT 0, " + // 新增字段
COLUMN_ITEM_ORDER + " INTEGER NOT NULL, " +
"FOREIGN KEY(" + COLUMN_LIST_REF_ID + ") REFERENCES " +
TABLE_LINK_LIST + "(" + COLUMN_LIST_ID + ") ON DELETE CASCADE)";
@@ -105,9 +118,31 @@ public class SQLClass extends SQLiteOpenHelper {
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- db.execSQL("DROP TABLE IF EXISTS " + TABLE_LINK_ITEMS);
- db.execSQL("DROP TABLE IF EXISTS " + TABLE_LINK_LIST);
- onCreate(db);
+ if (oldVersion < 2) {
+ // 添加第2版新增的列
+ db.execSQL("ALTER TABLE " + TABLE_LINK_ITEMS + " ADD COLUMN " + COLUMN_BOM1_SELECT + " INTEGER DEFAULT 0");
+ db.execSQL("ALTER TABLE " + TABLE_LINK_ITEMS + " ADD COLUMN " + COLUMN_BOM2_SELECT + " INTEGER DEFAULT 0");
+ }
+
+ if (oldVersion < 3) {
+ // 添加第3版新增的列
+ db.execSQL("ALTER TABLE " + TABLE_LINK_ITEMS + " ADD COLUMN " + COLUMN_BOM1_SHOW + " INTEGER DEFAULT 0");
+ db.execSQL("ALTER TABLE " + TABLE_LINK_ITEMS + " ADD COLUMN " + COLUMN_BOM1_HEIGHT + " INTEGER DEFAULT 0");
+ db.execSQL("ALTER TABLE " + TABLE_LINK_ITEMS + " ADD COLUMN " + COLUMN_BOM2_SHOW + " INTEGER DEFAULT 0");
+ db.execSQL("ALTER TABLE " + TABLE_LINK_ITEMS + " ADD COLUMN " + COLUMN_BOM2_HEIGHT + " INTEGER DEFAULT 0");
+ }
+
+ if (oldVersion < 4) {
+ // 添加第4版新增的列(stop_time字段)
+ db.execSQL("ALTER TABLE " + TABLE_LINK_ITEMS + " ADD COLUMN " + COLUMN_STOP_TIME + " INTEGER DEFAULT 0");
+ }
+
+ if (oldVersion < 1 || oldVersion >= 4) {
+ // 原有的升级逻辑(版本1或更高版本时)
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_LINK_ITEMS);
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_LINK_LIST);
+ onCreate(db);
+ }
}
@Override
@@ -155,6 +190,16 @@ public class SQLClass extends SQLiteOpenHelper {
itemValues.put(COLUMN_SPEED, createLink.getSpeed());
itemValues.put(COLUMN_WAYPOINT_INDEX, createLink.getWaypointIndex());
+ // 添加所有字段的处理
+ itemValues.put(COLUMN_BOM1_SELECT, createLink.isBom1_select() ? 1 : 0);
+ itemValues.put(COLUMN_BOM1_SHOW, createLink.isBom1_show() ? 1 : 0);
+ itemValues.put(COLUMN_BOM1_HEIGHT, createLink.getBom1_height());
+ itemValues.put(COLUMN_BOM2_SELECT, createLink.isBom2_select() ? 1 : 0);
+ itemValues.put(COLUMN_BOM2_SHOW, createLink.isBom2_show() ? 1 : 0);
+ itemValues.put(COLUMN_BOM2_HEIGHT, createLink.getBom2_height());
+ // 新增字段处理
+ itemValues.put(COLUMN_STOP_TIME, createLink.getStop_time());
+
if (createLink.getLatLng() != null) {
itemValues.put(COLUMN_LATITUDE, createLink.getLatLng().latitude);
itemValues.put(COLUMN_LONGITUDE, createLink.getLatLng().longitude);
@@ -239,11 +284,28 @@ public class SQLClass extends SQLiteOpenHelper {
int waypointIndex = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_WAYPOINT_INDEX));
double latitude = cursor.getDouble(cursor.getColumnIndexOrThrow(COLUMN_LATITUDE));
double longitude = cursor.getDouble(cursor.getColumnIndexOrThrow(COLUMN_LONGITUDE));
-// boolean bom1_select = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_BOM1_SELECT)) == 1;
-// boolean bom2_select = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_BOM2_SELECT)) == 1;
+
+ // 获取字段的值
+ boolean bom1_select = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_BOM1_SELECT)) == 1;
+ boolean bom1_show = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_BOM1_SHOW)) == 1;
+ int bom1_height = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_BOM1_HEIGHT));
+ boolean bom2_select = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_BOM2_SELECT)) == 1;
+ boolean bom2_show = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_BOM2_SHOW)) == 1;
+ int bom2_height = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_BOM2_HEIGHT));
+ // 新增字段读取
+ int stop_time = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_STOP_TIME));
LatLng latLng = new LatLng(latitude, longitude);
- CreateLink createLink = new CreateLink(name, height, speed, waypointIndex, latLng);
+ CreateLink createLink = new CreateLink(name, height, speed, waypointIndex, latLng,stop_time, bom1_show, bom2_show);
+ // 设置其他字段
+ createLink.setBom1_select(bom1_select);
+ createLink.setBom1_height(bom1_height);
+ createLink.setBom2_select(bom2_select);
+ createLink.setBom2_height(bom2_height);
+ createLink.setBom2_show(bom2_show);
+ // 设置新增字段
+ createLink.setStop_time(stop_time);
+
createLinkList.add(createLink);
} while (cursor.moveToNext());
}
@@ -299,6 +361,16 @@ public class SQLClass extends SQLiteOpenHelper {
itemValues.put(COLUMN_SPEED, createLink.getSpeed());
itemValues.put(COLUMN_WAYPOINT_INDEX, createLink.getWaypointIndex());
+ // 添加所有字段的处理
+ itemValues.put(COLUMN_BOM1_SELECT, createLink.isBom1_select() ? 1 : 0);
+ itemValues.put(COLUMN_BOM1_SHOW, createLink.isBom1_show() ? 1 : 0);
+ itemValues.put(COLUMN_BOM1_HEIGHT, createLink.getBom1_height());
+ itemValues.put(COLUMN_BOM2_SELECT, createLink.isBom2_select() ? 1 : 0);
+ itemValues.put(COLUMN_BOM2_SHOW, createLink.isBom2_show() ? 1 : 0);
+ itemValues.put(COLUMN_BOM2_HEIGHT, createLink.getBom2_height());
+ // 新增字段处理
+ itemValues.put(COLUMN_STOP_TIME, createLink.getStop_time());
+
if (createLink.getLatLng() != null) {
itemValues.put(COLUMN_LATITUDE, createLink.getLatLng().latitude);
itemValues.put(COLUMN_LONGITUDE, createLink.getLatLng().longitude);
diff --git a/app/src/main/java/com/example/longyi_groundstation/Main/Void/SerialTool.java b/app/src/main/java/com/example/longyi_groundstation/Main/Void/SerialTool.java
index e2ad7ee..e8fea2f 100644
--- a/app/src/main/java/com/example/longyi_groundstation/Main/Void/SerialTool.java
+++ b/app/src/main/java/com/example/longyi_groundstation/Main/Void/SerialTool.java
@@ -80,12 +80,12 @@ public class SerialTool {
* @return 包含解析结果的数组,[0]为第2、3字节组合的值,[1]为第4字节的值;校验失败返回null
*/
public static int[] parseSerialData(byte[] data) {
- if (data == null || data.length < 4) {
+ if (data == null || data.length < 5) {
throw new IllegalArgumentException("数据长度不足,无法解析");
}
// 校验:第4个字节应该等于前三个字节之和的低8位
- int checksum = (data[0] & 0xFF) + (data[1] & 0xFF) + (data[2] & 0xFF);
+ int checksum = (data[1] & 0xFF) + (data[2] & 0xFF) + (data[3] & 0xFF);
checksum = checksum & 0xFF; // 取低8位
// 如果校验失败,返回null
diff --git a/app/src/main/java/com/example/longyi_groundstation/Util/Http/HttpUrl.java b/app/src/main/java/com/example/longyi_groundstation/Util/Http/HttpUrl.java
new file mode 100644
index 0000000..5cad2a8
--- /dev/null
+++ b/app/src/main/java/com/example/longyi_groundstation/Util/Http/HttpUrl.java
@@ -0,0 +1,8 @@
+package com.example.longyi_groundstation.Util.Http;
+
+public class HttpUrl {
+
+ public static final String BASE_URL = "https://api.longyi-uav-cloud.com";
+ public static final String LOGIN = BASE_URL + "/admin-api/system/auth/login";
+
+}
diff --git a/app/src/main/java/com/example/longyi_groundstation/Util/Http/HttpUtil.java b/app/src/main/java/com/example/longyi_groundstation/Util/Http/HttpUtil.java
new file mode 100644
index 0000000..060f2be
--- /dev/null
+++ b/app/src/main/java/com/example/longyi_groundstation/Util/Http/HttpUtil.java
@@ -0,0 +1,130 @@
+package com.example.longyi_groundstation.Util.Http;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import okhttp3.Callback;
+import okhttp3.MediaType;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+
+/**
+ * 基于OkHttp3的网络请求工具类
+ */
+public class HttpUtil {
+ private static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8");
+ private static final MediaType MEDIA_TYPE_FORM = MediaType.parse("application/x-www-form-urlencoded");
+
+ private OkHttpClient client;
+
+ public HttpUtil() {
+ this.client = new OkHttpClient.Builder()
+ .connectTimeout(10, TimeUnit.SECONDS)
+ .readTimeout(30, TimeUnit.SECONDS)
+ .writeTimeout(30, TimeUnit.SECONDS)
+ .retryOnConnectionFailure(true)
+ .build();
+ }
+
+ /**
+ * GET请求
+ * @param url 请求地址
+ * @param headers 请求头
+ * @param callback 回调函数
+ */
+ public void get(String url, Map headers, Callback callback) {
+ Request.Builder builder = new Request.Builder().url(url);
+
+ // 添加请求头
+ addHeaders(builder, headers);
+
+ Request request = builder.get().build();
+ client.newCall(request).enqueue(callback);
+ }
+
+ /**
+ * POST请求 - JSON格式
+ * @param url 请求地址
+ * @param json JSON数据
+ * @param headers 请求头
+ * @param callback 回调函数
+ */
+ public void postJson(String url, String json, Map headers, Callback callback) {
+ RequestBody body = RequestBody.create(json, MEDIA_TYPE_JSON);
+ Request.Builder builder = new Request.Builder()
+ .url(url)
+ .post(body);
+
+ addHeaders(builder, headers);
+
+ Request request = builder.build();
+ client.newCall(request).enqueue(callback);
+ }
+
+ /**
+ * POST请求 - 表单格式
+ * @param url 请求地址
+ * @param formData 表单数据
+ * @param headers 请求头
+ * @param callback 回调函数
+ */
+ public void postForm(String url, String formData, Map headers, Callback callback) {
+ RequestBody body = RequestBody.create(formData, MEDIA_TYPE_FORM);
+ Request.Builder builder = new Request.Builder()
+ .url(url)
+ .post(body);
+
+ addHeaders(builder, headers);
+
+ Request request = builder.build();
+ client.newCall(request).enqueue(callback);
+ }
+
+ /**
+ * 同步GET请求
+ * @param url 请求地址
+ * @param headers 请求头
+ * @return Response响应对象
+ * @throws IOException IO异常
+ */
+ public Response executeGet(String url, Map headers) throws IOException {
+ Request.Builder builder = new Request.Builder().url(url);
+ addHeaders(builder, headers);
+
+ Request request = builder.get().build();
+ return client.newCall(request).execute();
+ }
+
+ /**
+ * 同步POST请求 - JSON格式
+ * @param url 请求地址
+ * @param json JSON数据
+ * @param headers 请求头
+ * @return Response响应对象
+ * @throws IOException IO异常
+ */
+ public Response executePostJson(String url, String json, Map headers) throws IOException {
+ RequestBody body = RequestBody.create(json, MEDIA_TYPE_JSON);
+ Request.Builder builder = new Request.Builder().url(url).post(body);
+ addHeaders(builder, headers);
+
+ Request request = builder.build();
+ return client.newCall(request).execute();
+ }
+
+ /**
+ * 添加请求头
+ * @param builder Request.Builder构建器
+ * @param headers 请求头Map
+ */
+ private void addHeaders(Request.Builder builder, Map headers) {
+ if (headers != null) {
+ for (Map.Entry entry : headers.entrySet()) {
+ builder.addHeader(entry.getKey(), entry.getValue());
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/longyi_groundstation/Util/SharedPreferencesTool.java b/app/src/main/java/com/example/longyi_groundstation/Util/SharedPreferencesTool.java
new file mode 100644
index 0000000..b0275fb
--- /dev/null
+++ b/app/src/main/java/com/example/longyi_groundstation/Util/SharedPreferencesTool.java
@@ -0,0 +1,65 @@
+package com.example.longyi_groundstation.Util;
+
+import static android.content.Context.MODE_PRIVATE;
+
+import android.content.Context;
+import android.util.Log;
+
+import org.json.JSONObject;
+
+public class SharedPreferencesTool {
+
+ private static String TAG = "SharedPreferencesTool";
+
+ public static void saveLogin(Context context, JSONObject userData) {
+ try {
+ // 使用 SharedPreferences 保存用户信息
+ android.content.SharedPreferences sharedPreferences =
+ context.getSharedPreferences("user_info", MODE_PRIVATE);
+ android.content.SharedPreferences.Editor editor = sharedPreferences.edit();
+
+ editor.putInt("id", userData.getInt("id"));
+ editor.putString("avatar", userData.getString("avatar"));
+ editor.putString("nickname", userData.getString("nickname"));
+ editor.putString("mobile", userData.getString("mobile"));
+ editor.putLong("create_time", userData.getLong("create_time"));
+ editor.putLong("update_time", userData.getLong("update_time"));
+ editor.putInt("is_active", userData.getInt("is_active"));
+ editor.putInt("sort", userData.getInt("sort"));
+ editor.putString("token", userData.getString("token"));
+ editor.apply(); // 异步保存
+ }catch (Exception e){
+ Log.d(TAG, "saveLogin:error " + e);
+ }
+
+ }
+
+ public static String getToken(Context context){
+ android.content.SharedPreferences sharedPreferences =
+ context.getSharedPreferences("user_info", MODE_PRIVATE);
+ String token = sharedPreferences.getString("token", null);
+ return token;
+ }
+
+ public static JSONObject getUserInfo(Context context){
+
+ android.content.SharedPreferences sharedPreferences =
+ context.getSharedPreferences("user_info", MODE_PRIVATE);
+ JSONObject userInfo = new JSONObject();
+ try {
+ userInfo.put("id", sharedPreferences.getInt("id", 0));
+ userInfo.put("avatar", sharedPreferences.getString("avatar", ""));
+ userInfo.put("nickname", sharedPreferences.getString("nickname", ""));
+ userInfo.put("mobile", sharedPreferences.getString("mobile", ""));
+ userInfo.put("create_time", sharedPreferences.getLong("create_time", 0));
+ userInfo.put("update_time", sharedPreferences.getLong( "update_time", 0));
+ userInfo.put("is_active", sharedPreferences.getInt("is_active", 0));
+ userInfo.put("sort", sharedPreferences.getInt("sort", 0));
+ userInfo.put("token", sharedPreferences.getString("token", ""));
+ return userInfo;
+ }catch (Exception e){
+ return null;
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/example/longyi_groundstation/Util/Url.java b/app/src/main/java/com/example/longyi_groundstation/Util/Url.java
deleted file mode 100644
index 7c49cb6..0000000
--- a/app/src/main/java/com/example/longyi_groundstation/Util/Url.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.example.longyi_groundstation.Util;
-
-public class Url {
-
- public static String getBaseUrl() {
- return "https://api.longyi-uav-cloud.com";
- }
-
- /**
- * 方法:登录接口
- *
- * @cuijingzhou
- */
- public static String LoginUrl() {
- return getBaseUrl() + "/admin-api/system/auth/login";
- }
-
-}
diff --git a/app/src/main/res/drawable/b2101010_4round_1stroke_bg.xml b/app/src/main/res/drawable/b2101010_4round_1stroke_bg.xml
index 3b839f5..ca8c203 100644
--- a/app/src/main/res/drawable/b2101010_4round_1stroke_bg.xml
+++ b/app/src/main/res/drawable/b2101010_4round_1stroke_bg.xml
@@ -5,7 +5,7 @@
+ android:color="#3A3A3A"/>
diff --git a/app/src/main/res/drawable/b2303030_4round_1stroke_bg.xml b/app/src/main/res/drawable/b2303030_4round_1stroke_bg.xml
index 2fa423e..7a0376e 100644
--- a/app/src/main/res/drawable/b2303030_4round_1stroke_bg.xml
+++ b/app/src/main/res/drawable/b2303030_4round_1stroke_bg.xml
@@ -7,6 +7,6 @@
android:width="0.5dp"
android:color="#303030"/>
-
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/x94555f75_16round_bg.xml b/app/src/main/res/drawable/cc3d4453_16round_bg.xml
similarity index 79%
rename from app/src/main/res/drawable/x94555f75_16round_bg.xml
rename to app/src/main/res/drawable/cc3d4453_16round_bg.xml
index c8c6a6e..5812a49 100644
--- a/app/src/main/res/drawable/x94555f75_16round_bg.xml
+++ b/app/src/main/res/drawable/cc3d4453_16round_bg.xml
@@ -3,7 +3,7 @@
-
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/x94555f75_4round_bg.xml b/app/src/main/res/drawable/cc3d4453_4round_bg.xml
similarity index 79%
rename from app/src/main/res/drawable/x94555f75_4round_bg.xml
rename to app/src/main/res/drawable/cc3d4453_4round_bg.xml
index 0871e3e..dde9832 100644
--- a/app/src/main/res/drawable/x94555f75_4round_bg.xml
+++ b/app/src/main/res/drawable/cc3d4453_4round_bg.xml
@@ -3,7 +3,7 @@
-
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ff8decec_2round_bg.xml b/app/src/main/res/drawable/ff029b45_2round_bg.xml
similarity index 80%
rename from app/src/main/res/drawable/ff8decec_2round_bg.xml
rename to app/src/main/res/drawable/ff029b45_2round_bg.xml
index b971a11..dc2016a 100644
--- a/app/src/main/res/drawable/ff8decec_2round_bg.xml
+++ b/app/src/main/res/drawable/ff029b45_2round_bg.xml
@@ -3,6 +3,6 @@
-
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ff101010_2round_1stroke_bg.xml b/app/src/main/res/drawable/ff101010_2round_1stroke_bg.xml
new file mode 100644
index 0000000..6be7704
--- /dev/null
+++ b/app/src/main/res/drawable/ff101010_2round_1stroke_bg.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ff112446_4round_bg.xml b/app/src/main/res/drawable/ff112446_4round_bg.xml
index a5988f8..39d5779 100644
--- a/app/src/main/res/drawable/ff112446_4round_bg.xml
+++ b/app/src/main/res/drawable/ff112446_4round_bg.xml
@@ -3,6 +3,6 @@
-
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ff33b138_1round_1stroke.xml b/app/src/main/res/drawable/ff33b138_1round_1stroke.xml
index d60c5c0..01fdcdd 100644
--- a/app/src/main/res/drawable/ff33b138_1round_1stroke.xml
+++ b/app/src/main/res/drawable/ff33b138_1round_1stroke.xml
@@ -2,6 +2,6 @@
-
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ff909090_2round_1stroke_bg.xml b/app/src/main/res/drawable/ff909090_2round_1stroke_bg.xml
new file mode 100644
index 0000000..e474389
--- /dev/null
+++ b/app/src/main/res/drawable/ff909090_2round_1stroke_bg.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/x94555f75_8round_bg.xml b/app/src/main/res/drawable/x94555f75_8round_bg.xml
index 4976d1c..cafc7c7 100644
--- a/app/src/main/res/drawable/x94555f75_8round_bg.xml
+++ b/app/src/main/res/drawable/x94555f75_8round_bg.xml
@@ -3,7 +3,7 @@
-
+
diff --git a/app/src/main/res/drawable/xbb303030_4round_bg.xml b/app/src/main/res/drawable/xbb303030_4round_bg.xml
index 57dc37a..dff2df1 100644
--- a/app/src/main/res/drawable/xbb303030_4round_bg.xml
+++ b/app/src/main/res/drawable/xbb303030_4round_bg.xml
@@ -3,6 +3,6 @@
-
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/xff555f75_4round_bg.xml b/app/src/main/res/drawable/xff555f75_4round_bg.xml
new file mode 100644
index 0000000..3b7c1f9
--- /dev/null
+++ b/app/src/main/res/drawable/xff555f75_4round_bg.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_funcation.xml b/app/src/main/res/layout/activity_funcation.xml
index f0f9d2b..b692e17 100644
--- a/app/src/main/res/layout/activity_funcation.xml
+++ b/app/src/main/res/layout/activity_funcation.xml
@@ -153,7 +153,7 @@
android:layout_marginTop="10dp"
android:layout_width="180dp"
android:layout_height="40dp"
- android:background="@drawable/x94555f75_4round_bg"
+ android:background="@drawable/cc3d4453_4round_bg"
android:gravity="center"
android:orientation="horizontal">
diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml
index 6461afe..ff5b756 100644
--- a/app/src/main/res/layout/activity_login.xml
+++ b/app/src/main/res/layout/activity_login.xml
@@ -14,7 +14,7 @@
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="20dp"
- android:background="@drawable/x94555f75_16round_bg"
+ android:background="@drawable/cc3d4453_16round_bg"
android:elevation="4dp">
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 58ad39b..2ed4ce5 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -311,8 +311,8 @@
@@ -446,7 +446,7 @@
android:background="@drawable/b2ffffff_4round_1stroke_bg"
android:gravity="center"
android:padding="5dp"
- android:visibility="gone">
+ android:visibility="visible">
-
-
-
+ android:visibility="gone">
@@ -1510,14 +1507,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1631,7 +1763,6 @@
-
+
+
diff --git a/app/src/main/res/layout/activity_setting.xml b/app/src/main/res/layout/activity_setting.xml
index 381fc84..662517f 100644
--- a/app/src/main/res/layout/activity_setting.xml
+++ b/app/src/main/res/layout/activity_setting.xml
@@ -55,7 +55,7 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/adapter_create_link_item.xml b/app/src/main/res/layout/adapter_create_link_item.xml
index e16d525..d1b020a 100644
--- a/app/src/main/res/layout/adapter_create_link_item.xml
+++ b/app/src/main/res/layout/adapter_create_link_item.xml
@@ -2,6 +2,7 @@
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
diff --git a/app/src/main/res/layout/adapter_motor_data_item.xml b/app/src/main/res/layout/adapter_motor_data_item.xml
index d7215e3..d983154 100644
--- a/app/src/main/res/layout/adapter_motor_data_item.xml
+++ b/app/src/main/res/layout/adapter_motor_data_item.xml
@@ -4,9 +4,10 @@
android:layout_height="wrap_content">
@@ -15,7 +15,7 @@
android:id="@+id/param_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textSize="14sp" />
+ android:textSize="11sp" />
diff --git a/app/src/main/res/layout/adapter_param_item.xml b/app/src/main/res/layout/adapter_param_item.xml
index 1be3b25..e7e3231 100644
--- a/app/src/main/res/layout/adapter_param_item.xml
+++ b/app/src/main/res/layout/adapter_param_item.xml
@@ -4,7 +4,7 @@
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:id="@+id/ll_main"
- android:background="@drawable/ff8decec_2round_bg"
+ android:background="@drawable/ff029b45_2round_bg"
android:orientation="horizontal"
android:layout_centerInParent="true"
android:padding="8dp">
@@ -16,7 +16,7 @@
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
- android:textSize="14sp" />
+ android:textSize="11sp" />
+ android:textSize="11sp" />
diff --git a/app/src/main/res/layout/adapter_secure_item.xml b/app/src/main/res/layout/adapter_secure_item.xml
index 11d6fd5..4fb8856 100644
--- a/app/src/main/res/layout/adapter_secure_item.xml
+++ b/app/src/main/res/layout/adapter_secure_item.xml
@@ -33,7 +33,7 @@
android:layout_height="22dp"
android:layout_marginLeft="5dp"
android:layout_weight="1"
- android:background="@drawable/ff029a45_2round_1stroke_bg"
+ android:background="@drawable/ff029a45_4round_1stroke_bg"
android:orientation="vertical">
diff --git a/app/src/main/res/layout/dialog_point_fly.xml b/app/src/main/res/layout/dialog_point_fly.xml
index dc50d07..f6e5279 100644
--- a/app/src/main/res/layout/dialog_point_fly.xml
+++ b/app/src/main/res/layout/dialog_point_fly.xml
@@ -92,6 +92,7 @@
android:layout_height="wrap_content"/>
+ android:background="@drawable/ff029a45_4round_1stroke_bg"/>
+ android:background="@drawable/ff029a45_4round_1stroke_bg"/>
+ android:background="@drawable/ff029a45_4round_1stroke_bg"/>
+ android:background="@drawable/ff029a45_4round_1stroke_bg"/>
+ android:background="@drawable/ff029a45_4round_1stroke_bg"/>
+ android:background="@drawable/ff029a45_4round_1stroke_bg"/>
+ android:background="@drawable/ff029a45_4round_1stroke_bg"/>
+ android:background="@drawable/ff029a45_4round_1stroke_bg"/>
+ android:background="@drawable/ff029a45_4round_1stroke_bg"/>
+ android:background="@drawable/ff029a45_4round_1stroke_bg"/>
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_load.xml b/app/src/main/res/layout/fragment_load.xml
index b6473cf..e3e7fad 100644
--- a/app/src/main/res/layout/fragment_load.xml
+++ b/app/src/main/res/layout/fragment_load.xml
@@ -134,7 +134,7 @@
android:layout_height="22dp"
android:layout_marginLeft="5dp"
android:layout_weight="1"
- android:background="@drawable/ff029a45_2round_1stroke_bg"
+ android:background="@drawable/ff029a45_4round_1stroke_bg"
android:orientation="vertical">
@@ -29,7 +28,7 @@
@@ -46,6 +45,8 @@
+ android:layout_marginBottom="8dp">
+ android:background="@drawable/ff029a45_4round_1stroke_bg"/>
@@ -95,13 +96,13 @@
android:text="+"
android:textColor="#ffffff"
android:textSize="10sp"
- android:background="@drawable/ff029a45_2round_1stroke_bg"/>
+ android:background="@drawable/ff029a45_4round_1stroke_bg"/>
+ android:layout_marginBottom="7dp">
+ android:background="@drawable/ff029a45_4round_1stroke_bg"/>
+ android:progress="5" />
+ android:background="@drawable/ff029a45_4round_1stroke_bg"/>
diff --git a/app/src/main/res/layout/fragment_payload.xml b/app/src/main/res/layout/fragment_payload.xml
index afc73b8..f0e276b 100644
--- a/app/src/main/res/layout/fragment_payload.xml
+++ b/app/src/main/res/layout/fragment_payload.xml
@@ -15,7 +15,7 @@
diff --git a/app/src/main/res/layout/fragment_secure.xml b/app/src/main/res/layout/fragment_secure.xml
index f0c6951..0aafdfb 100644
--- a/app/src/main/res/layout/fragment_secure.xml
+++ b/app/src/main/res/layout/fragment_secure.xml
@@ -76,7 +76,7 @@
android:text="-"
android:textColor="#ffffff"
android:textSize="10sp"
- android:background="@drawable/ff029a45_2round_1stroke_bg"/>
+ android:background="@drawable/ff029a45_4round_1stroke_bg"/>
+ android:background="@drawable/ff029a45_4round_1stroke_bg"/>
+ android:background="@drawable/ff029a45_4round_1stroke_bg"/>
+ android:background="@drawable/ff029a45_4round_1stroke_bg"/>
+ android:background="@drawable/ff029a45_4round_1stroke_bg"/>
+ android:background="@drawable/ff029a45_4round_1stroke_bg"/>
+ android:textColor="#ffffff"
+ android:textSize="12sp" />
+ android:textColor="#ffffff"
+ android:textSize="12sp" />
+ android:textColor="#ffffff"
+ android:textSize="12sp" />
+ android:textColor="#ffffff"
+ android:textSize="12sp" />
+ android:textColor="#ffffff"
+ android:textSize="12sp" />
+ android:textColor="#ffffff"
+ android:textSize="12sp" />
+ android:textColor="#ffffff"
+ android:textSize="12sp" />
+ android:textColor="#ffffff"
+ android:textSize="12sp" />
@@ -65,29 +65,30 @@
+ android:layout_height="32dp">
@@ -96,48 +97,84 @@
android:id="@+id/tv_updata_param"
android:layout_marginRight="5dp"
android:textColor="#ffffff"
- android:background="@drawable/ff8decec_2round_bg"
+ android:background="@drawable/ff029b45_2round_bg"
android:gravity="center"
- android:textSize="12sp"
+ android:textSize="11sp"
android:padding="5dp"
android:text="重新获取参数"
- android:layout_width="100dp"
- android:layout_height="wrap_content"/>
+ android:layout_width="84dp"
+ android:layout_height="28dp"/>
+ android:layout_height="28dp"/>
+ android:layout_height="28dp"/>
-
-
+ android:layout_height="match_parent">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -145,8 +182,9 @@