最新版(航线保存,航线执行,投弹,设置-载荷,安全,遥控器..页面基本完成)
4
.idea/deploymentTargetSelector.xml
generated
@ -4,10 +4,10 @@
|
||||
<selectionStates>
|
||||
<SelectionState runConfigName="app">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
<DropdownSelection timestamp="2025-06-27T06:06:37.137599900Z">
|
||||
<DropdownSelection timestamp="2025-08-18T01:38:39.489587200Z">
|
||||
<Target type="DEFAULT_BOOT">
|
||||
<handle>
|
||||
<DeviceId pluginId="PhysicalDevice" identifier="serial=235cb949" />
|
||||
<DeviceId pluginId="PhysicalDevice" identifier="serial=3571a890" />
|
||||
</handle>
|
||||
</Target>
|
||||
</DropdownSelection>
|
||||
|
||||
@ -69,6 +69,9 @@ dependencies {
|
||||
implementation files("libs/rcsdk-v1.2.1.aar")
|
||||
implementation files("libs/isoparser-1.1.9.jar")//用于H264封装为MP4
|
||||
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.10.0'
|
||||
implementation 'com.squareup.okio:okio:3.2.0'
|
||||
|
||||
|
||||
|
||||
// implementation 'com.github.licheedev.Android-SerialPort-API:serialport:2.0.0'
|
||||
|
||||
@ -18,30 +18,26 @@
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
android:hardwareAccelerated="true"
|
||||
android:icon="@mipmap/logo"
|
||||
android:label="LYUAV"
|
||||
android:roundIcon="@mipmap/logo"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.LongYiGroundStation"
|
||||
tools:targetApi="31"
|
||||
android:hardwareAccelerated="true">
|
||||
|
||||
|
||||
tools:targetApi="31">
|
||||
<activity
|
||||
android:name=".Main.Activity.PlayBackActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".Funcation.Activity.FuncationActivity"
|
||||
android:exported="true" >
|
||||
</activity>
|
||||
|
||||
android:exported="true"></activity>
|
||||
<activity
|
||||
android:name=".Main.Setting.Activity.SettingActivity"
|
||||
android:exported="true" >
|
||||
|
||||
|
||||
</activity>
|
||||
|
||||
android:exported="true"></activity>
|
||||
<activity
|
||||
android:name=".MainActivity2"
|
||||
android:exported="true"></activity>
|
||||
android:exported="true"
|
||||
android:screenOrientation="landscape"></activity>
|
||||
|
||||
<meta-data
|
||||
android:name="com.amap.api.v2.apikey"
|
||||
@ -52,13 +48,11 @@
|
||||
android:name=".Login.Activity.LoginActivity"
|
||||
android:exported="true"
|
||||
android:screenOrientation="landscape">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".Main.Activity.MainActivity"
|
||||
|
||||
@ -75,6 +75,7 @@ public class FuncationActivity extends AppCompatActivity {
|
||||
intents.putExtra("port", intent.getStringExtra("port"));
|
||||
}
|
||||
startActivity(intents);
|
||||
finish();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@ -12,6 +12,9 @@ import com.example.longyi_groundstation.MAVLink.Messages.MAVLinkPayload;
|
||||
import com.example.longyi_groundstation.MAVLink.Messages.Units;
|
||||
import com.example.longyi_groundstation.MAVLink.Messages.Description;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
/**
|
||||
* Reports the current commanded attitude of the vehicle as specified by the autopilot. This should match the commands sent in a SET_ATTITUDE_TARGET message if the vehicle is being controlled this way.
|
||||
*/
|
||||
@ -189,7 +192,37 @@ public class msg_attitude_target extends MAVLinkMessage {
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MAVLINK_MSG_ID_ATTITUDE_TARGET - sysid:"+sysid+" compid:"+compid+" time_boot_ms:"+time_boot_ms+" q:"+q+" body_roll_rate:"+body_roll_rate+" body_pitch_rate:"+body_pitch_rate+" body_yaw_rate:"+body_yaw_rate+" thrust:"+thrust+" type_mask:"+type_mask+"";
|
||||
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
try {
|
||||
jsonObject.put("msgid",MAVLINK_MSG_ID_ATTITUDE_TARGET);
|
||||
jsonObject.put("sysid",sysid);
|
||||
jsonObject.put("compid",compid);
|
||||
jsonObject.put("time_boot_ms",time_boot_ms);
|
||||
jsonObject.put("q",q);
|
||||
jsonObject.put("body_roll_rate",body_roll_rate);
|
||||
jsonObject.put("body_pitch_rate",body_pitch_rate);
|
||||
jsonObject.put("body_yaw_rate",body_yaw_rate);
|
||||
jsonObject.put("thrust",thrust);
|
||||
jsonObject.put("type_mask",type_mask);
|
||||
|
||||
return jsonObject.toString();
|
||||
} catch (JSONException e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// return "MAVLINK_MSG_ID_ATTITUDE_TARGET - sysid:"+
|
||||
// sysid+" compid:"+
|
||||
// compid+" time_boot_ms:"+
|
||||
// time_boot_ms+" q:"+
|
||||
// q+" body_roll_rate:"+
|
||||
// body_roll_rate+" body_pitch_rate:"+
|
||||
// body_pitch_rate+" body_yaw_rate:"+
|
||||
// body_yaw_rate+" thrust:"+
|
||||
// thrust+" type_mask:"+
|
||||
// type_mask+"";
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -0,0 +1,87 @@
|
||||
package com.example.longyi_groundstation.Main.Activity;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.activity.EdgeToEdge;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.graphics.Insets;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
|
||||
import com.example.longyi_groundstation.Main.View.CustomSeekBar;
|
||||
import com.example.longyi_groundstation.Main.Void.MyTool;
|
||||
import com.example.longyi_groundstation.R;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
public class PlayBackActivity extends AppCompatActivity {
|
||||
|
||||
|
||||
// 在类成员变量中添加
|
||||
private CustomSeekBar customSeekBar;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
EdgeToEdge.enable(this);
|
||||
setContentView(R.layout.activity_play_back);
|
||||
MyTool.hideBottomNavigationBar(this);
|
||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
|
||||
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
|
||||
return insets;
|
||||
});
|
||||
|
||||
initData();
|
||||
initView();
|
||||
initOnClick();
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法:初始化数据
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initData() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法:初始化视图
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initView() {
|
||||
// 初始化自定义进度条
|
||||
customSeekBar = findViewById(R.id.custom_seekbar);
|
||||
|
||||
// 设置默认进度(例如50%)
|
||||
customSeekBar.setProgress(0.5f);
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法:初始化点击事件
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initOnClick() {
|
||||
// 设置进度变化监听器
|
||||
customSeekBar.setOnProgressChangeListener(new CustomSeekBar.OnProgressChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(float progress) {
|
||||
// 这里可以获取到保留两位小数的进度值
|
||||
// 例如:如果进度是0.1099,会显示为10.99%
|
||||
BigDecimal bd = new BigDecimal(progress * 100);
|
||||
bd = bd.setScale(2, RoundingMode.HALF_UP);
|
||||
String progressText = bd.toString() + "%";
|
||||
|
||||
// 可以在这里处理进度变化的逻辑
|
||||
Log.d("CustomSeekBar", "Progress: " + progressText);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,150 @@
|
||||
package com.example.longyi_groundstation.Main.Adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.example.longyi_groundstation.Main.Base.CreateLink;
|
||||
import com.example.longyi_groundstation.Main.Void.SQLClass;
|
||||
import com.example.longyi_groundstation.R;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class AllLinkAdapter extends RecyclerView.Adapter<AllLinkAdapter.AllLinkViewHolder> {
|
||||
private static final String TAG = "AllLinkAdapter";
|
||||
|
||||
private Context context;
|
||||
private List<SQLClass.LinkListInfo> linkListInfoList;
|
||||
private SQLClass sqlClass;
|
||||
private OnItemClickListener onItemClickListener;
|
||||
|
||||
public AllLinkAdapter(Context context, List<SQLClass.LinkListInfo> linkListInfoList, SQLClass sqlClass) {
|
||||
this.context = context;
|
||||
this.linkListInfoList = linkListInfoList;
|
||||
this.sqlClass = sqlClass;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public AllLinkViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_all_link_item, parent, false);
|
||||
return new AllLinkViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull AllLinkViewHolder holder, int position) {
|
||||
SQLClass.LinkListInfo linkListInfo = linkListInfoList.get(position);
|
||||
|
||||
// 显示航线名称
|
||||
holder.tv_title.setText(linkListInfo.getListName());
|
||||
|
||||
// 显示创建时间
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault());
|
||||
String createTime = sdf.format(new Date(linkListInfo.getCreatedTime()));
|
||||
holder.tv_time.setText(createTime);
|
||||
|
||||
// 获取点位数量
|
||||
ArrayList<CreateLink> createLinkList = sqlClass.getCreateLinkList(linkListInfo.getListId());
|
||||
int waypointCount = (createLinkList != null) ? createLinkList.size() : 0;
|
||||
holder.tv_number.setText( waypointCount+"个");
|
||||
|
||||
// 设置删除按钮点击事件
|
||||
holder.tv_del.setOnClickListener(v -> {
|
||||
deleteLinkList(position);
|
||||
List<SQLClass.LinkListInfo> updatedList = sqlClass.getAllLinkListInfo();
|
||||
updateDataList(updatedList);
|
||||
});
|
||||
|
||||
// 设置整个item的点击事件
|
||||
holder.itemView.setOnClickListener(v -> {
|
||||
if (onItemClickListener != null) {
|
||||
onItemClickListener.onItemClick(linkListInfo.getListId(), position);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return linkListInfoList != null ? linkListInfoList.size() : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除指定位置的航线列表
|
||||
* @param position 要删除的位置
|
||||
*/
|
||||
private void deleteLinkList(int position) {
|
||||
if (position < 0 || position >= linkListInfoList.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
SQLClass.LinkListInfo linkListInfo = linkListInfoList.get(position);
|
||||
int listId = linkListInfo.getListId();
|
||||
|
||||
// 从数据库中删除
|
||||
boolean isDeleted = sqlClass.deleteCreateLinkList(listId);
|
||||
|
||||
if (isDeleted) {
|
||||
// 从列表中移除
|
||||
linkListInfoList.remove(position);
|
||||
// 通知适配器数据已更改
|
||||
notifyItemRemoved(position);
|
||||
notifyItemRangeChanged(position, linkListInfoList.size());
|
||||
|
||||
Toast.makeText(context, "航线删除成功", Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Log.e(TAG, "删除航线失败,列表ID: " + listId);
|
||||
Toast.makeText(context, "航线删除失败", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新数据列表
|
||||
* @param newLinkListInfoList 新的数据列表
|
||||
*/
|
||||
public void updateDataList(List<SQLClass.LinkListInfo> newLinkListInfoList) {
|
||||
this.linkListInfoList = newLinkListInfoList;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置item点击监听器
|
||||
* @param listener 监听器
|
||||
*/
|
||||
public void setOnItemClickListener(OnItemClickListener listener) {
|
||||
this.onItemClickListener = listener;
|
||||
}
|
||||
|
||||
static class AllLinkViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView tv_title;
|
||||
TextView tv_time;
|
||||
TextView tv_number;
|
||||
TextView tv_del;
|
||||
|
||||
public AllLinkViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
tv_title = itemView.findViewById(R.id.tv_title);
|
||||
tv_time = itemView.findViewById(R.id.tv_time);
|
||||
tv_number = itemView.findViewById(R.id.tv_number);
|
||||
tv_del = itemView.findViewById(R.id.tv_del);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Item点击监听器接口
|
||||
*/
|
||||
public interface OnItemClickListener {
|
||||
void onItemClick(int listId, int position);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,108 @@
|
||||
// 文件: CreateLinkAdapter.java
|
||||
package com.example.longyi_groundstation.Main.Adapter;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.example.longyi_groundstation.Main.Base.CreateLink;
|
||||
import com.example.longyi_groundstation.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CreateLinkAdapter extends RecyclerView.Adapter<CreateLinkAdapter.ViewHolder> {
|
||||
private List<CreateLink> createLinkList;
|
||||
private OnItemClickListener onItemClickListener;
|
||||
|
||||
public interface OnItemClickListener {
|
||||
void onDeleteClick(int position);
|
||||
}
|
||||
|
||||
public CreateLinkAdapter() {
|
||||
this.createLinkList = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void setOnItemClickListener(OnItemClickListener listener) {
|
||||
this.onItemClickListener = listener;
|
||||
}
|
||||
|
||||
public void setCreateLinkList(List<CreateLink> createLinkList) {
|
||||
this.createLinkList = createLinkList;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public List<CreateLink> getCreateLinkList() {
|
||||
return createLinkList;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_create_link_item, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
CreateLink createLink = createLinkList.get(position);
|
||||
holder.bind(createLink, position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return createLinkList.size();
|
||||
}
|
||||
|
||||
public class ViewHolder extends RecyclerView.ViewHolder {
|
||||
private TextView tvDel,tv_title;
|
||||
private EditText etHeight;
|
||||
private EditText etSpeed;
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
tvDel = itemView.findViewById(R.id.tv_del);
|
||||
tv_title = itemView.findViewById(R.id.tv_title);
|
||||
etHeight = itemView.findViewById(R.id.et_height);
|
||||
etSpeed = itemView.findViewById(R.id.et_speed);
|
||||
}
|
||||
|
||||
public void bind(CreateLink createLink, int position) {
|
||||
etHeight.setText(String.valueOf((int) createLink.getHeight()));
|
||||
etSpeed.setText(String.valueOf((int) createLink.getSpeed()));
|
||||
tv_title.setText(createLink.getName());
|
||||
|
||||
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()));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
etSpeed.setOnFocusChangeListener((v, hasFocus) -> {
|
||||
if (!hasFocus) {
|
||||
try {
|
||||
createLink.setSpeed(Double.parseDouble(etSpeed.getText().toString()));
|
||||
} catch (NumberFormatException e) {
|
||||
etSpeed.setText(String.valueOf((int) createLink.getSpeed()));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -43,26 +43,46 @@ public class TypeAdapter extends RecyclerView.Adapter<TypeAdapter.TypeViewHolder
|
||||
|
||||
case "relative_alt":
|
||||
holder.textView.setText("融合高度:" + (Integer.parseInt(item.getMsg()) / 1000) + " m");
|
||||
holder.textView.setMaxWidth(Integer.MAX_VALUE); // 移除最大宽度限制
|
||||
holder.textView.setMinimumWidth(0); // 移除最小宽度限制
|
||||
break;
|
||||
|
||||
case "alt":
|
||||
holder.textView.setText("海拔高度:" + (Integer.parseInt(item.getMsg()) / 1000) + " m");
|
||||
holder.textView.setMaxWidth(Integer.MAX_VALUE); // 移除最大宽度限制
|
||||
holder.textView.setMinimumWidth(0); // 移除最小宽度限制
|
||||
break;
|
||||
|
||||
case "time_boot_ms":
|
||||
holder.textView.setText("飞行时间:" + Tool.formatMillisecondsLong(Long.parseLong(item.getMsg())));
|
||||
holder.textView.setMaxWidth(Integer.MAX_VALUE); // 移除最大宽度限制
|
||||
holder.textView.setMinimumWidth(0); // 移除最小宽度限制
|
||||
break;
|
||||
|
||||
case "lat":
|
||||
holder.textView.setText("纬度:" + item.getMsg());
|
||||
// 设置纬度显示的最大宽度,确保能完整显示坐标值
|
||||
holder.textView.setMaxWidth(Integer.MAX_VALUE);
|
||||
holder.textView.setMinimumWidth(400); // 设置最小宽度确保足够显示
|
||||
break;
|
||||
|
||||
case "lon":
|
||||
holder.textView.setText("经度:" + item.getMsg());
|
||||
// 设置经度显示的最大宽度,确保能完整显示坐标值
|
||||
holder.textView.setMaxWidth(Integer.MAX_VALUE);
|
||||
holder.textView.setMinimumWidth(400); // 设置最小宽度确保足够显示
|
||||
break;
|
||||
|
||||
case "throttle":
|
||||
holder.textView.setText("油门量:" + item.getMsg());
|
||||
holder.textView.setMaxWidth(Integer.MAX_VALUE); // 移除最大宽度限制
|
||||
holder.textView.setMinimumWidth(0); // 移除最小宽度限制
|
||||
break;
|
||||
|
||||
default:
|
||||
holder.textView.setText("距家距离:"+item.getMsg());
|
||||
holder.textView.setMaxWidth(Integer.MAX_VALUE); // 移除最大宽度限制
|
||||
holder.textView.setMinimumWidth(0); // 移除最小宽度限制
|
||||
break;
|
||||
|
||||
}
|
||||
@ -72,9 +92,9 @@ public class TypeAdapter extends RecyclerView.Adapter<TypeAdapter.TypeViewHolder
|
||||
}else {
|
||||
holder.ll_main.setVisibility(GONE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return dataList.size();
|
||||
|
||||
@ -0,0 +1,60 @@
|
||||
// 文件: CreateLink.java
|
||||
package com.example.longyi_groundstation.Main.Base;
|
||||
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
|
||||
public class CreateLink {
|
||||
private String name;
|
||||
private double height;
|
||||
private double speed;
|
||||
private int waypointIndex;
|
||||
private LatLng latLng;
|
||||
|
||||
public CreateLink(String name, double height, double speed, int waypointIndex, LatLng latLng) {
|
||||
this.name = name;
|
||||
this.height = height;
|
||||
this.speed = speed;
|
||||
this.waypointIndex = waypointIndex;
|
||||
this.latLng = latLng;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public double getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(double height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public double getSpeed() {
|
||||
return speed;
|
||||
}
|
||||
|
||||
public void setSpeed(double speed) {
|
||||
this.speed = speed;
|
||||
}
|
||||
|
||||
public int getWaypointIndex() {
|
||||
return waypointIndex;
|
||||
}
|
||||
|
||||
public void setWaypointIndex(int waypointIndex) {
|
||||
this.waypointIndex = waypointIndex;
|
||||
}
|
||||
|
||||
public LatLng getLatLng() {
|
||||
return latLng;
|
||||
}
|
||||
|
||||
public void setLatLng(LatLng latLng) {
|
||||
this.latLng = latLng;
|
||||
}
|
||||
}
|
||||
@ -1,16 +1,22 @@
|
||||
package com.example.longyi_groundstation.Main.Service;
|
||||
|
||||
import static com.example.longyi_groundstation.MAVLink.common.msg_attitude.MAVLINK_MSG_ID_ATTITUDE;
|
||||
import static com.example.longyi_groundstation.MAVLink.common.msg_attitude_target.MAVLINK_MSG_ID_ATTITUDE_TARGET;
|
||||
import static com.example.longyi_groundstation.MAVLink.common.msg_global_position_int.MAVLINK_MSG_ID_GLOBAL_POSITION_INT;
|
||||
import static com.example.longyi_groundstation.MAVLink.common.msg_gps_raw_int.MAVLINK_MSG_ID_GPS_RAW_INT;
|
||||
import static com.example.longyi_groundstation.MAVLink.common.msg_param_request_list.MAVLINK_MSG_ID_PARAM_REQUEST_LIST;
|
||||
import static com.example.longyi_groundstation.MAVLink.common.msg_param_request_read.MAVLINK_MSG_ID_PARAM_REQUEST_READ;
|
||||
import static com.example.longyi_groundstation.MAVLink.common.msg_param_value.MAVLINK_MSG_ID_PARAM_VALUE;
|
||||
import static com.example.longyi_groundstation.MAVLink.common.msg_power_status.MAVLINK_MSG_ID_POWER_STATUS;
|
||||
import static com.example.longyi_groundstation.MAVLink.common.msg_rc_channels.MAVLINK_MSG_ID_RC_CHANNELS;
|
||||
import static com.example.longyi_groundstation.MAVLink.common.msg_rc_channels_raw.MAVLINK_MSG_ID_RC_CHANNELS_RAW;
|
||||
import static com.example.longyi_groundstation.MAVLink.common.msg_statustext.MAVLINK_MSG_ID_STATUSTEXT;
|
||||
import static com.example.longyi_groundstation.MAVLink.common.msg_sys_status.MAVLINK_MSG_ID_SYS_STATUS;
|
||||
import static com.example.longyi_groundstation.MAVLink.common.msg_vfr_hud.MAVLINK_MSG_ID_VFR_HUD;
|
||||
import static com.example.longyi_groundstation.MAVLink.enums.MAV_DATA_STREAM.MAV_DATA_STREAM_ALL;
|
||||
import static com.example.longyi_groundstation.MAVLink.minimal.msg_heartbeat.MAVLINK_MSG_ID_HEARTBEAT;
|
||||
import static com.example.longyi_groundstation.Main.Void.SerialTool.bytesToHex;
|
||||
import static com.example.longyi_groundstation.Main.Void.SerialTool.parseSerialData;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
@ -31,6 +37,7 @@ 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.LogCat.LogUtil;
|
||||
import com.example.longyi_groundstation.Main.Void.MyTool;
|
||||
import com.example.longyi_groundstation.Util.BroadcastUtil;
|
||||
import com.example.longyi_groundstation.Util.Tool;
|
||||
@ -61,6 +68,8 @@ public class MyBoundService extends Service {
|
||||
private static final String TAG = "UDPServer";
|
||||
private TextView tv_text;
|
||||
public static DatagramSocket serverSocket;
|
||||
public static DatagramSocket serverSocket2;
|
||||
|
||||
private boolean isRunning = false;
|
||||
private String serverPort = "14551"; // 服务端监听端口
|
||||
|
||||
@ -99,7 +108,7 @@ public class MyBoundService extends Service {
|
||||
}
|
||||
|
||||
|
||||
public static SerialHelper serialHelper;
|
||||
public static SerialHelper serialHelper, serialHelper2;
|
||||
private Parser parser = new Parser();
|
||||
private MAVLinkMessage msgOld = null;
|
||||
|
||||
@ -173,9 +182,67 @@ public class MyBoundService extends Service {
|
||||
wordT();
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法:连接串口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);
|
||||
}
|
||||
};
|
||||
try {
|
||||
serialHelper2.open();
|
||||
// wordT1();
|
||||
} catch (IOException e) {
|
||||
// throw new RuntimeException(e);
|
||||
Log.d(TAG, e.toString());
|
||||
}
|
||||
}else {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
serverSocket2 = new DatagramSocket(13551);
|
||||
byte[] buffer = new byte[1024];
|
||||
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);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "接收数据错误: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
} catch (SocketException e) {
|
||||
Log.e(TAG, "启动服务端失败: " + e.getMessage());
|
||||
|
||||
} finally {
|
||||
stopUdpServer();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送请求姿态数据的MAVLink指令
|
||||
* 方法:发送请求姿态数据的MAVLink指令
|
||||
*/
|
||||
public void requestAttitudeData() {
|
||||
// 构造REQUEST_DATA_STREAM消息
|
||||
@ -268,6 +335,8 @@ public class MyBoundService extends Service {
|
||||
//判断当前索引下的数据是否有变动,如过没有变动,就不储存,用一个判断增加性能
|
||||
if (!msg.toString().equals(MsgList.get(msg.msgid))) {
|
||||
// Log.d("cuijigzhou_msg_all", msg.toString());
|
||||
LogUtil.d("cuijigzhou_msg_all", msg.toString());
|
||||
|
||||
|
||||
MsgList.set(msg.msgid, msg.toString());
|
||||
if (msgOld == null) {
|
||||
@ -279,7 +348,6 @@ public class MyBoundService extends Service {
|
||||
msgOld = msg;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -313,6 +381,16 @@ public class MyBoundService extends Service {
|
||||
if (MsgList.get(MAVLINK_MSG_ID_HEARTBEAT) != null) {
|
||||
BroadcastUtil.Broadcast_HEARTBEAT(getApplication(), MsgList.get(MAVLINK_MSG_ID_HEARTBEAT));
|
||||
}
|
||||
if (MsgList.get(MAVLINK_MSG_ID_RC_CHANNELS) != null) {
|
||||
BroadcastUtil.Broadcast_RC_CHANNELS(getApplication(), MsgList.get(MAVLINK_MSG_ID_RC_CHANNELS));
|
||||
}
|
||||
if (MsgList.get(MAVLINK_MSG_ID_RC_CHANNELS_RAW) != null) {
|
||||
BroadcastUtil.Broadcast_RC_CHANNELS_RAW(getApplication(), MsgList.get(MAVLINK_MSG_ID_RC_CHANNELS_RAW));
|
||||
}
|
||||
if (MsgList.get(MAVLINK_MSG_ID_VFR_HUD) != null) {
|
||||
// Log.e("MAVLINK_MSG_ID_ATTITUDE_TARGET", 1+"");
|
||||
BroadcastUtil.Broadcast_VFR_HUD(getApplication(), MsgList.get(MAVLINK_MSG_ID_VFR_HUD));
|
||||
}
|
||||
|
||||
Thread.sleep(50);
|
||||
}
|
||||
@ -354,7 +432,6 @@ public class MyBoundService extends Service {
|
||||
FlyVoid.setParamUpdateComplete(false);
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
// Log.d("cuijigzhou_msg_all_id", "不做处理:"+msg.msgid);
|
||||
|
||||
@ -384,6 +461,7 @@ public class MyBoundService extends Service {
|
||||
// 初始化服务逻辑
|
||||
initList();
|
||||
getData();
|
||||
getDataSerial();
|
||||
|
||||
|
||||
return binder;
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
// SettingActivity.java
|
||||
package com.example.longyi_groundstation.Main.Setting.Activity;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.ProgressDialog;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.widget.Toast;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.activity.EdgeToEdge;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
@ -29,7 +32,6 @@ import com.example.longyi_groundstation.R;
|
||||
public class SettingActivity extends AppCompatActivity {
|
||||
private FlyVoid flyVoid = new FlyVoid();
|
||||
private AllView allView;
|
||||
|
||||
private FoundationFragment foundationFragment;
|
||||
private ControlFragment controlFragment;
|
||||
private FlyFragment flyFragment;
|
||||
@ -39,9 +41,30 @@ public class SettingActivity extends AppCompatActivity {
|
||||
private SensorFragment sensorFragment;
|
||||
private SettingsFragment settingsFragment;
|
||||
|
||||
// 添加参数加载对话框
|
||||
private ProgressDialog paramLoadingDialog;
|
||||
|
||||
// 添加Handler引用以便在销毁时移除回调
|
||||
private Handler uiHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
// 添加参数更新检查的Runnable
|
||||
private Runnable paramUpdateChecker = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (FlyVoid.isParamUpdateComplete()) {
|
||||
// 参数更新完成,关闭对话框并初始化界面
|
||||
if (paramLoadingDialog != null && paramLoadingDialog.isShowing()) {
|
||||
paramLoadingDialog.dismiss();
|
||||
}
|
||||
initView();
|
||||
initOnClick();
|
||||
} else {
|
||||
// 参数未更新完成,继续等待并定期检查
|
||||
uiHandler.postDelayed(this, 500); // 500毫秒后再次检查
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//广播接收器
|
||||
|
||||
@Override
|
||||
@ -49,20 +72,35 @@ public class SettingActivity extends AppCompatActivity {
|
||||
super.onCreate(savedInstanceState);
|
||||
EdgeToEdge.enable(this);
|
||||
setContentView(R.layout.activity_setting);
|
||||
View decorView = getWindow().getDecorView();
|
||||
decorView.setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_FULLSCREEN // 隐藏状态栏
|
||||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY // 启用沉浸式粘滞模式
|
||||
);
|
||||
// 设置导航栏背景为黑色
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
|
||||
getWindow().setNavigationBarColor(Color.BLACK);
|
||||
}
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
|
||||
|
||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
|
||||
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
|
||||
return insets;
|
||||
});
|
||||
|
||||
MyTool.hideBottomNavigationBar(this);
|
||||
initData();
|
||||
|
||||
|
||||
if (FlyVoid.isParamUpdateComplete()){
|
||||
initView();
|
||||
initOnClick();
|
||||
} else {
|
||||
// 显示参数加载对话框
|
||||
showParamLoadingDialog();
|
||||
// 开始检查参数更新状态
|
||||
uiHandler.postDelayed(paramUpdateChecker, 500);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 方法:初始化数据
|
||||
*
|
||||
@ -81,38 +119,12 @@ public class SettingActivity extends AppCompatActivity {
|
||||
private void initView() {
|
||||
allView = new AllView(this);
|
||||
|
||||
// 预加载所有 Fragment
|
||||
// 只预加载默认的 MotorFragment
|
||||
androidx.fragment.app.FragmentManager fragmentManager = getSupportFragmentManager();
|
||||
androidx.fragment.app.FragmentTransaction transaction = fragmentManager.beginTransaction();
|
||||
|
||||
foundationFragment = new FoundationFragment();
|
||||
controlFragment = new ControlFragment();
|
||||
flyFragment = new FlyFragment();
|
||||
secureFragment = new SecureFragment();
|
||||
motorFragment = new MotorFragment();
|
||||
loadFragment = new LoadFragment();
|
||||
sensorFragment = new SensorFragment();
|
||||
settingsFragment = new SettingsFragment();
|
||||
|
||||
// 添加所有 Fragment,但只显示默认的 MotorFragment
|
||||
transaction.add(R.id.fragment_container, motorFragment, "MotorFragment")
|
||||
.add(R.id.fragment_container, foundationFragment, "FoundationFragment")
|
||||
.add(R.id.fragment_container, controlFragment, "ControlFragment")
|
||||
.add(R.id.fragment_container, flyFragment, "FlyFragment")
|
||||
.add(R.id.fragment_container, secureFragment, "SecureFragment")
|
||||
.add(R.id.fragment_container, loadFragment, "LoadFragment")
|
||||
.add(R.id.fragment_container, sensorFragment, "SensorFragment")
|
||||
.add(R.id.fragment_container, settingsFragment, "SettingsFragment");
|
||||
|
||||
// 隐藏除 MotorFragment 外的其他 Fragment
|
||||
transaction.hide(motorFragment)
|
||||
.hide(controlFragment)
|
||||
.hide(flyFragment)
|
||||
.hide(secureFragment)
|
||||
.hide(loadFragment)
|
||||
.hide(sensorFragment)
|
||||
.hide(settingsFragment);
|
||||
|
||||
transaction.add(R.id.fragment_container, foundationFragment, "FoundationFragment");
|
||||
transaction.commit();
|
||||
}
|
||||
|
||||
@ -122,19 +134,6 @@ public class SettingActivity extends AppCompatActivity {
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initOnClick() {
|
||||
|
||||
// msg_param_set paramSet = new msg_param_set();
|
||||
// paramSet.target_system = 1; // 目标系统ID (飞控)
|
||||
// paramSet.target_component = 1; // 目标组件ID
|
||||
// String paramId = "RTL_OPTIONS";
|
||||
// // 设置参数ID (最多16字符)
|
||||
// byte[] paramIdBytes = paramId.getBytes();
|
||||
// System.arraycopy(paramIdBytes, 0, paramSet.param_id, 0, Math.min(paramIdBytes.length, 16));
|
||||
// paramSet.param_value = Float.parseFloat("0");// 参数值
|
||||
// paramSet.param_type = 1; // 参数类型
|
||||
// // 发送命令
|
||||
// flyVoid.sendMavlinkMessage(MyBoundService.type,paramSet);
|
||||
|
||||
allView.iv_back.setOnClickListener(v -> {
|
||||
finish();
|
||||
});
|
||||
@ -145,7 +144,6 @@ public class SettingActivity extends AppCompatActivity {
|
||||
selectItem(finalI);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -175,59 +173,117 @@ public class SettingActivity extends AppCompatActivity {
|
||||
androidx.fragment.app.FragmentManager fragmentManager = getSupportFragmentManager();
|
||||
androidx.fragment.app.FragmentTransaction transaction = fragmentManager.beginTransaction();
|
||||
|
||||
// 隐藏所有 Fragment
|
||||
transaction.hide(foundationFragment)
|
||||
.hide(controlFragment)
|
||||
.hide(flyFragment)
|
||||
.hide(secureFragment)
|
||||
.hide(motorFragment)
|
||||
.hide(loadFragment)
|
||||
.hide(sensorFragment)
|
||||
.hide(settingsFragment);
|
||||
// 隐藏当前显示的Fragment
|
||||
if (foundationFragment != null && foundationFragment.isVisible()) {
|
||||
transaction.hide(foundationFragment);
|
||||
}
|
||||
if (controlFragment != null && controlFragment.isVisible()) {
|
||||
transaction.hide(controlFragment);
|
||||
}
|
||||
if (flyFragment != null && flyFragment.isVisible()) {
|
||||
transaction.hide(flyFragment);
|
||||
}
|
||||
if (secureFragment != null && secureFragment.isVisible()) {
|
||||
transaction.hide(secureFragment);
|
||||
}
|
||||
if (motorFragment != null && motorFragment.isVisible()) {
|
||||
transaction.hide(motorFragment);
|
||||
}
|
||||
if (loadFragment != null && loadFragment.isVisible()) {
|
||||
transaction.hide(loadFragment);
|
||||
}
|
||||
if (sensorFragment != null && sensorFragment.isVisible()) {
|
||||
transaction.hide(sensorFragment);
|
||||
}
|
||||
if (settingsFragment != null && settingsFragment.isVisible()) {
|
||||
transaction.hide(settingsFragment);
|
||||
}
|
||||
|
||||
// 根据 index 显示对应的 Fragment
|
||||
// 根据 index 动态加载并显示对应的 Fragment
|
||||
switch (index) {
|
||||
case 0:
|
||||
transaction.show(foundationFragment);
|
||||
if (foundationFragment == null) {
|
||||
foundationFragment = new FoundationFragment();
|
||||
transaction.add(R.id.fragment_container, foundationFragment, "FoundationFragment");
|
||||
} else {
|
||||
transaction.show(foundationFragment);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
transaction.show(controlFragment);
|
||||
if (controlFragment == null) {
|
||||
controlFragment = new ControlFragment();
|
||||
transaction.add(R.id.fragment_container, controlFragment, "ControlFragment");
|
||||
} else {
|
||||
transaction.show(controlFragment);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
transaction.show(flyFragment);
|
||||
if (flyFragment == null) {
|
||||
flyFragment = new FlyFragment();
|
||||
transaction.add(R.id.fragment_container, flyFragment, "FlyFragment");
|
||||
} else {
|
||||
transaction.show(flyFragment);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
transaction.show(secureFragment);
|
||||
if (secureFragment == null) {
|
||||
secureFragment = new SecureFragment();
|
||||
transaction.add(R.id.fragment_container, secureFragment, "SecureFragment");
|
||||
} else {
|
||||
transaction.show(secureFragment);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
transaction.show(motorFragment);
|
||||
if (motorFragment == null) {
|
||||
motorFragment = new MotorFragment();
|
||||
transaction.add(R.id.fragment_container, motorFragment, "MotorFragment");
|
||||
} else {
|
||||
transaction.show(motorFragment);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
transaction.show(loadFragment);
|
||||
if (loadFragment == null) {
|
||||
loadFragment = new LoadFragment();
|
||||
transaction.add(R.id.fragment_container, loadFragment, "LoadFragment");
|
||||
} else {
|
||||
transaction.show(loadFragment);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
transaction.show(sensorFragment);
|
||||
if (sensorFragment == null) {
|
||||
sensorFragment = new SensorFragment();
|
||||
transaction.add(R.id.fragment_container, sensorFragment, "SensorFragment");
|
||||
} else {
|
||||
transaction.show(sensorFragment);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
transaction.show(settingsFragment);
|
||||
default: // settingsFragment现在是索引7
|
||||
if (settingsFragment == null) {
|
||||
settingsFragment = new SettingsFragment();
|
||||
transaction.add(R.id.fragment_container, settingsFragment, "SettingsFragment");
|
||||
} else {
|
||||
transaction.show(settingsFragment);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
transaction.commitAllowingStateLoss(); // 使用commitAllowingStateLoss防止状态异常
|
||||
}
|
||||
|
||||
|
||||
private void initReceiver() {
|
||||
|
||||
/**
|
||||
* 显示参数加载对话框
|
||||
*/
|
||||
private void showParamLoadingDialog() {
|
||||
paramLoadingDialog = new ProgressDialog(this);
|
||||
paramLoadingDialog.setMessage("参数加载中,请稍候...");
|
||||
paramLoadingDialog.setCancelable(false); // 设置为不可取消
|
||||
paramLoadingDialog.setIndeterminate(true); // 设置为不确定进度
|
||||
paramLoadingDialog.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
initView();
|
||||
initOnClick();
|
||||
initReceiver();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
package com.example.longyi_groundstation.Main.Setting.Adapter;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||
|
||||
import com.example.longyi_groundstation.Main.Setting.Fragment.Foundation.FlyModelFragment;
|
||||
import com.example.longyi_groundstation.Main.Setting.Fragment.Foundation.FlyInstallFragment;
|
||||
import com.example.longyi_groundstation.Main.Setting.Fragment.Foundation.FlyAccelerationFragment;
|
||||
import com.example.longyi_groundstation.Main.Setting.Fragment.Foundation.FlyMagnetometerFragment;
|
||||
|
||||
public class FoundationPagerAdapter extends FragmentStateAdapter {
|
||||
|
||||
public FoundationPagerAdapter(FragmentActivity fragmentActivity) {
|
||||
super(fragmentActivity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment createFragment(int position) {
|
||||
switch (position) {
|
||||
case 0:
|
||||
return new FlyModelFragment();
|
||||
case 1:
|
||||
return new FlyInstallFragment();
|
||||
case 2:
|
||||
return new FlyAccelerationFragment();
|
||||
case 3:
|
||||
return new FlyMagnetometerFragment();
|
||||
default:
|
||||
return new FlyModelFragment();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return 4; // 四个选项卡
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,11 @@
|
||||
// 新文件:E:\AndroidProject\LongYiGroundStation\app\src\main\java\com\example\longyi_groundstation\Adapter\ParamGridAdapter.java
|
||||
package com.example.longyi_groundstation.Main.Setting.Adapter;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@ -33,29 +35,66 @@ public class ParamGridAdapter extends RecyclerView.Adapter<ParamGridAdapter.Para
|
||||
public void onBindViewHolder(@NonNull ParamViewHolder holder, int position) {
|
||||
ParamItem item = paramItems.get(position);
|
||||
holder.tvParamName.setText(item.getParamName());
|
||||
holder.tvMaxValue.setText(String.format("最大值: %s", item.getMaxValue()));
|
||||
holder.tvMinValue.setText(String.format("最小值: %s", item.getMinValue()));
|
||||
holder.tvCurrentValue.setText(String.format("%s", item.getCurrentValue()));
|
||||
holder.tvMaxDesc.setText("("+item.getMaxDesc()+")");
|
||||
holder.tvMinDesc.setText("("+item.getMinDesc()+")");
|
||||
// 限制值在1000-2000范围内
|
||||
int clampedValue = Integer.parseInt(item.getCurrentValue());
|
||||
|
||||
// 计算进度比例 (1000-2000映射到0-100%)
|
||||
// 1500为中心点,左边是1000-1500,右边是1500-2000
|
||||
if (clampedValue <= 1500) {
|
||||
// 值在左侧范围(1000-1500)
|
||||
float leftRatio = (float)(clampedValue - 1000) / 500; // 0.0 - 1.0
|
||||
float rightRatio = 1.0f;
|
||||
|
||||
// 设置权重
|
||||
LinearLayout.LayoutParams leftParams = (LinearLayout.LayoutParams) holder.leftProgress.getLayoutParams();
|
||||
LinearLayout.LayoutParams rightParams = (LinearLayout.LayoutParams) holder.rightProgress.getLayoutParams();
|
||||
|
||||
leftParams.weight = leftRatio;
|
||||
rightParams.weight = rightRatio;
|
||||
|
||||
holder.leftProgress.setLayoutParams(leftParams);
|
||||
holder.rightProgress.setLayoutParams(rightParams);
|
||||
|
||||
// 设置颜色
|
||||
holder.leftProgress.setBackgroundColor(Color.parseColor("#62a7f0")); // 蓝色
|
||||
holder.rightProgress.setBackgroundColor(Color.parseColor("#cccccc")); // 灰色
|
||||
} else {
|
||||
// 值在右侧范围(1500-2000)
|
||||
float leftRatio = 1.0f;
|
||||
float rightRatio = (float)(2000 - clampedValue) / 500; // 1.0 - 0.0
|
||||
|
||||
// 设置权重
|
||||
LinearLayout.LayoutParams leftParams = (LinearLayout.LayoutParams) holder.leftProgress.getLayoutParams();
|
||||
LinearLayout.LayoutParams rightParams = (LinearLayout.LayoutParams) holder.rightProgress.getLayoutParams();
|
||||
|
||||
leftParams.weight = leftRatio;
|
||||
rightParams.weight = rightRatio;
|
||||
|
||||
holder.leftProgress.setLayoutParams(leftParams);
|
||||
holder.rightProgress.setLayoutParams(rightParams);
|
||||
|
||||
// 设置颜色
|
||||
holder.leftProgress.setBackgroundColor(Color.parseColor("#62a7f0")); // 蓝色
|
||||
holder.rightProgress.setBackgroundColor(Color.parseColor("#cccccc")); // 灰色
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return paramItems != null ? paramItems.size() : 0;
|
||||
return paramItems.size();
|
||||
}
|
||||
|
||||
public static class ParamViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView tvParamName, tvMaxValue, tvMinValue, tvCurrentValue, tvMaxDesc, tvMinDesc;
|
||||
TextView tvParamName, tvCurrentValue;
|
||||
|
||||
View leftProgress, rightProgress;
|
||||
public ParamViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
tvParamName = itemView.findViewById(R.id.tv_param_name);
|
||||
tvMaxValue = itemView.findViewById(R.id.tv_max_value);
|
||||
tvMinValue = itemView.findViewById(R.id.tv_min_value);
|
||||
tvCurrentValue = itemView.findViewById(R.id.tv_current_value);
|
||||
tvMaxDesc = itemView.findViewById(R.id.tv_max_desc);
|
||||
tvMinDesc = itemView.findViewById(R.id.tv_min_desc);
|
||||
leftProgress = itemView.findViewById(R.id.view_left_progress);
|
||||
rightProgress = itemView.findViewById(R.id.view_right_progress);
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,5 +140,29 @@ public class ParamGridAdapter extends RecyclerView.Adapter<ParamGridAdapter.Para
|
||||
public String getMinDesc() {
|
||||
return minDesc;
|
||||
}
|
||||
|
||||
public void setParamName(String paramName) {
|
||||
this.paramName = paramName;
|
||||
}
|
||||
|
||||
public void setMaxValue(String maxValue) {
|
||||
this.maxValue = maxValue;
|
||||
}
|
||||
|
||||
public void setMinValue(String minValue) {
|
||||
this.minValue = minValue;
|
||||
}
|
||||
|
||||
public void setCurrentValue(String currentValue) {
|
||||
this.currentValue = currentValue;
|
||||
}
|
||||
|
||||
public void setMaxDesc(String maxDesc) {
|
||||
this.maxDesc = maxDesc;
|
||||
}
|
||||
|
||||
public void setMinDesc(String minDesc) {
|
||||
this.minDesc = minDesc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
package com.example.longyi_groundstation.Main.Setting.Base;
|
||||
|
||||
public class AirplaneModel {
|
||||
private int imageResId;
|
||||
private String modelName;
|
||||
|
||||
public AirplaneModel(int imageResId, String modelName) {
|
||||
this.imageResId = imageResId;
|
||||
this.modelName = modelName;
|
||||
}
|
||||
|
||||
public int getImageResId() {
|
||||
return imageResId;
|
||||
}
|
||||
|
||||
public void setImageResId(int imageResId) {
|
||||
this.imageResId = imageResId;
|
||||
}
|
||||
|
||||
public String getModelName() {
|
||||
return modelName;
|
||||
}
|
||||
|
||||
public void setModelName(String modelName) {
|
||||
this.modelName = modelName;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package com.example.longyi_groundstation.Main.Setting.Base;
|
||||
|
||||
// 在LoadFragment.java中添加这个内部类
|
||||
public class ChannelItem {
|
||||
private String text;
|
||||
private int value;
|
||||
|
||||
public ChannelItem(String text, int value) {
|
||||
this.text = text;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return text; // Spinner显示的内容
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,8 @@
|
||||
package com.example.longyi_groundstation.Main.Setting.Fragment;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
@ -7,14 +10,18 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.example.longyi_groundstation.Main.Setting.Adapter.ParamGridAdapter;
|
||||
import com.example.longyi_groundstation.Main.Void.FlyVoid;
|
||||
import com.example.longyi_groundstation.Main.Void.MyReceiver;
|
||||
import com.example.longyi_groundstation.R;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -27,8 +34,7 @@ public class ControlFragment extends Fragment {
|
||||
private ParamGridAdapter adapter;
|
||||
private FlyVoid flyVoid = new FlyVoid();
|
||||
private List<ParamGridAdapter.ParamItem> paramItems = new ArrayList<>();
|
||||
private boolean isClear = true;
|
||||
|
||||
private MyReceiver mBroadcast_RC_CHANNELS, mBroadcast_RC_CHANNELS_RAW;
|
||||
|
||||
|
||||
@Override
|
||||
@ -40,6 +46,8 @@ public class ControlFragment extends Fragment {
|
||||
initData();
|
||||
initView(view);
|
||||
initOnClick();
|
||||
initReceiver();
|
||||
|
||||
|
||||
return view;
|
||||
}
|
||||
@ -50,8 +58,16 @@ public class ControlFragment extends Fragment {
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initData() {
|
||||
adapter = new ParamGridAdapter(paramItems);
|
||||
updata();
|
||||
//开启广播监听-RC通道
|
||||
mBroadcast_RC_CHANNELS = new MyReceiver();
|
||||
IntentFilter filter8 = new IntentFilter("Broadcast_RC_CHANNELS");
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
getActivity().registerReceiver(mBroadcast_RC_CHANNELS, filter8, Context.RECEIVER_EXPORTED);
|
||||
} else {
|
||||
ContextCompat.registerReceiver(getActivity(), mBroadcast_RC_CHANNELS, filter8, ContextCompat.RECEIVER_NOT_EXPORTED);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,8 +79,10 @@ public class ControlFragment extends Fragment {
|
||||
rv_data = view.findViewById(R.id.rv_data);
|
||||
tv_calibration = view.findViewById(R.id.tv_calibration);
|
||||
|
||||
adapter = new ParamGridAdapter(paramItems);
|
||||
updata();
|
||||
// 设置GridLayoutManager,每行显示2个item
|
||||
rv_data.setLayoutManager(new GridLayoutManager(getContext(), 2));
|
||||
rv_data.setLayoutManager(new GridLayoutManager(getContext(), 3));
|
||||
rv_data.setAdapter(adapter);
|
||||
}
|
||||
|
||||
@ -77,29 +95,37 @@ public class ControlFragment extends Fragment {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法:初始化广播
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initReceiver() {
|
||||
|
||||
//广播接收-RcChannelsRawlistener
|
||||
mBroadcast_RC_CHANNELS.setRcChannelsRawlistener(data -> {
|
||||
Log.d("cuijingzhou_ctrl", data.toString());
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(data.toString());
|
||||
for (int i = 0; i < 12; i++){
|
||||
paramItems.get(i).setCurrentValue(jsonObject.optString("chan" + (i + 1) + "_raw"));
|
||||
}
|
||||
}catch (Exception e){
|
||||
Log.d("cuijingzhou_ctrl_E", e.toString());
|
||||
}
|
||||
adapter.notifyDataSetChanged();
|
||||
});
|
||||
}
|
||||
|
||||
private void updata() {
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
while (isClear){
|
||||
try {
|
||||
for (int i = 1; i <= 12; i++) {
|
||||
flyVoid.requestParamRead("RC"+i+"_MAX");
|
||||
Thread.sleep(100);
|
||||
flyVoid.requestParamRead("RC"+i+"_MIN");
|
||||
Thread.sleep(100);
|
||||
flyVoid.requestParamRead("RC"+i+"_TRIM");
|
||||
Thread.sleep(100);
|
||||
}
|
||||
if (!flyVoid.isParamUpdateComplete()){
|
||||
Thread.sleep(1000);
|
||||
getList();
|
||||
adapter.notifyDataSetChanged();
|
||||
Log.d("cuijingzhou", "一直更新");
|
||||
}
|
||||
}catch (Exception e){
|
||||
Log.d("cuijingzhou", "没事");
|
||||
}
|
||||
try {
|
||||
getList();
|
||||
adapter.notifyDataSetChanged();
|
||||
} catch (Exception e) {
|
||||
Log.d("cuijingzhou", "没事");
|
||||
}
|
||||
|
||||
}
|
||||
@ -113,7 +139,7 @@ public class ControlFragment extends Fragment {
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void getList(){
|
||||
private void getList() {
|
||||
paramItems.clear();
|
||||
// 添加数据
|
||||
paramItems.add(new ParamGridAdapter.ParamItem(
|
||||
@ -216,7 +242,6 @@ public class ControlFragment extends Fragment {
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
isClear = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -4,14 +4,41 @@ import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.example.longyi_groundstation.Main.Void.FlyVoid;
|
||||
import com.example.longyi_groundstation.R;
|
||||
|
||||
|
||||
public class FlyFragment extends Fragment {
|
||||
|
||||
private TextView tv_flight_speed_minus;
|
||||
private SeekBar seekBar_flight_speed;
|
||||
private TextView tv_flight_speed_add;
|
||||
private TextView tv_flight_speed;
|
||||
private TextView tv_climb_speed_minus;
|
||||
private SeekBar seekBar_climb_speed;
|
||||
private TextView tv_climb_speed_add;
|
||||
private TextView tv_climb_speed;
|
||||
private TextView tv_decline_speed_minus;
|
||||
private SeekBar seekBar_decline_speed;
|
||||
private TextView tv_decline_speed_add;
|
||||
private TextView tv_decline_speed;
|
||||
private TextView tv_horizontal_angle_minus;
|
||||
private SeekBar seekBar_horizontal_angle;
|
||||
private TextView tv_horizontal_angle_add;
|
||||
private TextView tv_horizontal_angle;
|
||||
private TextView tv_rotation_rate_minus;
|
||||
private SeekBar seekBar_rotation_rate;
|
||||
private TextView tv_rotation_rate_add;
|
||||
private TextView tv_rotation_rate;
|
||||
private TextView tv_save;
|
||||
private TextView tv_default;
|
||||
private FlyVoid flyVoid = new FlyVoid();
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
@ -19,10 +46,12 @@ public class FlyFragment extends Fragment {
|
||||
// Inflate the layout for this fragment
|
||||
View view = inflater.inflate(R.layout.fragment_fly, container, false);
|
||||
|
||||
initData();
|
||||
initView();
|
||||
initOnClick();
|
||||
|
||||
if (FlyVoid.isParamUpdateComplete()){
|
||||
initData();
|
||||
initView(view);
|
||||
initOnClick();
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
@ -40,7 +69,34 @@ public class FlyFragment extends Fragment {
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initView() {
|
||||
private void initView(View view) {
|
||||
tv_flight_speed_minus = view.findViewById(R.id.tv_flight_speed_minus);
|
||||
seekBar_flight_speed = view.findViewById(R.id.seekBar_flight_speed);
|
||||
tv_flight_speed_add = view.findViewById(R.id.tv_flight_speed_add);
|
||||
tv_flight_speed = view.findViewById(R.id.tv_flight_speed);
|
||||
|
||||
tv_climb_speed_minus = view.findViewById(R.id.tv_climb_speed_minus);
|
||||
seekBar_climb_speed = view.findViewById(R.id.seekBar_climb_speed);
|
||||
tv_climb_speed_add = view.findViewById(R.id.tv_climb_speed_add);
|
||||
tv_climb_speed = view.findViewById(R.id.tv_climb_speed);
|
||||
|
||||
tv_decline_speed_minus = view.findViewById(R.id.tv_decline_speed_minus);
|
||||
seekBar_decline_speed = view.findViewById(R.id.seekBar_decline_speed);
|
||||
tv_decline_speed_add = view.findViewById(R.id.tv_decline_speed_add);
|
||||
tv_decline_speed = view.findViewById(R.id.tv_decline_speed);
|
||||
|
||||
tv_horizontal_angle_minus = view.findViewById(R.id.tv_horizontal_angle_minus);
|
||||
seekBar_horizontal_angle = view.findViewById(R.id.seekBar_horizontal_angle);
|
||||
tv_horizontal_angle_add = view.findViewById(R.id.tv_horizontal_angle_add);
|
||||
tv_horizontal_angle = view.findViewById(R.id.tv_horizontal_angle);
|
||||
|
||||
tv_rotation_rate_minus = view.findViewById(R.id.tv_rotation_rate_minus);
|
||||
seekBar_rotation_rate = view.findViewById(R.id.seekBar_rotation_rate);
|
||||
tv_rotation_rate_add = view.findViewById(R.id.tv_rotation_rate_add);
|
||||
tv_rotation_rate = view.findViewById(R.id.tv_rotation_rate);
|
||||
|
||||
tv_save = view.findViewById(R.id.tv_save);
|
||||
tv_default = view.findViewById(R.id.tv_default);
|
||||
|
||||
}
|
||||
|
||||
@ -50,8 +106,216 @@ public class FlyFragment extends Fragment {
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initOnClick() {
|
||||
// 最大平飞速度
|
||||
tv_flight_speed_minus.setOnClickListener(v -> {
|
||||
int progress = seekBar_flight_speed.getProgress();
|
||||
if (progress > 20) {
|
||||
seekBar_flight_speed.setProgress(progress - 10);
|
||||
tv_flight_speed.setText(((double)seekBar_flight_speed.getProgress()/100) + "m/s");
|
||||
}
|
||||
});
|
||||
|
||||
tv_flight_speed_add.setOnClickListener(v -> {
|
||||
int progress = seekBar_flight_speed.getProgress();
|
||||
if (progress < seekBar_flight_speed.getMax()) {
|
||||
seekBar_flight_speed.setProgress(progress + 10);
|
||||
tv_flight_speed.setText(((double)seekBar_flight_speed.getProgress()/100) + "m/s");
|
||||
}
|
||||
});
|
||||
|
||||
seekBar_flight_speed.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
tv_flight_speed.setText(((double)seekBar_flight_speed.getProgress()/100) + "m/s");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
});
|
||||
|
||||
// 最大爬升速度
|
||||
tv_climb_speed_minus.setOnClickListener(v -> {
|
||||
int progress = seekBar_climb_speed.getProgress();
|
||||
if (progress > 50) {
|
||||
seekBar_climb_speed.setProgress(progress - 10);
|
||||
tv_climb_speed.setText(((double)seekBar_climb_speed.getProgress()/100) + "m/s");
|
||||
}
|
||||
});
|
||||
|
||||
tv_climb_speed_add.setOnClickListener(v -> {
|
||||
int progress = seekBar_climb_speed.getProgress();
|
||||
if (progress < seekBar_climb_speed.getMax()) {
|
||||
seekBar_climb_speed.setProgress(progress + 10);
|
||||
tv_climb_speed.setText(((double)seekBar_climb_speed.getProgress()/100) + "m/s");
|
||||
}
|
||||
});
|
||||
|
||||
seekBar_climb_speed.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
tv_climb_speed.setText(((double)seekBar_climb_speed.getProgress()/100) + "m/s");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
});
|
||||
|
||||
// 最大下降速度
|
||||
tv_decline_speed_minus.setOnClickListener(v -> {
|
||||
int progress = seekBar_decline_speed.getProgress();
|
||||
if (progress > 0) {
|
||||
seekBar_decline_speed.setProgress(progress - 10);
|
||||
tv_decline_speed.setText(((double)seekBar_decline_speed.getProgress()/100) + "m/s");
|
||||
}
|
||||
});
|
||||
|
||||
tv_decline_speed_add.setOnClickListener(v -> {
|
||||
int progress = seekBar_decline_speed.getProgress();
|
||||
if (progress < seekBar_decline_speed.getMax()) {
|
||||
seekBar_decline_speed.setProgress(progress + 10);
|
||||
tv_decline_speed.setText(((double)seekBar_decline_speed.getProgress()/100) + "m/s");
|
||||
}
|
||||
});
|
||||
|
||||
seekBar_decline_speed.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
tv_decline_speed.setText(((double)seekBar_decline_speed.getProgress()/100) + "m/s");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
});
|
||||
|
||||
// 最大水平角度
|
||||
tv_horizontal_angle_minus.setOnClickListener(v -> {
|
||||
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_add.setOnClickListener(v -> {
|
||||
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");
|
||||
}
|
||||
});
|
||||
|
||||
seekBar_horizontal_angle.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
tv_horizontal_angle.setText(progress + "度");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
});
|
||||
|
||||
// 最大旋转速率
|
||||
tv_rotation_rate_minus.setOnClickListener(v -> {
|
||||
int progress = seekBar_rotation_rate.getProgress();
|
||||
if (progress > 1) {
|
||||
seekBar_rotation_rate.setProgress(progress - 1);
|
||||
tv_rotation_rate.setText(((double)seekBar_rotation_rate.getProgress()/10) + "度/s");
|
||||
}
|
||||
});
|
||||
|
||||
tv_rotation_rate_add.setOnClickListener(v -> {
|
||||
int progress = seekBar_rotation_rate.getProgress();
|
||||
if (progress < seekBar_rotation_rate.getMax()) {
|
||||
seekBar_rotation_rate.setProgress(progress + 1);
|
||||
tv_rotation_rate.setText(((double)seekBar_rotation_rate.getProgress()/10) + "度/s");
|
||||
}
|
||||
});
|
||||
|
||||
seekBar_rotation_rate.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
tv_rotation_rate.setText(((double)progress/10) + "度/s");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||
});
|
||||
|
||||
//保存
|
||||
tv_save.setOnClickListener( v -> {
|
||||
save();
|
||||
Toast.makeText(getActivity(), "保存成功!", Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
|
||||
tv_default.setOnClickListener(v -> {
|
||||
save();
|
||||
seekBar_flight_speed.setProgress(1250);
|
||||
tv_flight_speed.setText(seekBar_flight_speed.getProgress() + "m/s");
|
||||
seekBar_climb_speed.setProgress(250);
|
||||
tv_climb_speed.setText(seekBar_climb_speed.getProgress() + "m/s");
|
||||
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");
|
||||
seekBar_rotation_rate.setProgress(2025);
|
||||
tv_rotation_rate.setText(((double)seekBar_rotation_rate.getProgress()/10) + "度/s");
|
||||
Toast.makeText(getActivity(), "初始化完成", Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法:获取当前所有的参数
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void getData(){
|
||||
seekBar_flight_speed.setProgress(Integer.parseInt(FlyVoid.paramList.get("LOIT_SPEED").getParam_value()));
|
||||
tv_flight_speed.setText(((double)seekBar_flight_speed.getProgress()/100) + "m/s");
|
||||
seekBar_climb_speed.setProgress(Integer.parseInt(FlyVoid.paramList.get("PILOT_SPEED_UP").getParam_value()));
|
||||
tv_climb_speed.setText(((double)seekBar_climb_speed.getProgress()/100) + "m/s");
|
||||
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");
|
||||
//旋转速率单独运算一下
|
||||
float rotation_rate = Float.parseFloat(FlyVoid.paramList.get("PILOT_Y_RATE").getParam_value())*10;
|
||||
seekBar_rotation_rate.setProgress((int) rotation_rate);
|
||||
tv_rotation_rate.setText(((double)seekBar_rotation_rate.getProgress()/10) + "度/s");
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法:保存
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void save(){
|
||||
flyVoid.requestParamSet("LOIT_SPEED", String.valueOf(seekBar_flight_speed.getProgress()));
|
||||
flyVoid.requestParamSet("PILOT_SPEED_UP", String.valueOf(seekBar_climb_speed.getProgress()));
|
||||
flyVoid.requestParamSet("PILOT_SPEED_DN", String.valueOf(seekBar_decline_speed.getProgress()));
|
||||
flyVoid.requestParamSet("ANGLE_MAX", String.valueOf(seekBar_horizontal_angle.getProgress()));
|
||||
flyVoid.requestParamSet("PILOT_Y_RATE", String.valueOf((double)seekBar_rotation_rate.getProgress()/10));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
getData();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
package com.example.longyi_groundstation.Main.Setting.Fragment.Foundation;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.example.longyi_groundstation.R;
|
||||
|
||||
// 简单的载荷Fragment,用于显示不同载荷的内容
|
||||
public class FlyAccelerationFragment extends Fragment {
|
||||
View view;
|
||||
|
||||
|
||||
public FlyAccelerationFragment() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
}
|
||||
|
||||
@SuppressLint("MissingInflatedId")
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
view = inflater.inflate(R.layout.fragment_fly_acceleration, container, false);
|
||||
|
||||
initData();
|
||||
initView();
|
||||
initOnClick();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private void initData() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 方法:初始化视图
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initView() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法:初始化点击事件
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initOnClick() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
package com.example.longyi_groundstation.Main.Setting.Fragment.Foundation;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.example.longyi_groundstation.R;
|
||||
|
||||
// 简单的载荷Fragment,用于显示不同载荷的内容
|
||||
public class FlyInstallFragment extends Fragment {
|
||||
View view;
|
||||
|
||||
|
||||
public FlyInstallFragment() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
}
|
||||
|
||||
@SuppressLint("MissingInflatedId")
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
view = inflater.inflate(R.layout.fragment_fly_install, container, false);
|
||||
|
||||
initData();
|
||||
initView();
|
||||
initOnClick();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private void initData() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 方法:初始化视图
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initView() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法:初始化点击事件
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initOnClick() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
package com.example.longyi_groundstation.Main.Setting.Fragment.Foundation;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.example.longyi_groundstation.R;
|
||||
|
||||
// 简单的载荷Fragment,用于显示不同载荷的内容
|
||||
public class FlyMagnetometerFragment extends Fragment {
|
||||
View view;
|
||||
|
||||
|
||||
public FlyMagnetometerFragment() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
}
|
||||
|
||||
@SuppressLint("MissingInflatedId")
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
view = inflater.inflate(R.layout.fragment_fly_magnetometer, container, false);
|
||||
|
||||
initData();
|
||||
initView();
|
||||
initOnClick();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private void initData() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 方法:初始化视图
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initView() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法:初始化点击事件
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initOnClick() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
package com.example.longyi_groundstation.Main.Setting.Fragment.Foundation;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.example.longyi_groundstation.Main.Setting.Adapter.SecureItemListAdapter;
|
||||
import com.example.longyi_groundstation.Main.Setting.Base.Payload;
|
||||
import com.example.longyi_groundstation.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
// 简单的载荷Fragment,用于显示不同载荷的内容
|
||||
public class FlyModelFragment extends Fragment {
|
||||
View view;
|
||||
|
||||
|
||||
public FlyModelFragment() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
}
|
||||
|
||||
@SuppressLint("MissingInflatedId")
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
view = inflater.inflate(R.layout.fragment_fly_model, container, false);
|
||||
|
||||
initData();
|
||||
initView();
|
||||
initOnClick();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private void initData() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 方法:初始化视图
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initView() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法:初始化点击事件
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initOnClick() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -6,18 +6,26 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.viewpager2.widget.ViewPager2;
|
||||
|
||||
import com.example.longyi_groundstation.Main.Setting.Adapter.SecurePagerAdapter;
|
||||
import com.example.longyi_groundstation.R;
|
||||
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import com.google.android.material.tabs.TabLayoutMediator;
|
||||
import com.example.longyi_groundstation.Main.Setting.Adapter.FoundationPagerAdapter;
|
||||
|
||||
public class FoundationFragment extends Fragment {
|
||||
|
||||
private View view;
|
||||
private TabLayout tabLayout;
|
||||
private ViewPager2 viewPager;
|
||||
private TabLayoutMediator tabLayoutMediator;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
View view = inflater.inflate(R.layout.fragment_foundation, container, false);
|
||||
view = inflater.inflate(R.layout.fragment_foundation, container, false);
|
||||
|
||||
initData();
|
||||
initView();
|
||||
@ -41,7 +49,48 @@ public class FoundationFragment extends Fragment {
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initView() {
|
||||
viewPager = view.findViewById(R.id.view_pager);
|
||||
tabLayout = view.findViewById(R.id.tab_layout);
|
||||
|
||||
|
||||
// if (getActivity() != null) {
|
||||
// viewPager.setAdapter(new FoundationPagerAdapter(getActivity()));
|
||||
//
|
||||
// // 先释放之前的TabLayoutMediator(如果存在)
|
||||
// if (tabLayoutMediator != null) {
|
||||
// tabLayoutMediator.detach();
|
||||
// }
|
||||
//
|
||||
// tabLayoutMediator = new TabLayoutMediator(tabLayout, viewPager,
|
||||
// (tab, position) -> {
|
||||
// switch (position) {
|
||||
// case 0:
|
||||
// tab.setText("机型设置");
|
||||
// break;
|
||||
// case 1:
|
||||
// tab.setText("安装设置");
|
||||
// break;
|
||||
// case 2:
|
||||
// tab.setText("加速度计");
|
||||
// break;
|
||||
// case 3:
|
||||
// tab.setText("磁力计");
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// );
|
||||
// tabLayoutMediator.attach();
|
||||
//
|
||||
// // 为Tab之间添加间距
|
||||
// for (int i = 0; i < tabLayout.getTabCount(); i++) {
|
||||
// View tab = (((ViewGroup) tabLayout.getChildAt(0)).getChildAt(i));
|
||||
// ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) tab.getLayoutParams();
|
||||
// layoutParams.setMargins(6, 0, 6, 0); // 左右各16dp的间距
|
||||
// tab.setLayoutParams(layoutParams);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
@ -53,5 +102,27 @@ public class FoundationFragment extends Fragment {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
// // 使用post方法将initData()推迟到下一个UI循环执行,避免FragmentManager冲突
|
||||
// getView().post(new Runnable() {
|
||||
// @Override
|
||||
// public void run() {
|
||||
// initData();
|
||||
// initView();
|
||||
// initOnClick();
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
// 清理TabLayoutMediator资源
|
||||
if (tabLayoutMediator != null) {
|
||||
tabLayoutMediator.detach();
|
||||
tabLayoutMediator = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,29 +1,106 @@
|
||||
|
||||
package com.example.longyi_groundstation.Main.Setting.Fragment;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.InputType;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.viewpager2.widget.ViewPager2;
|
||||
|
||||
import com.example.longyi_groundstation.Main.Setting.Adapter.SecurePagerAdapter;
|
||||
import com.example.longyi_groundstation.Main.Setting.Void.ViewTool;
|
||||
import com.example.longyi_groundstation.Main.Setting.Base.ChannelItem;
|
||||
import com.example.longyi_groundstation.Main.Void.FlyVoid;
|
||||
import com.example.longyi_groundstation.R;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import com.google.android.material.tabs.TabLayoutMediator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class LoadFragment extends Fragment {
|
||||
|
||||
private View view;
|
||||
private TabLayout tabLayout;
|
||||
private ViewPager2 viewPager;
|
||||
private TabLayoutMediator tabLayoutMediator;
|
||||
private TextView tv_save;
|
||||
private TextView tv_ctrl_m7;
|
||||
private TextView tv_fly_m7;
|
||||
private Spinner sp_m7;
|
||||
private TextView tv_value_minus_m7;
|
||||
private EditText et_value_m7;
|
||||
private TextView tv_value_add_m7;
|
||||
private TextView tv_off_minus_m7;
|
||||
private EditText et_off_m7;
|
||||
private TextView tv_off_add_m7;
|
||||
private TextView tv_ctrl_m8;
|
||||
private TextView tv_fly_m8;
|
||||
private Spinner sp_m8;
|
||||
private TextView tv_value_minus_m8;
|
||||
private EditText et_value_m8;
|
||||
private TextView tv_value_add_m8;
|
||||
private TextView tv_off_minus_m8;
|
||||
private EditText et_off_m8;
|
||||
private TextView tv_off_add_m8;
|
||||
private TextView tv_ctrl_m9;
|
||||
private TextView tv_fly_m9;
|
||||
private Spinner sp_m9;
|
||||
private TextView tv_value_minus_m9;
|
||||
private EditText et_value_m9;
|
||||
private TextView tv_value_add_m9;
|
||||
private TextView tv_off_minus_m9;
|
||||
private EditText et_off_m9;
|
||||
private TextView tv_off_add_m9;
|
||||
private TextView tv_ctrl_m10;
|
||||
private TextView tv_fly_m10;
|
||||
private Spinner sp_m10;
|
||||
private TextView tv_value_minus_m10;
|
||||
private EditText et_value_m10;
|
||||
private TextView tv_value_add_m10;
|
||||
private TextView tv_off_minus_m10;
|
||||
private EditText et_off_m10;
|
||||
private TextView tv_off_add_m10;
|
||||
private TextView tv_ctrl_m11;
|
||||
private TextView tv_fly_m11;
|
||||
private Spinner sp_m11;
|
||||
private TextView tv_value_minus_m11;
|
||||
private EditText et_value_m11;
|
||||
private TextView tv_value_add_m11;
|
||||
private TextView tv_off_minus_m11;
|
||||
private EditText et_off_m11;
|
||||
private TextView tv_off_add_m11;
|
||||
private TextView tv_ctrl_m12;
|
||||
private TextView tv_fly_m12;
|
||||
private Spinner sp_m12;
|
||||
private TextView tv_value_minus_m12;
|
||||
private EditText et_value_m12;
|
||||
private TextView tv_value_add_m12;
|
||||
private TextView tv_off_minus_m12;
|
||||
private EditText et_off_m12;
|
||||
private TextView tv_off_add_m12;
|
||||
private TextView tv_ctrl_m13;
|
||||
private TextView tv_fly_m13;
|
||||
private Spinner sp_m13;
|
||||
private TextView tv_value_minus_m13;
|
||||
private EditText et_value_m13;
|
||||
private TextView tv_value_add_m13;
|
||||
private TextView tv_off_minus_m13;
|
||||
private EditText et_off_m13;
|
||||
private TextView tv_off_add_m13;
|
||||
|
||||
// 在Fragment或Activity中声明EditText变量
|
||||
private EditText[] valueEditTexts;
|
||||
private EditText[] offEditTexts;
|
||||
private TextView[] flyTextViews;
|
||||
private FlyVoid flyVoid = new FlyVoid();
|
||||
|
||||
|
||||
@SuppressLint("MissingInflatedId")
|
||||
@ -33,57 +110,27 @@ public class LoadFragment extends Fragment {
|
||||
// Inflate the layout for this fragment
|
||||
view = inflater.inflate(R.layout.fragment_load, container, false);
|
||||
|
||||
tabLayout = view.findViewById(R.id.tab_layout);
|
||||
viewPager = view.findViewById(R.id.view_pager);
|
||||
|
||||
|
||||
initData();
|
||||
initView();
|
||||
initOnClick();
|
||||
// 初始化数据
|
||||
initDataView();
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法:初始化数据
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initData() {
|
||||
if (getActivity() != null) {
|
||||
viewPager.setAdapter(new SecurePagerAdapter(getActivity()));
|
||||
|
||||
// 先释放之前的TabLayoutMediator(如果存在)
|
||||
if (tabLayoutMediator != null) {
|
||||
tabLayoutMediator.detach();
|
||||
}
|
||||
|
||||
tabLayoutMediator = new TabLayoutMediator(tabLayout, viewPager,
|
||||
(tab, position) -> {
|
||||
switch (position) {
|
||||
case 0:
|
||||
tab.setText("灭火弹");
|
||||
break;
|
||||
case 1:
|
||||
tab.setText("缓降器");
|
||||
break;
|
||||
case 2:
|
||||
tab.setText("抛投勾");
|
||||
break;
|
||||
case 3:
|
||||
tab.setText("其他载荷");
|
||||
break;
|
||||
}
|
||||
}
|
||||
);
|
||||
tabLayoutMediator.attach();
|
||||
|
||||
// 为Tab之间添加间距
|
||||
for (int i = 0; i < tabLayout.getTabCount(); i++) {
|
||||
View tab = (((ViewGroup) tabLayout.getChildAt(0)).getChildAt(i));
|
||||
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) tab.getLayoutParams();
|
||||
layoutParams.setMargins(6, 0, 6, 0); // 左右各16dp的间距
|
||||
tab.setLayoutParams(layoutParams);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -92,6 +139,84 @@ public class LoadFragment extends Fragment {
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initView() {
|
||||
tv_save = view.findViewById(R.id.tv_save);
|
||||
tv_ctrl_m7 = view.findViewById(R.id.tv_ctrl_m7);
|
||||
tv_fly_m7 = view.findViewById(R.id.tv_fly_m7);
|
||||
sp_m7 = view.findViewById(R.id.sp_m7);
|
||||
tv_value_minus_m7 = view.findViewById(R.id.tv_value_minus_m7);
|
||||
et_value_m7 = view.findViewById(R.id.et_value_m7);
|
||||
tv_value_add_m7 = view.findViewById(R.id.tv_value_add_m7);
|
||||
tv_off_minus_m7 = view.findViewById(R.id.tv_off_minus_m7);
|
||||
et_off_m7 = view.findViewById(R.id.et_off_m7);
|
||||
tv_off_add_m7 = view.findViewById(R.id.tv_off_add_m7);
|
||||
tv_ctrl_m8 = view.findViewById(R.id.tv_ctrl_m8);
|
||||
tv_fly_m8 = view.findViewById(R.id.tv_fly_m8);
|
||||
sp_m8 = view.findViewById(R.id.sp_m8);
|
||||
tv_value_minus_m8 = view.findViewById(R.id.tv_value_minus_m8);
|
||||
et_value_m8 = view.findViewById(R.id.et_value_m8);
|
||||
tv_value_add_m8 = view.findViewById(R.id.tv_value_add_m8);
|
||||
tv_off_minus_m8 = view.findViewById(R.id.tv_off_minus_m8);
|
||||
et_off_m8 = view.findViewById(R.id.et_off_m8);
|
||||
tv_off_add_m8 = view.findViewById(R.id.tv_off_add_m8);
|
||||
tv_ctrl_m9 = view.findViewById(R.id.tv_ctrl_m9);
|
||||
tv_fly_m9 = view.findViewById(R.id.tv_fly_m9);
|
||||
sp_m9 = view.findViewById(R.id.sp_m9);
|
||||
tv_value_minus_m9 = view.findViewById(R.id.tv_value_minus_m9);
|
||||
et_value_m9 = view.findViewById(R.id.et_value_m9);
|
||||
tv_value_add_m9 = view.findViewById(R.id.tv_value_add_m9);
|
||||
tv_off_minus_m9 = view.findViewById(R.id.tv_off_minus_m9);
|
||||
et_off_m9 = view.findViewById(R.id.et_off_m9);
|
||||
tv_off_add_m9 = view.findViewById(R.id.tv_off_add_m9);
|
||||
tv_ctrl_m10 = view.findViewById(R.id.tv_ctrl_m10);
|
||||
tv_fly_m10 = view.findViewById(R.id.tv_fly_m10);
|
||||
sp_m10 = view.findViewById(R.id.sp_m10);
|
||||
tv_value_minus_m10 = view.findViewById(R.id.tv_value_minus_m10);
|
||||
et_value_m10 = view.findViewById(R.id.et_value_m10);
|
||||
tv_value_add_m10 = view.findViewById(R.id.tv_value_add_m10);
|
||||
tv_off_minus_m10 = view.findViewById(R.id.tv_off_minus_m10);
|
||||
et_off_m10 = view.findViewById(R.id.et_off_m10);
|
||||
tv_off_add_m10 = view.findViewById(R.id.tv_off_add_m10);
|
||||
tv_ctrl_m11 = view.findViewById(R.id.tv_ctrl_m11);
|
||||
tv_fly_m11 = view.findViewById(R.id.tv_fly_m11);
|
||||
sp_m11 = view.findViewById(R.id.sp_m11);
|
||||
tv_value_minus_m11 = view.findViewById(R.id.tv_value_minus_m11);
|
||||
et_value_m11 = view.findViewById(R.id.et_value_m11);
|
||||
tv_value_add_m11 = view.findViewById(R.id.tv_value_add_m11);
|
||||
tv_off_minus_m11 = view.findViewById(R.id.tv_off_minus_m11);
|
||||
et_off_m11 = view.findViewById(R.id.et_off_m11);
|
||||
tv_off_add_m11 = view.findViewById(R.id.tv_off_add_m11);
|
||||
tv_ctrl_m12 = view.findViewById(R.id.tv_ctrl_m12);
|
||||
tv_fly_m12 = view.findViewById(R.id.tv_fly_m12);
|
||||
sp_m12 = view.findViewById(R.id.sp_m12);
|
||||
tv_value_minus_m12 = view.findViewById(R.id.tv_value_minus_m12);
|
||||
et_value_m12 = view.findViewById(R.id.et_value_m12);
|
||||
tv_value_add_m12 = view.findViewById(R.id.tv_value_add_m12);
|
||||
tv_off_minus_m12 = view.findViewById(R.id.tv_off_minus_m12);
|
||||
et_off_m12 = view.findViewById(R.id.et_off_m12);
|
||||
tv_off_add_m12 = view.findViewById(R.id.tv_off_add_m12);
|
||||
tv_ctrl_m13 = view.findViewById(R.id.tv_ctrl_m13);
|
||||
tv_fly_m13 = view.findViewById(R.id.tv_fly_m13);
|
||||
sp_m13 = view.findViewById(R.id.sp_m13);
|
||||
tv_value_minus_m13 = view.findViewById(R.id.tv_value_minus_m13);
|
||||
et_value_m13 = view.findViewById(R.id.et_value_m13);
|
||||
tv_value_add_m13 = view.findViewById(R.id.tv_value_add_m13);
|
||||
tv_off_minus_m13 = view.findViewById(R.id.tv_off_minus_m13);
|
||||
et_off_m13 = view.findViewById(R.id.et_off_m13);
|
||||
tv_off_add_m13 = view.findViewById(R.id.tv_off_add_m13);
|
||||
|
||||
// 初始化所有Spinner数据
|
||||
initSpinnerData();
|
||||
|
||||
// 初始化所有EditText,TextView
|
||||
initTexts(view);
|
||||
|
||||
// 为所有EditText设置输入限制
|
||||
setupInputFilters();
|
||||
|
||||
// 给flyTextViews里面所有的view添加点击事件:点击后会打开对应的Spinner
|
||||
initFlyTextViewClickListeners();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -102,29 +227,621 @@ public class LoadFragment extends Fragment {
|
||||
*/
|
||||
private void initOnClick() {
|
||||
|
||||
tv_value_minus_m7.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_value_m7.getText().toString()) >= 1200) {
|
||||
et_value_m7.setText(String.valueOf(Integer.parseInt(et_value_m7.getText().toString()) - 100));
|
||||
} else {
|
||||
et_value_m7.setText("1100");
|
||||
}
|
||||
});
|
||||
tv_value_add_m7.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_value_m7.getText().toString()) <= 1800) {
|
||||
et_value_m7.setText(String.valueOf(Integer.parseInt(et_value_m7.getText().toString()) + 100));
|
||||
} else {
|
||||
et_value_m7.setText("1900");
|
||||
}
|
||||
});
|
||||
tv_off_minus_m7.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_off_m7.getText().toString()) >= 1200) {
|
||||
et_off_m7.setText(String.valueOf(Integer.parseInt(et_off_m7.getText().toString()) - 100));
|
||||
} else {
|
||||
et_off_m7.setText("1100");
|
||||
}
|
||||
});
|
||||
tv_off_add_m7.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_off_m7.getText().toString()) <= 1800) {
|
||||
et_off_m7.setText(String.valueOf(Integer.parseInt(et_off_m7.getText().toString()) + 100));
|
||||
} else {
|
||||
et_off_m7.setText("1900");
|
||||
}
|
||||
});
|
||||
tv_value_minus_m8.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_value_m8.getText().toString()) >= 1200) {
|
||||
et_value_m8.setText(String.valueOf(Integer.parseInt(et_value_m8.getText().toString()) - 100));
|
||||
} else {
|
||||
et_value_m8.setText("1100");
|
||||
}
|
||||
});
|
||||
tv_value_add_m8.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_value_m8.getText().toString()) <= 1800) {
|
||||
et_value_m8.setText(String.valueOf(Integer.parseInt(et_value_m8.getText().toString()) + 100));
|
||||
} else {
|
||||
et_value_m8.setText("1900");
|
||||
}
|
||||
});
|
||||
tv_off_minus_m8.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_off_m8.getText().toString()) >= 1200) {
|
||||
et_off_m8.setText(String.valueOf(Integer.parseInt(et_off_m8.getText().toString()) - 100));
|
||||
} else {
|
||||
et_off_m8.setText("1100");
|
||||
}
|
||||
});
|
||||
tv_off_add_m8.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_off_m8.getText().toString()) <= 1800) {
|
||||
et_off_m8.setText(String.valueOf(Integer.parseInt(et_off_m8.getText().toString()) + 100));
|
||||
} else {
|
||||
et_off_m8.setText("1900");
|
||||
}
|
||||
});
|
||||
tv_value_minus_m9.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_value_m9.getText().toString()) >= 1200) {
|
||||
et_value_m9.setText(String.valueOf(Integer.parseInt(et_value_m9.getText().toString()) - 100));
|
||||
} else {
|
||||
et_value_m9.setText("1100");
|
||||
}
|
||||
});
|
||||
tv_value_add_m9.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_value_m9.getText().toString()) <= 1800) {
|
||||
et_value_m9.setText(String.valueOf(Integer.parseInt(et_value_m9.getText().toString()) + 100));
|
||||
} else {
|
||||
et_value_m9.setText("1900");
|
||||
}
|
||||
});
|
||||
tv_off_minus_m9.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_off_m9.getText().toString()) >= 1200) {
|
||||
et_off_m9.setText(String.valueOf(Integer.parseInt(et_off_m9.getText().toString()) - 100));
|
||||
} else {
|
||||
et_off_m9.setText("1100");
|
||||
}
|
||||
});
|
||||
tv_off_add_m9.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_off_m9.getText().toString()) <= 1800) {
|
||||
et_off_m9.setText(String.valueOf(Integer.parseInt(et_off_m9.getText().toString()) + 100));
|
||||
} else {
|
||||
et_off_m9.setText("1900");
|
||||
}
|
||||
});
|
||||
tv_value_minus_m10.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_value_m10.getText().toString()) >= 1200) {
|
||||
et_value_m10.setText(String.valueOf(Integer.parseInt(et_value_m10.getText().toString()) - 100));
|
||||
} else {
|
||||
et_value_m10.setText("1100");
|
||||
}
|
||||
});
|
||||
tv_value_add_m10.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_value_m10.getText().toString()) <= 1800) {
|
||||
et_value_m10.setText(String.valueOf(Integer.parseInt(et_value_m10.getText().toString()) + 100));
|
||||
} else {
|
||||
et_value_m10.setText("1900");
|
||||
}
|
||||
});
|
||||
tv_off_minus_m10.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_off_m10.getText().toString()) >= 1200) {
|
||||
et_off_m10.setText(String.valueOf(Integer.parseInt(et_off_m10.getText().toString()) - 100));
|
||||
} else {
|
||||
et_off_m10.setText("1100");
|
||||
}
|
||||
});
|
||||
tv_off_add_m10.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_off_m10.getText().toString()) <= 1800) {
|
||||
et_off_m10.setText(String.valueOf(Integer.parseInt(et_off_m10.getText().toString()) + 100));
|
||||
} else {
|
||||
et_off_m10.setText("1900");
|
||||
}
|
||||
});
|
||||
tv_value_minus_m11.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_value_m11.getText().toString()) >= 1200) {
|
||||
et_value_m11.setText(String.valueOf(Integer.parseInt(et_value_m11.getText().toString()) - 100));
|
||||
} else {
|
||||
et_value_m11.setText("1100");
|
||||
}
|
||||
});
|
||||
tv_value_add_m11.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_value_m11.getText().toString()) <= 1800) {
|
||||
et_value_m11.setText(String.valueOf(Integer.parseInt(et_value_m11.getText().toString()) + 100));
|
||||
} else {
|
||||
et_value_m11.setText("1900");
|
||||
}
|
||||
});
|
||||
tv_off_minus_m11.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_off_m11.getText().toString()) >= 1200) {
|
||||
et_off_m11.setText(String.valueOf(Integer.parseInt(et_off_m11.getText().toString()) - 100));
|
||||
} else {
|
||||
et_off_m11.setText("1100");
|
||||
}
|
||||
});
|
||||
tv_off_add_m11.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_off_m11.getText().toString()) <= 1800) {
|
||||
et_off_m11.setText(String.valueOf(Integer.parseInt(et_off_m11.getText().toString()) + 100));
|
||||
} else {
|
||||
et_off_m11.setText("1900");
|
||||
}
|
||||
});
|
||||
tv_value_minus_m12.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_value_m12.getText().toString()) >= 1200) {
|
||||
et_value_m12.setText(String.valueOf(Integer.parseInt(et_value_m12.getText().toString()) - 100));
|
||||
} else {
|
||||
et_value_m12.setText("1100");
|
||||
}
|
||||
});
|
||||
tv_value_add_m12.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_value_m12.getText().toString()) <= 1800) {
|
||||
et_value_m12.setText(String.valueOf(Integer.parseInt(et_value_m12.getText().toString()) + 100));
|
||||
} else {
|
||||
et_value_m12.setText("1900");
|
||||
}
|
||||
});
|
||||
tv_off_minus_m12.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_off_m12.getText().toString()) >= 1200) {
|
||||
et_off_m12.setText(String.valueOf(Integer.parseInt(et_off_m12.getText().toString()) - 100));
|
||||
} else {
|
||||
et_off_m12.setText("1100");
|
||||
}
|
||||
});
|
||||
tv_off_add_m12.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_off_m12.getText().toString()) <= 1800) {
|
||||
et_off_m12.setText(String.valueOf(Integer.parseInt(et_off_m12.getText().toString()) + 100));
|
||||
} else {
|
||||
et_off_m12.setText("1900");
|
||||
}
|
||||
});
|
||||
tv_value_minus_m13.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_value_m13.getText().toString()) >= 1200) {
|
||||
et_value_m13.setText(String.valueOf(Integer.parseInt(et_value_m13.getText().toString()) - 100));
|
||||
} else {
|
||||
et_value_m13.setText("1100");
|
||||
}
|
||||
});
|
||||
tv_value_add_m13.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_value_m13.getText().toString()) <= 1800) {
|
||||
et_value_m13.setText(String.valueOf(Integer.parseInt(et_value_m13.getText().toString()) + 100));
|
||||
} else {
|
||||
et_value_m13.setText("1900");
|
||||
}
|
||||
});
|
||||
tv_off_minus_m13.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_off_m13.getText().toString()) >= 1200) {
|
||||
et_off_m13.setText(String.valueOf(Integer.parseInt(et_off_m13.getText().toString()) - 100));
|
||||
} else {
|
||||
et_off_m13.setText("1100");
|
||||
}
|
||||
});
|
||||
tv_off_add_m13.setOnClickListener(v -> {
|
||||
if (Integer.parseInt(et_off_m13.getText().toString()) <= 1800) {
|
||||
et_off_m13.setText(String.valueOf(Integer.parseInt(et_off_m13.getText().toString()) + 100));
|
||||
} else {
|
||||
et_off_m13.setText("1900");
|
||||
}
|
||||
});
|
||||
// 修改所有的Spinner监听器,以sp_m7为例:
|
||||
sp_m7.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@SuppressLint("SetTextI18n")
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
Log.d("无事发生", "onItemSelected: sp_m7");
|
||||
tv_fly_m7.setText( parent.getSelectedItem().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
Log.d("无事发生", "onNothingSelected: sp_m7");
|
||||
}
|
||||
});
|
||||
|
||||
// 对其他Spinner也做同样处理,例如sp_m8:
|
||||
sp_m8.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@SuppressLint("SetTextI18n")
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
Log.d("无事发生", "onItemSelected: sp_m8");
|
||||
tv_fly_m8.setText( parent.getSelectedItem().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
Log.d("无事发生", "onNothingSelected: sp_m8");
|
||||
}
|
||||
});
|
||||
|
||||
// 对sp_m9到sp_m13都做相同处理
|
||||
sp_m9.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@SuppressLint("SetTextI18n")
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
tv_fly_m9.setText( parent.getSelectedItem().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
sp_m10.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@SuppressLint("SetTextI18n")
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
tv_fly_m10.setText( parent.getSelectedItem().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
sp_m11.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@SuppressLint("SetTextI18n")
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
tv_fly_m11.setText( parent.getSelectedItem().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
sp_m12.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@SuppressLint("SetTextI18n")
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
|
||||
tv_fly_m12.setText( parent.getSelectedItem().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
sp_m13.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@SuppressLint("SetTextI18n")
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
|
||||
tv_fly_m13.setText( parent.getSelectedItem().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//保存
|
||||
tv_save.setOnClickListener(v -> {
|
||||
save();
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法:初始化flyTextView点击事件
|
||||
* 点击TextView后会打开对应的Spinner
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initFlyTextViewClickListeners() {
|
||||
TextView[] flyTextViews = {
|
||||
tv_fly_m7, tv_fly_m8, tv_fly_m9, tv_fly_m10,
|
||||
tv_fly_m11, tv_fly_m12, tv_fly_m13
|
||||
};
|
||||
|
||||
Spinner[] correspondingSpinners = {
|
||||
sp_m7, sp_m8, sp_m9, sp_m10,
|
||||
sp_m11, sp_m12, sp_m13
|
||||
};
|
||||
|
||||
for (int i = 0; i < flyTextViews.length; i++) {
|
||||
final Spinner correspondingSpinner = correspondingSpinners[i];
|
||||
if (flyTextViews[i] != null && correspondingSpinner != null) {
|
||||
flyTextViews[i].setOnClickListener(v -> {
|
||||
// 点击TextView后打开对应的Spinner
|
||||
correspondingSpinner.performClick();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 方法:初始化Spinner数据
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initSpinnerData() {
|
||||
// 创建通道数据列表
|
||||
List<ChannelItem> channelList = new ArrayList<>();
|
||||
for (int i = 7; i <= 14; i++) {
|
||||
channelList.add(new ChannelItem("通道" + i, 51 + (i - 7)));
|
||||
}
|
||||
|
||||
// 创建适配器
|
||||
ArrayAdapter<ChannelItem> adapter = new ArrayAdapter<>(requireContext(),
|
||||
android.R.layout.simple_spinner_item, channelList);
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
|
||||
// 为所有Spinner设置适配器
|
||||
Spinner[] spinners = {sp_m7, sp_m8, sp_m9, sp_m10, sp_m11, sp_m12, sp_m13};
|
||||
for (Spinner spinner : spinners) {
|
||||
if (spinner != null) {
|
||||
spinner.setAdapter(adapter);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法:初始化Spinner选择监听器
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initSpinnerListeners() {
|
||||
// 为所有Spinner设置选择监听器
|
||||
// Spinner[] spinners = {sp_m7, sp_m8, sp_m9, sp_m10, sp_m11, sp_m12, sp_m13};
|
||||
//
|
||||
// AdapterView.OnItemSelectedListener spinnerListener = new AdapterView.OnItemSelectedListener() {
|
||||
// @Override
|
||||
// public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
// Spinner spinner = (Spinner) parent;
|
||||
// ChannelItem selectedItem = (ChannelItem) parent.getItemAtPosition(position);
|
||||
// // 更新对应的TextView显示选中的通道
|
||||
// updateChannelTextView(spinner, selectedItem);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onNothingSelected(AdapterView<?> parent) {
|
||||
// // 什么都不做
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// // 为每个Spinner设置监听器
|
||||
// for (Spinner spinner : spinners) {
|
||||
// if (spinner != null) {
|
||||
// spinner.setOnItemSelectedListener(spinnerListener);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
// 示例:获取sp_m7选中的值
|
||||
private int getSelectedChannelValue(Spinner spinner) {
|
||||
if (spinner.getSelectedItem() instanceof ChannelItem) {
|
||||
ChannelItem item = (ChannelItem) spinner.getSelectedItem();
|
||||
return item.getValue();
|
||||
}
|
||||
return 0; // 默认值
|
||||
}
|
||||
|
||||
// 示例:设置Spinner选中项
|
||||
private void setSelectedChannel(Spinner spinner, int value) {
|
||||
ArrayAdapter<ChannelItem> adapter = (ArrayAdapter<ChannelItem>) spinner.getAdapter();
|
||||
for (int i = 0; i < adapter.getCount(); i++) {
|
||||
ChannelItem item = adapter.getItem(i);
|
||||
if (item != null && item.getValue() == value) {
|
||||
spinner.setSelection(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void initTexts(View view) {
|
||||
// 打开值EditText数组
|
||||
flyTextViews = new TextView[]{
|
||||
tv_fly_m7,
|
||||
tv_fly_m8,
|
||||
tv_fly_m9,
|
||||
tv_fly_m10,
|
||||
tv_fly_m11,
|
||||
tv_fly_m12,
|
||||
tv_fly_m13
|
||||
};
|
||||
|
||||
// 打开值EditText数组
|
||||
valueEditTexts = new EditText[]{
|
||||
view.findViewById(R.id.et_value_m7),
|
||||
view.findViewById(R.id.et_value_m8),
|
||||
view.findViewById(R.id.et_value_m9),
|
||||
view.findViewById(R.id.et_value_m10),
|
||||
view.findViewById(R.id.et_value_m11),
|
||||
view.findViewById(R.id.et_value_m12),
|
||||
view.findViewById(R.id.et_value_m13)
|
||||
};
|
||||
|
||||
// 关闭值EditText数组
|
||||
offEditTexts = new EditText[]{
|
||||
view.findViewById(R.id.et_off_m7),
|
||||
view.findViewById(R.id.et_off_m8),
|
||||
view.findViewById(R.id.et_off_m9),
|
||||
view.findViewById(R.id.et_off_m10),
|
||||
view.findViewById(R.id.et_off_m11),
|
||||
view.findViewById(R.id.et_off_m12),
|
||||
view.findViewById(R.id.et_off_m13)
|
||||
};
|
||||
}
|
||||
|
||||
private void setupInputFilters() {
|
||||
// 为所有EditText设置输入过滤器
|
||||
for (EditText et : valueEditTexts) {
|
||||
if (et != null) {
|
||||
setInputFilter(et);
|
||||
}
|
||||
}
|
||||
|
||||
for (EditText et : offEditTexts) {
|
||||
if (et != null) {
|
||||
setInputFilter(et);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setInputFilter(EditText editText) {
|
||||
// 设置输入类型为数字
|
||||
editText.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
|
||||
// 添加文本监听器验证范围
|
||||
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
if (!hasFocus) { // 失去焦点时验证
|
||||
validateAndCorrectInput(editText);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 添加文本变化监听器
|
||||
editText.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) {
|
||||
// 可以在这里添加实时验证逻辑
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void validateAndCorrectInput(EditText editText) {
|
||||
String input = editText.getText().toString().trim();
|
||||
|
||||
// 如果输入为空,设置默认值
|
||||
if (input.isEmpty()) {
|
||||
editText.setText("1100");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
int value = Integer.parseInt(input);
|
||||
|
||||
// 检查范围
|
||||
if (value < 1100) {
|
||||
editText.setText("1100");
|
||||
} else if (value > 1900) {
|
||||
editText.setText("1900");
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// 如果解析失败,设置默认值
|
||||
editText.setText("1100");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void initDataView() {
|
||||
|
||||
for (int i = 0; i < valueEditTexts.length; i++) {
|
||||
valueEditTexts[i].setText(flyVoid.paramList.get("SERVO" + (i + 7) + "_MAX").getParam_value());
|
||||
}
|
||||
|
||||
for (int i = 0; i < offEditTexts.length; i++) {
|
||||
offEditTexts[i].setText(flyVoid.paramList.get("SERVO" + (i + 7) + "_MIN").getParam_value());
|
||||
}
|
||||
|
||||
for (int i = 0; i < flyTextViews.length; i++) {
|
||||
String flyText = flyVoid.paramList.get("SERVO" + (i + 7) + "_FUNCTION").getParam_value();
|
||||
Log.d("flyTextViews", i + "++" + flyText);
|
||||
switch (flyText) {
|
||||
case "51":
|
||||
setSelectedChannel(sp_m7, Integer.parseInt(flyText));
|
||||
flyTextViews[i].setText("通道7");
|
||||
break;
|
||||
case "52":
|
||||
setSelectedChannel(sp_m8, Integer.parseInt(flyText));
|
||||
flyTextViews[i].setText("通道8");
|
||||
break;
|
||||
case "53":
|
||||
setSelectedChannel(sp_m9, Integer.parseInt(flyText));
|
||||
flyTextViews[i].setText("通道9");
|
||||
break;
|
||||
case "54":
|
||||
setSelectedChannel(sp_m10, Integer.parseInt(flyText));
|
||||
flyTextViews[i].setText("通道10");
|
||||
break;
|
||||
case "55":
|
||||
setSelectedChannel(sp_m11, Integer.parseInt(flyText));
|
||||
flyTextViews[i].setText("通道11");
|
||||
break;
|
||||
case "56":
|
||||
setSelectedChannel(sp_m12, Integer.parseInt(flyText));
|
||||
flyTextViews[i].setText("通道12");
|
||||
break;
|
||||
default:
|
||||
setSelectedChannel(sp_m13, Integer.parseInt(flyText));
|
||||
flyTextViews[i].setText("通道13");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Log.d("无事发生", "加载完成: ");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法:保存数据
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void save() {
|
||||
flyVoid.requestParamSet("SERVO7_FUNCTION", getSelectedChannelValue(sp_m7) + "");
|
||||
flyVoid.requestParamSet("SERVO7_MAX", et_value_m7.getText().toString());
|
||||
flyVoid.requestParamSet("SERVO7_MIN", et_value_m7.getText().toString());
|
||||
flyVoid.requestParamSet("SERVO8_FUNCTION", getSelectedChannelValue(sp_m8) + "");
|
||||
flyVoid.requestParamSet("SERVO8_MAX", et_value_m8.getText().toString());
|
||||
flyVoid.requestParamSet("SERVO8_MIN", et_value_m8.getText().toString());
|
||||
flyVoid.requestParamSet("SERVO9_FUNCTION", getSelectedChannelValue(sp_m9) + "");
|
||||
flyVoid.requestParamSet("SERVO9_MAX", et_value_m9.getText().toString());
|
||||
flyVoid.requestParamSet("SERVO9_MIN", et_value_m9.getText().toString());
|
||||
flyVoid.requestParamSet("SERVO10_FUNCTION", getSelectedChannelValue(sp_m10) + "");
|
||||
flyVoid.requestParamSet("SERVO10_MAX", et_value_m10.getText().toString());
|
||||
flyVoid.requestParamSet("SERVO10_MIN", et_value_m10.getText().toString());
|
||||
flyVoid.requestParamSet("SERVO11_FUNCTION", getSelectedChannelValue(sp_m11) + "");
|
||||
flyVoid.requestParamSet("SERVO11_MAX", et_value_m11.getText().toString());
|
||||
flyVoid.requestParamSet("SERVO11_MIN", et_value_m11.getText().toString());
|
||||
flyVoid.requestParamSet("SERVO12_FUNCTION", getSelectedChannelValue(sp_m12) + "");
|
||||
flyVoid.requestParamSet("SERVO12_MAX", et_value_m12.getText().toString());
|
||||
flyVoid.requestParamSet("SERVO12_MIN", et_value_m12.getText().toString());
|
||||
flyVoid.requestParamSet("SERVO13_FUNCTION", getSelectedChannelValue(sp_m13) + "");
|
||||
flyVoid.requestParamSet("SERVO13_MAX", et_value_m13.getText().toString());
|
||||
flyVoid.requestParamSet("SERVO13_MIN", et_value_m13.getText().toString());
|
||||
Toast.makeText(getActivity(), "保存成功!", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
// 使用post方法将initData()推迟到下一个UI循环执行,避免FragmentManager冲突
|
||||
getView().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
initData();
|
||||
initView();
|
||||
initOnClick();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
// 清理TabLayoutMediator资源
|
||||
if (tabLayoutMediator != null) {
|
||||
tabLayoutMediator.detach();
|
||||
tabLayoutMediator = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -49,7 +49,9 @@ public class MotorFragment extends Fragment {
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
view = inflater.inflate(R.layout.fragment_motor, container, false);
|
||||
|
||||
initData();
|
||||
initView(view);
|
||||
initOnClick();
|
||||
|
||||
|
||||
return view;
|
||||
@ -221,8 +223,6 @@ public class MotorFragment extends Fragment {
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
initData();
|
||||
initView(view);
|
||||
initOnClick();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,24 +5,39 @@ import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.EditText;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||
import androidx.viewpager2.widget.ViewPager2;
|
||||
|
||||
import com.example.longyi_groundstation.Main.Setting.Adapter.SecurePagerAdapter;
|
||||
import com.example.longyi_groundstation.Main.Setting.Fragment.Secure.PayloadFragment;
|
||||
import com.example.longyi_groundstation.Main.Void.MyTool;
|
||||
import com.example.longyi_groundstation.R;
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import com.google.android.material.tabs.TabLayoutMediator;
|
||||
|
||||
|
||||
public class SecureFragment extends Fragment {
|
||||
private View view;
|
||||
|
||||
private TextView tv_one_power_minus;
|
||||
private SeekBar seekBar_one_power;
|
||||
private TextView tv_one_power_add;
|
||||
private TextView tv_one_power;
|
||||
private TextView tv_two_power_minus;
|
||||
private SeekBar seekBar_two_power;
|
||||
private TextView tv_two_power_add;
|
||||
private TextView tv_two_power;
|
||||
private TextView tv_link_minus;
|
||||
private EditText et_link;
|
||||
private TextView tv_link_add;
|
||||
private TextView tv_link;
|
||||
private Spinner sp_one_power_protect;
|
||||
private Spinner sp_two_power_protect;
|
||||
private Spinner sp_link_protect;
|
||||
private TextView tv_one_power_protect;
|
||||
private TextView tv_two_power_protect;
|
||||
private TextView tv_link_protect;
|
||||
|
||||
|
||||
@SuppressLint("MissingInflatedId")
|
||||
@ -31,7 +46,9 @@ public class SecureFragment extends Fragment {
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
view = inflater.inflate(R.layout.fragment_secure, container, false);
|
||||
|
||||
initData();
|
||||
initView(view);
|
||||
initOnClick();
|
||||
return view;
|
||||
}
|
||||
|
||||
@ -49,7 +66,28 @@ public class SecureFragment extends Fragment {
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
private void initView() {
|
||||
private void initView(View view) {
|
||||
|
||||
tv_one_power_minus = view.findViewById(R.id.tv_one_power_minus);
|
||||
seekBar_one_power = view.findViewById(R.id.seekBar_one_power);
|
||||
tv_one_power_add = view.findViewById(R.id.tv_one_power_add);
|
||||
tv_one_power = view.findViewById(R.id.tv_one_power);
|
||||
tv_two_power_minus = view.findViewById(R.id.tv_two_power_minus);
|
||||
seekBar_two_power = view.findViewById(R.id.seekBar_two_power);
|
||||
tv_two_power_add = view.findViewById(R.id.tv_two_power_add);
|
||||
tv_two_power = view.findViewById(R.id.tv_two_power);
|
||||
tv_link_minus = view.findViewById(R.id.tv_link_minus);
|
||||
et_link = view.findViewById(R.id.et_link);
|
||||
tv_link_add = view.findViewById(R.id.tv_link_add);
|
||||
tv_link = view.findViewById(R.id.tv_link);
|
||||
sp_one_power_protect = view.findViewById(R.id.sp_one_power_protect);
|
||||
sp_two_power_protect = view.findViewById(R.id.sp_two_power_protect);
|
||||
sp_link_protect = view.findViewById(R.id.sp_link_protect);
|
||||
tv_one_power_protect = view.findViewById(R.id.tv_one_power_protect);
|
||||
tv_two_power_protect = view.findViewById(R.id.tv_two_power_protect);
|
||||
tv_link_protect = view.findViewById(R.id.tv_link_protect);
|
||||
//初始化
|
||||
initSpinners();
|
||||
|
||||
}
|
||||
|
||||
@ -60,13 +98,204 @@ public class SecureFragment extends Fragment {
|
||||
*/
|
||||
private void initOnClick() {
|
||||
|
||||
// 修改一级电压的加减按钮和SeekBar监听事件
|
||||
tv_one_power_minus.setOnClickListener(v -> {
|
||||
int progress = seekBar_one_power.getProgress();
|
||||
if (progress > 0) {
|
||||
seekBar_one_power.setProgress(progress - 1);
|
||||
// 直接更新文本显示
|
||||
double voltage = (progress - 1) * 0.5;
|
||||
tv_one_power.setText(String.format("%.1fV", voltage));
|
||||
}
|
||||
});
|
||||
|
||||
tv_one_power_add.setOnClickListener(v -> {
|
||||
int progress = seekBar_one_power.getProgress();
|
||||
if (progress < 100) {
|
||||
seekBar_one_power.setProgress(progress + 1);
|
||||
// 直接更新文本显示
|
||||
double voltage = (progress + 1) * 0.5;
|
||||
tv_one_power.setText(String.format("%.1fV", voltage));
|
||||
}
|
||||
});
|
||||
|
||||
seekBar_one_power.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
// 将进度(0-100)转换为电压值(0-50.0V)
|
||||
double voltage = progress * 0.5;
|
||||
tv_one_power.setText(String.format("%.1fV", voltage));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
});
|
||||
|
||||
// 修改二级电压的加减按钮和SeekBar监听事件
|
||||
tv_two_power_minus.setOnClickListener(v -> {
|
||||
int progress = seekBar_two_power.getProgress();
|
||||
if (progress > 0) {
|
||||
seekBar_two_power.setProgress(progress - 1);
|
||||
// 直接更新文本显示
|
||||
double voltage = (progress - 1) * 0.5;
|
||||
tv_two_power.setText(String.format("%.1fV", voltage));
|
||||
}
|
||||
});
|
||||
|
||||
tv_two_power_add.setOnClickListener(v -> {
|
||||
int progress = seekBar_two_power.getProgress();
|
||||
if (progress < 100) {
|
||||
seekBar_two_power.setProgress(progress + 1);
|
||||
// 直接更新文本显示
|
||||
double voltage = (progress + 1) * 0.5;
|
||||
tv_two_power.setText(String.format("%.1fV", voltage));
|
||||
}
|
||||
});
|
||||
|
||||
seekBar_two_power.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
// 将进度(0-100)转换为电压值(0-50.0V)
|
||||
double voltage = progress * 0.5;
|
||||
tv_two_power.setText(String.format("%.1fV", voltage));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
tv_link_minus.setOnClickListener(v -> {
|
||||
try {
|
||||
String currentText = et_link.getText().toString().trim();
|
||||
if (!currentText.isEmpty()) {
|
||||
int currentValue = Integer.parseInt(currentText);
|
||||
if (currentValue > 0) { // 防止出现负数,可根据需要调整
|
||||
et_link.setText(String.valueOf(currentValue - 1));
|
||||
}
|
||||
} else {
|
||||
et_link.setText("0");
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
et_link.setText("0");
|
||||
}
|
||||
});
|
||||
|
||||
tv_link_add.setOnClickListener(v -> {
|
||||
try {
|
||||
String currentText = et_link.getText().toString().trim();
|
||||
if (!currentText.isEmpty()) {
|
||||
int currentValue = Integer.parseInt(currentText);
|
||||
et_link.setText(String.valueOf(currentValue + 1));
|
||||
} else {
|
||||
et_link.setText("1");
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
et_link.setText("1");
|
||||
}
|
||||
});
|
||||
|
||||
// 为Spinner设置选择监听器
|
||||
sp_one_power_protect.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
tv_one_power_protect.setText(parent.getItemAtPosition(position).toString());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
// 什么都不做
|
||||
}
|
||||
});
|
||||
|
||||
sp_two_power_protect.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
|
||||
tv_two_power_protect.setText(parent.getItemAtPosition(position).toString());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
// 什么都不做
|
||||
}
|
||||
});
|
||||
|
||||
sp_link_protect.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
tv_link_protect.setText(parent.getItemAtPosition(position).toString());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
// 什么都不做
|
||||
}
|
||||
});
|
||||
|
||||
tv_one_power_protect.setOnClickListener(v -> {
|
||||
|
||||
sp_one_power_protect.performClick();
|
||||
|
||||
});
|
||||
|
||||
tv_two_power_protect.setOnClickListener(v -> {
|
||||
|
||||
sp_two_power_protect.performClick();
|
||||
|
||||
});
|
||||
|
||||
tv_link_protect.setOnClickListener(v -> {
|
||||
|
||||
sp_link_protect.performClick();
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void initSpinners() {
|
||||
// 一级电压保护动作Spinner
|
||||
String[] onePowerOptions = {"返航", "降落", "继续飞行"};
|
||||
ArrayAdapter<String> onePowerAdapter = new ArrayAdapter<>(getContext(),
|
||||
android.R.layout.simple_spinner_item, onePowerOptions);
|
||||
onePowerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
sp_one_power_protect.setAdapter(onePowerAdapter);
|
||||
|
||||
// 二级电压保护动作Spinner
|
||||
String[] twoPowerOptions = {"降落"};
|
||||
ArrayAdapter<String> twoPowerAdapter = new ArrayAdapter<>(getContext(),
|
||||
android.R.layout.simple_spinner_item, twoPowerOptions);
|
||||
twoPowerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
sp_two_power_protect.setAdapter(twoPowerAdapter);
|
||||
|
||||
// 链路保护动作Spinner
|
||||
String[] linkOptions = {"返航", "继续飞行"};
|
||||
ArrayAdapter<String> linkAdapter = new ArrayAdapter<>(getContext(),
|
||||
android.R.layout.simple_spinner_item, linkOptions);
|
||||
linkAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
sp_link_protect.setAdapter(linkAdapter);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
initData();
|
||||
initView();
|
||||
initOnClick();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,7 +34,9 @@ public class SensorFragment extends Fragment {
|
||||
// Inflate the layout for this fragment
|
||||
view = inflater.inflate(R.layout.fragment_sensor, container, false);
|
||||
|
||||
|
||||
initData();
|
||||
initView(view);
|
||||
initOnClick();
|
||||
return view;
|
||||
}
|
||||
|
||||
@ -785,9 +787,7 @@ public class SensorFragment extends Fragment {
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
initData();
|
||||
initView(view);
|
||||
initOnClick();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -86,9 +86,9 @@ public class SettingsFragment extends Fragment {
|
||||
|
||||
|
||||
view = inflater.inflate(R.layout.fragment_settings, container, false);
|
||||
|
||||
|
||||
|
||||
initData();
|
||||
initView(view);
|
||||
initOnClick();
|
||||
return view;
|
||||
}
|
||||
|
||||
@ -140,7 +140,6 @@ public class SettingsFragment extends Fragment {
|
||||
selectIndex_item = 0;
|
||||
paramsList.get(0).setSelect(true);
|
||||
if (paramAdapter != null) {
|
||||
MyTool.hideBottomNavigationBar(getActivity());
|
||||
paramAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@ -338,7 +337,7 @@ public class SettingsFragment extends Fragment {
|
||||
rl_password.setVisibility(View.GONE);
|
||||
ViewTool.closeKeyboard(getActivity());
|
||||
}
|
||||
MyTool.hideBottomNavigationBar(getActivity());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -377,7 +376,7 @@ public class SettingsFragment extends Fragment {
|
||||
@Override
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||
MyTool.hideBottomNavigationBar(getActivity());
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -448,7 +447,7 @@ public class SettingsFragment extends Fragment {
|
||||
}
|
||||
}
|
||||
if (getActivity() != null) {
|
||||
MyTool.hideBottomNavigationBar(getActivity());
|
||||
|
||||
}
|
||||
ProgressDialogUtil.dismissProgressDialog();
|
||||
} catch (InterruptedException e) {
|
||||
@ -471,9 +470,7 @@ public class SettingsFragment extends Fragment {
|
||||
// myReceiver_PARAM_VALUE.isReceiverRegistered = false;
|
||||
// }
|
||||
|
||||
initData();
|
||||
initView(view);
|
||||
initOnClick();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,111 @@
|
||||
package com.example.longyi_groundstation.Main.View;
|
||||
|
||||
import static com.example.longyi_groundstation.MAVLink.enums.MAV_CMD.MAV_CMD_NAV_TAKEOFF;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.view.LayoutInflater;
|
||||
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;
|
||||
|
||||
import com.example.longyi_groundstation.MAVLink.common.msg_command_long;
|
||||
import com.example.longyi_groundstation.Main.Service.MyBoundService;
|
||||
import com.example.longyi_groundstation.Main.Void.FlyVoid;
|
||||
import com.example.longyi_groundstation.Main.Void.MyTool;
|
||||
import com.example.longyi_groundstation.R;
|
||||
|
||||
public class BombingDialog {
|
||||
|
||||
private final Activity context;
|
||||
private String title;
|
||||
private String message;
|
||||
private String positiveButtonText;
|
||||
|
||||
private FlyVoid flyVoid = new FlyVoid();
|
||||
|
||||
|
||||
public BombingDialog(Activity context) {
|
||||
this.context = context;
|
||||
this.title = "投弹";
|
||||
this.message = "";
|
||||
this.positiveButtonText = "确定";
|
||||
}
|
||||
|
||||
// 设置弹窗标题
|
||||
public BombingDialog setTitle(String title) {
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
// 设置弹窗内容
|
||||
public BombingDialog setMessage(String message) {
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
// 设置确认按钮文字
|
||||
public BombingDialog setPositiveButtonText(String text) {
|
||||
this.positiveButtonText = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
// 显示弹窗
|
||||
public void show() {
|
||||
MyTool.hideBottomNavigationBar( context);
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
|
||||
// 使用自定义布局
|
||||
View view = LayoutInflater.from(context).inflate(R.layout.dialog_bombing, null);
|
||||
@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_height = view.findViewById(R.id.et_height);
|
||||
|
||||
|
||||
// 添加日志
|
||||
builder.setView(view);
|
||||
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
|
||||
// 设置宽高
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
WindowManager.LayoutParams layoutParams = window.getAttributes();
|
||||
layoutParams.width = MyTool.dpToPx(context, 300); // 或具体像素值
|
||||
layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT; // 或具体像素值
|
||||
window.setAttributes(layoutParams);
|
||||
window.setBackgroundDrawableResource(R.drawable.ffffffff_4round_bg);
|
||||
}
|
||||
|
||||
unlockView.setText("滑动执行");
|
||||
unlockView.setOnUnlockListener(new SlideToUnlockView.OnUnlockListener() {
|
||||
@Override
|
||||
public void onUnlock() {
|
||||
// 发送命令
|
||||
// flyVoid.sendMavlinkMessage(MyBoundService.type,command);
|
||||
flyVoid.requestBombing(et_height.getText().toString());
|
||||
|
||||
dialog.dismiss();
|
||||
// 滑动到阈值后触发(如关闭对话框或执行操作)
|
||||
Toast.makeText(context, "操作已确认", Toast.LENGTH_SHORT).show();
|
||||
MyTool.hideBottomNavigationBar(context);
|
||||
}
|
||||
});
|
||||
|
||||
;
|
||||
//取消按钮
|
||||
tvMessage.setOnClickListener(v -> {
|
||||
dialog.dismiss();
|
||||
MyTool.hideBottomNavigationBar(context);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,136 @@
|
||||
// 修改 CustomSeekBar.java 文件
|
||||
|
||||
package com.example.longyi_groundstation.Main.View;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
public class CustomSeekBar extends View {
|
||||
private Paint backgroundPaint;
|
||||
private Paint progressPaint;
|
||||
private Paint thumbPaint;
|
||||
private Paint progressBgPaint;
|
||||
|
||||
private float progress = 0f; // 0.0f to 1.0f
|
||||
private float thumbRadius = 15f; // 减小拖拽按钮半径(从30f改为15f)
|
||||
private float barHeight = 8f; // 减小进度条高度(从12f改为8f)
|
||||
private float cornerRadius = 4f; // 调整圆角半径
|
||||
|
||||
private OnProgressChangeListener listener;
|
||||
|
||||
public interface OnProgressChangeListener {
|
||||
void onProgressChanged(float progress);
|
||||
}
|
||||
|
||||
public CustomSeekBar(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public CustomSeekBar(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public CustomSeekBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
// 背景画笔(进度条背景)
|
||||
backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
backgroundPaint.setColor(Color.parseColor("#404040"));
|
||||
|
||||
// 进度背景画笔
|
||||
progressBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
progressBgPaint.setColor(Color.parseColor("#606060"));
|
||||
|
||||
// 进度画笔
|
||||
progressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
progressPaint.setColor(Color.parseColor("#4CAF50")); // 绿色进度条
|
||||
|
||||
// 拖拽按钮画笔
|
||||
thumbPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
thumbPaint.setColor(Color.WHITE);
|
||||
thumbPaint.setShadowLayer(4.0f, 0.0f, 2.0f, Color.argb(100, 0, 0, 0)); // 添加阴影效果
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
|
||||
float width = getWidth();
|
||||
float height = getHeight();
|
||||
float centerY = height / 2f;
|
||||
|
||||
// 绘制进度条背景
|
||||
RectF bgRect = new RectF(thumbRadius, centerY - barHeight/2, width - thumbRadius, centerY + barHeight/2);
|
||||
canvas.drawRoundRect(bgRect, cornerRadius, cornerRadius, backgroundPaint);
|
||||
|
||||
// 绘制进度背景
|
||||
float progressWidth = (width - 2 * thumbRadius) * progress;
|
||||
if (progressWidth > 0) {
|
||||
RectF progressRect = new RectF(thumbRadius, centerY - barHeight/2, thumbRadius + progressWidth, centerY + barHeight/2);
|
||||
canvas.drawRoundRect(progressRect, cornerRadius, cornerRadius, progressPaint);
|
||||
}
|
||||
|
||||
// 绘制拖拽按钮
|
||||
float thumbX = thumbRadius + progressWidth;
|
||||
canvas.drawCircle(thumbX, centerY, thumbRadius, thumbPaint);
|
||||
|
||||
// 注意:这里移除了百分比文字的绘制
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
float x = event.getX();
|
||||
float width = getWidth();
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
case MotionEvent.ACTION_UP:
|
||||
// 限制x在有效范围内
|
||||
x = Math.max(thumbRadius, Math.min(width - thumbRadius, x));
|
||||
progress = (x - thumbRadius) / (width - 2 * thumbRadius);
|
||||
|
||||
// 确保进度在0-1范围内
|
||||
progress = Math.max(0f, Math.min(1f, progress));
|
||||
|
||||
invalidate();
|
||||
|
||||
if (listener != null) {
|
||||
listener.onProgressChanged(progress);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
public void setProgress(float progress) {
|
||||
this.progress = Math.max(0f, Math.min(1f, progress));
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public float getProgress() {
|
||||
return progress;
|
||||
}
|
||||
|
||||
public void setOnProgressChangeListener(OnProgressChangeListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,319 @@
|
||||
package com.example.longyi_groundstation.Main.View;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.Region;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class DpadView extends View {
|
||||
|
||||
private Paint paint;
|
||||
private Path upButtonPath;
|
||||
private Path downButtonPath;
|
||||
private Path leftButtonPath;
|
||||
private Path rightButtonPath;
|
||||
|
||||
// Regions for touch detection
|
||||
private Region upButtonRegion;
|
||||
private Region downButtonRegion;
|
||||
private Region leftButtonRegion;
|
||||
private Region rightButtonRegion;
|
||||
|
||||
private int upButtonColor = Color.GRAY;
|
||||
private int downButtonColor = Color.GRAY;
|
||||
private int leftButtonColor = Color.GRAY;
|
||||
private int rightButtonColor = Color.GRAY;
|
||||
|
||||
private OnDpadButtonClickListener listener;
|
||||
|
||||
// Button states (pressed or not)
|
||||
private boolean upPressed = false;
|
||||
private boolean downPressed = false;
|
||||
private boolean leftPressed = false;
|
||||
private boolean rightPressed = false;
|
||||
|
||||
public DpadView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public DpadView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public DpadView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
paint = new Paint();
|
||||
paint.setAntiAlias(true);
|
||||
paint.setStyle(Paint.Style.FILL);
|
||||
|
||||
upButtonPath = new Path();
|
||||
downButtonPath = new Path();
|
||||
leftButtonPath = new Path();
|
||||
rightButtonPath = new Path();
|
||||
|
||||
upButtonRegion = new Region();
|
||||
downButtonRegion = new Region();
|
||||
leftButtonRegion = new Region();
|
||||
rightButtonRegion = new Region();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
int centerX = width / 2;
|
||||
int centerY = height / 2;
|
||||
int buttonWidth = Math.min(width, height) / 5;
|
||||
int buttonHeight = Math.min(width, height) / 3;
|
||||
|
||||
// Clear paths
|
||||
upButtonPath.reset();
|
||||
downButtonPath.reset();
|
||||
leftButtonPath.reset();
|
||||
rightButtonPath.reset();
|
||||
|
||||
// Draw up button (rectangle)
|
||||
upButtonPath.addRect(
|
||||
centerX - buttonWidth/2,
|
||||
centerY - buttonHeight/2 - buttonHeight/3,
|
||||
centerX + buttonWidth/2,
|
||||
centerY - buttonHeight/2 + buttonHeight/3,
|
||||
Path.Direction.CW
|
||||
);
|
||||
|
||||
paint.setColor(upPressed ? darkenColor(upButtonColor) : upButtonColor);
|
||||
canvas.drawPath(upButtonPath, paint);
|
||||
|
||||
// Draw down button (rectangle)
|
||||
downButtonPath.addRect(
|
||||
centerX - buttonWidth/2,
|
||||
centerY + buttonHeight/2 - buttonHeight/3,
|
||||
centerX + buttonWidth/2,
|
||||
centerY + buttonHeight/2 + buttonHeight/3,
|
||||
Path.Direction.CW
|
||||
);
|
||||
|
||||
paint.setColor(downPressed ? darkenColor(downButtonColor) : downButtonColor);
|
||||
canvas.drawPath(downButtonPath, paint);
|
||||
|
||||
// Draw left button (rectangle)
|
||||
leftButtonPath.addRect(
|
||||
centerX - buttonHeight/2 - buttonHeight/3,
|
||||
centerY - buttonWidth/2,
|
||||
centerX - buttonHeight/2 + buttonHeight/3,
|
||||
centerY + buttonWidth/2,
|
||||
Path.Direction.CW
|
||||
);
|
||||
|
||||
paint.setColor(leftPressed ? darkenColor(leftButtonColor) : leftButtonColor);
|
||||
canvas.drawPath(leftButtonPath, paint);
|
||||
|
||||
// Draw right button (rectangle)
|
||||
rightButtonPath.addRect(
|
||||
centerX + buttonHeight/2 - buttonHeight/3,
|
||||
centerY - buttonWidth/2,
|
||||
centerX + buttonHeight/2 + buttonHeight/3,
|
||||
centerY + buttonWidth/2,
|
||||
Path.Direction.CW
|
||||
);
|
||||
|
||||
paint.setColor(rightPressed ? darkenColor(rightButtonColor) : rightButtonColor);
|
||||
canvas.drawPath(rightButtonPath, paint);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
|
||||
// Update regions when size changes
|
||||
updateButtonRegions();
|
||||
}
|
||||
|
||||
private void updateButtonRegions() {
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
int centerX = width / 2;
|
||||
int centerY = height / 2;
|
||||
int buttonWidth = Math.min(width, height) / 5;
|
||||
int buttonHeight = Math.min(width, height) / 3;
|
||||
|
||||
// Define regions for touch detection
|
||||
Path tempPath = new Path();
|
||||
|
||||
// Up button region
|
||||
tempPath.reset();
|
||||
tempPath.addRect(
|
||||
centerX - buttonWidth/2,
|
||||
centerY - buttonHeight/2 - buttonHeight/3,
|
||||
centerX + buttonWidth/2,
|
||||
centerY - buttonHeight/2 + buttonHeight/3,
|
||||
Path.Direction.CW
|
||||
);
|
||||
upButtonRegion.setPath(tempPath, new Region(0, 0, getWidth(), getHeight()));
|
||||
|
||||
// Down button region
|
||||
tempPath.reset();
|
||||
tempPath.addRect(
|
||||
centerX - buttonWidth/2,
|
||||
centerY + buttonHeight/2 - buttonHeight/3,
|
||||
centerX + buttonWidth/2,
|
||||
centerY + buttonHeight/2 + buttonHeight/3,
|
||||
Path.Direction.CW
|
||||
);
|
||||
downButtonRegion.setPath(tempPath, new Region(0, 0, getWidth(), getHeight()));
|
||||
|
||||
// Left button region
|
||||
tempPath.reset();
|
||||
tempPath.addRect(
|
||||
centerX - buttonHeight/2 - buttonHeight/3,
|
||||
centerY - buttonWidth/2,
|
||||
centerX - buttonHeight/2 + buttonHeight/3,
|
||||
centerY + buttonWidth/2,
|
||||
Path.Direction.CW
|
||||
);
|
||||
leftButtonRegion.setPath(tempPath, new Region(0, 0, getWidth(), getHeight()));
|
||||
|
||||
// Right button region
|
||||
tempPath.reset();
|
||||
tempPath.addRect(
|
||||
centerX + buttonHeight/2 - buttonHeight/3,
|
||||
centerY - buttonWidth/2,
|
||||
centerX + buttonHeight/2 + buttonHeight/3,
|
||||
centerY + buttonWidth/2,
|
||||
Path.Direction.CW
|
||||
);
|
||||
rightButtonRegion.setPath(tempPath, new Region(0, 0, getWidth(), getHeight()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
float x = event.getX();
|
||||
float y = event.getY();
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
handleTouch(x, y, true);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
handleTouch(x, y, false);
|
||||
// Reset all buttons
|
||||
upPressed = false;
|
||||
downPressed = false;
|
||||
leftPressed = false;
|
||||
rightPressed = false;
|
||||
invalidate();
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void handleTouch(float x, float y, boolean pressed) {
|
||||
boolean upWasPressed = upPressed;
|
||||
boolean downWasPressed = downPressed;
|
||||
boolean leftWasPressed = leftPressed;
|
||||
boolean rightWasPressed = rightPressed;
|
||||
|
||||
// Check which button is pressed using regions
|
||||
upPressed = upButtonRegion.contains((int)x, (int)y) && pressed;
|
||||
downPressed = downButtonRegion.contains((int)x, (int)y) && pressed;
|
||||
leftPressed = leftButtonRegion.contains((int)x, (int)y) && pressed;
|
||||
rightPressed = rightButtonRegion.contains((int)x, (int)y) && pressed;
|
||||
|
||||
// Notify listeners of changes
|
||||
if (listener != null) {
|
||||
if (upPressed && !upWasPressed) {
|
||||
listener.onUpButtonClicked();
|
||||
} else if (!upPressed && upWasPressed) {
|
||||
listener.onUpButtonReleased();
|
||||
}
|
||||
|
||||
if (downPressed && !downWasPressed) {
|
||||
listener.onDownButtonClicked();
|
||||
} else if (!downPressed && downWasPressed) {
|
||||
listener.onDownButtonReleased();
|
||||
}
|
||||
|
||||
if (leftPressed && !leftWasPressed) {
|
||||
listener.onLeftButtonClicked();
|
||||
} else if (!leftPressed && leftWasPressed) {
|
||||
listener.onLeftButtonReleased();
|
||||
}
|
||||
|
||||
if (rightPressed && !rightWasPressed) {
|
||||
listener.onRightButtonClicked();
|
||||
} else if (!rightPressed && rightWasPressed) {
|
||||
listener.onRightButtonReleased();
|
||||
}
|
||||
}
|
||||
|
||||
// Redraw if any state changed
|
||||
if (upWasPressed != upPressed || downWasPressed != downPressed ||
|
||||
leftWasPressed != leftPressed || rightWasPressed != rightPressed) {
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
// Helper method to darken color when pressed
|
||||
private int darkenColor(int color) {
|
||||
float[] hsv = new float[3];
|
||||
Color.colorToHSV(color, hsv);
|
||||
hsv[2] *= 0.8f; // Reduce brightness
|
||||
return Color.HSVToColor(hsv);
|
||||
}
|
||||
|
||||
// Set button colors
|
||||
public void setUpButtonColor(int color) {
|
||||
this.upButtonColor = color;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setDownButtonColor(int color) {
|
||||
this.downButtonColor = color;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setLeftButtonColor(int color) {
|
||||
this.leftButtonColor = color;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setRightButtonColor(int color) {
|
||||
this.rightButtonColor = color;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
// Set click listener
|
||||
public void setOnDpadButtonClickListener(OnDpadButtonClickListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
// Interface for button click events
|
||||
public interface OnDpadButtonClickListener {
|
||||
void onUpButtonClicked();
|
||||
void onUpButtonReleased();
|
||||
void onDownButtonClicked();
|
||||
void onDownButtonReleased();
|
||||
void onLeftButtonClicked();
|
||||
void onLeftButtonReleased();
|
||||
void onRightButtonClicked();
|
||||
void onRightButtonReleased();
|
||||
}
|
||||
}
|
||||
@ -81,27 +81,12 @@ public class LandDialog {
|
||||
}
|
||||
|
||||
|
||||
unlockView.setText("滑动返航");
|
||||
unlockView.setText("滑动降落");
|
||||
unlockView.setOnUnlockListener(new SlideToUnlockView.OnUnlockListener() {
|
||||
@Override
|
||||
public void onUnlock() {
|
||||
// 构造命令
|
||||
// msg_command_long command = new msg_command_long();
|
||||
// command.target_system = 1; // 目标系统ID(飞控)
|
||||
// command.target_component = 1; // 目标组件ID
|
||||
// command.command = MAV_CMD_NAV_RETURN_TO_LAUNCH; // 返航命令
|
||||
// command.confirmation = 0; // 确认位
|
||||
// command.param1 = 0; // 通常不需要参数
|
||||
// command.param2 = 0;
|
||||
// command.param3 = 0;
|
||||
// command.param4 = 0;
|
||||
// command.param5 = 0;
|
||||
// command.param6 = 0;
|
||||
// command.param7 = 0;
|
||||
//
|
||||
// // 发送命令
|
||||
// flyVoid.sendMavlinkMessage(MyBoundService.type, command);
|
||||
|
||||
flyVoid.requestLand();
|
||||
MyTool.hideBottomNavigationBar( context);
|
||||
dialog.dismiss();
|
||||
// 滑动到阈值后触发(如关闭对话框或执行操作)
|
||||
|
||||
@ -16,7 +16,7 @@ public class SlideToUnlockView extends View {
|
||||
private RectF thumbRect = new RectF();
|
||||
private OnUnlockListener listener;
|
||||
private int bgColor = Color.parseColor("#cfcfcf");
|
||||
private int activeColor = Color.parseColor("#49B6E7");
|
||||
private int activeColor = Color.parseColor("#029A45");
|
||||
private float thumbSize; // 滑块尺寸
|
||||
private float minX, maxX; // 滑块X轴边界
|
||||
|
||||
@ -44,7 +44,7 @@ public class SlideToUnlockView extends View {
|
||||
|
||||
textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
textPaint.setColor(Color.WHITE);
|
||||
textPaint.setTextSize(dpToPx(14));
|
||||
textPaint.setTextSize(dpToPx(12));
|
||||
textPaint.setTextAlign(Paint.Align.CENTER);
|
||||
|
||||
reboundAnimator = ValueAnimator.ofFloat(0, 1);
|
||||
|
||||
@ -94,22 +94,21 @@ public class TakeOffDialog {
|
||||
unlockView.setOnUnlockListener(new SlideToUnlockView.OnUnlockListener() {
|
||||
@Override
|
||||
public void onUnlock() {
|
||||
msg_command_long command = new msg_command_long();
|
||||
command.target_system = 1;
|
||||
command.target_component = 1;
|
||||
command.command = MAV_CMD_NAV_TAKEOFF;
|
||||
command.confirmation = 0;
|
||||
command.param1 = 0;
|
||||
command.param2 = 0;
|
||||
command.param3 = 0;
|
||||
command.param4 = 0;
|
||||
command.param5 = 0;
|
||||
command.param6 = 0;
|
||||
command.param7 = Float.parseFloat(et_height.getText().toString());
|
||||
|
||||
// 发送命令
|
||||
flyVoid.sendMavlinkMessage(MyBoundService.type,command);
|
||||
|
||||
// msg_command_long command = new msg_command_long();
|
||||
// command.target_system = 1;
|
||||
// command.target_component = 1;
|
||||
// command.command = MAV_CMD_NAV_TAKEOFF;
|
||||
// command.confirmation = 0;
|
||||
// command.param1 = 0;
|
||||
// command.param2 = 0;
|
||||
// command.param3 = 0;
|
||||
// command.param4 = 0;
|
||||
// command.param5 = 0;
|
||||
// command.param6 = 0;
|
||||
// command.param7 = Float.parseFloat(et_height.getText().toString());
|
||||
// // 发送命令
|
||||
// flyVoid.sendMavlinkMessage(MyBoundService.type,command);
|
||||
flyVoid.requestTakeOff(et_height.getText().toString());
|
||||
dialog.dismiss();
|
||||
// 滑动到阈值后触发(如关闭对话框或执行操作)
|
||||
Toast.makeText(context, "操作已确认", Toast.LENGTH_SHORT).show();
|
||||
|
||||
@ -89,25 +89,26 @@ public class TurnBackDialog {
|
||||
}
|
||||
|
||||
|
||||
unlockView.setText("滑动降落");
|
||||
unlockView.setText("滑动返航");
|
||||
unlockView.setOnUnlockListener(new SlideToUnlockView.OnUnlockListener() {
|
||||
@Override
|
||||
public void onUnlock() {
|
||||
// 构造命令
|
||||
msg_command_long command = new msg_command_long();
|
||||
command.target_system = 1;
|
||||
command.target_component = 1;
|
||||
command.command = MAV_CMD_NAV_LAND;
|
||||
command.confirmation = 0;
|
||||
command.param1 = 0;
|
||||
command.param2 = 0;
|
||||
command.param3 = 0;
|
||||
command.param4 = 0;
|
||||
command.param5 = 0;
|
||||
command.param6 = 0;
|
||||
command.param7 = 0;
|
||||
// 发送命令
|
||||
flyVoid.sendMavlinkMessage(MyBoundService.type, command);
|
||||
// // 构造命令
|
||||
// msg_command_long command = new msg_command_long();
|
||||
// command.target_system = 1;
|
||||
// command.target_component = 1;
|
||||
// command.command = MAV_CMD_NAV_LAND;
|
||||
// command.confirmation = 0;
|
||||
// command.param1 = 0;
|
||||
// command.param2 = 0;
|
||||
// command.param3 = 0;
|
||||
// command.param4 = 0;
|
||||
// command.param5 = 0;
|
||||
// command.param6 = 0;
|
||||
// command.param7 = 0;
|
||||
// // 发送命令
|
||||
// flyVoid.sendMavlinkMessage(MyBoundService.type, command);
|
||||
flyVoid.requestTurnBack();
|
||||
MyTool.hideBottomNavigationBar( context);
|
||||
dialog.dismiss();
|
||||
// 滑动到阈值后触发(如关闭对话框或执行操作)
|
||||
|
||||
@ -13,6 +13,7 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.amap.api.maps.MapView;
|
||||
import com.example.longyi_groundstation.Main.View.AttitudeIndicatorView;
|
||||
import com.example.longyi_groundstation.Main.View.CircularLinearLayout;
|
||||
import com.example.longyi_groundstation.Main.View.DpadView;
|
||||
import com.example.longyi_groundstation.R;
|
||||
import com.skydroid.fpvplayer.FPVWidget;
|
||||
|
||||
@ -46,7 +47,7 @@ public class AllView {
|
||||
public LinearLayout ll_icon_land;
|
||||
public LinearLayout ll_mode_select;
|
||||
public RecyclerView rv_error_list;
|
||||
public LinearLayout ll_left_layout;
|
||||
public LinearLayout ll_left_error_layout;
|
||||
public LinearLayout ll_setting;
|
||||
public ImageView iv_logo;
|
||||
public TextView tv_param_load;
|
||||
@ -64,6 +65,34 @@ public class AllView {
|
||||
public LinearLayout ll_searchlight;
|
||||
public LinearLayout ll_thoroughfare;
|
||||
public LinearLayout ll_hook;
|
||||
public ImageView iv_ptz_top;
|
||||
public ImageView iv_ptz_left;
|
||||
public ImageView iv_ptz_right;
|
||||
public ImageView iv_ptz_bottom;
|
||||
public LinearLayout ll_PTZ_one_center;
|
||||
public LinearLayout ll_PTZ_amplify;
|
||||
public LinearLayout ll_PTZ_reduce;
|
||||
public LinearLayout ll_PTZ_focus_amplify;
|
||||
public LinearLayout ll_PTZ_focus_reduce;
|
||||
public LinearLayout ll_ptz_ctrl;
|
||||
public LinearLayout ll_ptz_fun;
|
||||
public LinearLayout ll_PTZ_one_bottom;
|
||||
public LinearLayout ll_open_layout;
|
||||
public LinearLayout ll_text;
|
||||
public LinearLayout ll_link;
|
||||
public LinearLayout ll_link_save;
|
||||
public LinearLayout ll_link_fun1;
|
||||
public LinearLayout ll_link_fun2;
|
||||
public LinearLayout ll_link_back;
|
||||
public LinearLayout ll_create_link_layout;
|
||||
public RecyclerView rv_create_link_list;
|
||||
public LinearLayout ll_all_link_layout;
|
||||
public RecyclerView rv_all_link_list;
|
||||
public LinearLayout ll_link_start;
|
||||
public LinearLayout ll_link_start_fun1;
|
||||
public LinearLayout ll_link_start_fun2;
|
||||
public LinearLayout ll_link_start_back;
|
||||
|
||||
|
||||
|
||||
public AllView(Activity activity) {
|
||||
@ -97,7 +126,7 @@ public class AllView {
|
||||
ll_icon_land = activity.findViewById(R.id.ll_icon_land);
|
||||
ll_mode_select = activity.findViewById(R.id.ll_mode_select);
|
||||
rv_error_list = activity.findViewById(R.id.rv_error_list);
|
||||
ll_left_layout = activity.findViewById(R.id.ll_left_layout);
|
||||
ll_left_error_layout = activity.findViewById(R.id.ll_left_error_layout);
|
||||
ll_setting = activity.findViewById(R.id.ll_setting);
|
||||
iv_logo = activity.findViewById(R.id.iv_logo);
|
||||
tv_param_load = activity.findViewById(R.id.tv_param_load);
|
||||
@ -115,10 +144,34 @@ public class AllView {
|
||||
ll_searchlight = activity.findViewById(R.id.ll_searchlight);
|
||||
ll_thoroughfare = activity.findViewById(R.id.ll_thoroughfare);
|
||||
ll_hook = activity.findViewById(R.id.ll_hook);
|
||||
iv_ptz_top = activity.findViewById(R.id.iv_ptz_top);
|
||||
iv_ptz_left = activity.findViewById(R.id.iv_ptz_left);
|
||||
iv_ptz_right = activity.findViewById(R.id.iv_ptz_right);
|
||||
iv_ptz_bottom = activity.findViewById(R.id.iv_ptz_bottom);
|
||||
ll_PTZ_one_center = activity.findViewById(R.id.ll_PTZ_one_center);
|
||||
ll_PTZ_amplify = activity.findViewById(R.id.ll_PTZ_amplify);
|
||||
ll_PTZ_reduce = activity.findViewById(R.id.ll_PTZ_reduce);
|
||||
ll_PTZ_focus_amplify = activity.findViewById(R.id.ll_PTZ_focus_amplify);
|
||||
ll_PTZ_focus_reduce = activity.findViewById(R.id.ll_PTZ_focus_reduce);
|
||||
ll_ptz_ctrl = activity.findViewById(R.id.ll_ptz_ctrl);
|
||||
ll_ptz_fun = activity.findViewById(R.id.ll_ptz_fun);
|
||||
ll_PTZ_one_bottom = activity.findViewById(R.id.ll_PTZ_one_bottom);
|
||||
ll_open_layout = activity.findViewById(R.id.ll_open_layout);
|
||||
ll_text= activity.findViewById(R.id.ll_text);
|
||||
ll_link = activity.findViewById(R.id.ll_link);
|
||||
ll_link_save = activity.findViewById(R.id.ll_link_save);
|
||||
ll_link_fun1 = activity.findViewById(R.id.ll_link_fun1);
|
||||
ll_link_fun2 = activity.findViewById(R.id.ll_link_fun2);
|
||||
ll_link_back = activity.findViewById(R.id.ll_link_back);
|
||||
ll_create_link_layout = activity.findViewById(R.id.ll_create_link_layout);
|
||||
rv_create_link_list = activity.findViewById(R.id.rv_create_link_list);
|
||||
ll_all_link_layout = activity.findViewById(R.id.ll_all_link_layout);
|
||||
rv_all_link_list = activity.findViewById(R.id.rv_all_link_list);
|
||||
ll_link_start = activity.findViewById(R.id.ll_link_start);
|
||||
ll_link_start_fun1 = activity.findViewById(R.id.ll_link_start_fun1);
|
||||
ll_link_start_fun2 = activity.findViewById(R.id.ll_link_start_fun2);
|
||||
ll_link_start_back = activity.findViewById(R.id.ll_link_start_back);
|
||||
|
||||
|
||||
|
||||
|
||||
// iv_line_fly = activity.findViewById(R.id.iv_line_fly);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,65 @@
|
||||
package com.example.longyi_groundstation.Main.Void;
|
||||
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.example.longyi_groundstation.Main.Adapter.AllLinkAdapter;
|
||||
import com.example.longyi_groundstation.Main.Void.XiangTuo.TcpClientUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AllVoid {
|
||||
|
||||
/**
|
||||
* 带重试机制的云台TCP连接方法
|
||||
* 如果连接失败,等待5秒后重试,最多重试3次
|
||||
*
|
||||
* @param tcpClient TcpClientUtil实例
|
||||
* @param host 主机地址
|
||||
* @param port 端口号
|
||||
* @param context 上下文对象,用于显示Toast提示
|
||||
* @param tag 日志标签
|
||||
*/
|
||||
public static void connectToPTZWithRetry(TcpClientUtil tcpClient, String host, int port, android.content.Context context, String tag) {
|
||||
new Thread(() -> {
|
||||
int maxRetries = 3;
|
||||
int retryCount = 0;
|
||||
|
||||
while (retryCount < maxRetries) {
|
||||
try {
|
||||
if (tcpClient != null) {
|
||||
tcpClient.connect(host, port);
|
||||
// 连接成功,跳出循环
|
||||
((android.app.Activity) context).runOnUiThread(() -> {
|
||||
Toast.makeText(context, "云台连接成功", Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
retryCount++;
|
||||
Log.e(tag, "云台连接失败,第" + retryCount + "次重试", e);
|
||||
|
||||
if (retryCount < maxRetries) {
|
||||
((android.app.Activity) context).runOnUiThread(() -> {
|
||||
Toast.makeText(context, "云台连接失败,5秒后重试...", Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
|
||||
try {
|
||||
Thread.sleep(5000); // 等待5秒
|
||||
} catch (InterruptedException ie) {
|
||||
Thread.currentThread().interrupt();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// 最后一次重试也失败了
|
||||
((android.app.Activity) context).runOnUiThread(() -> {
|
||||
Toast.makeText(context, "云台连接失败,请检查设备", Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -1,5 +1,8 @@
|
||||
package com.example.longyi_groundstation.Main.Void;
|
||||
|
||||
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;
|
||||
import static com.example.longyi_groundstation.Main.Service.MyBoundService.type;
|
||||
|
||||
import android.content.Context;
|
||||
@ -40,6 +43,8 @@ public class FlyVoid {
|
||||
// 新增字段:表示参数是否更新完成
|
||||
private static volatile boolean isParamUpdateComplete = false;
|
||||
|
||||
public static int[] parseSerialData = null;
|
||||
|
||||
// 提供一个获取状态的方法
|
||||
public static boolean isParamUpdateComplete() {
|
||||
return isParamUpdateComplete;
|
||||
@ -72,31 +77,6 @@ public class FlyVoid {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通用MAVLink消息发送方法
|
||||
*/
|
||||
public void sendMavlinkMessage(int type,MAVLinkMessage msg) {
|
||||
MAVLinkPacket packet = msg.pack();
|
||||
|
||||
if (type == 0) { // 串口
|
||||
if (MyBoundService.serialHelper != null) {
|
||||
MyBoundService.serialHelper.send(packet.encodePacket());
|
||||
}
|
||||
} else { // UDP
|
||||
try {
|
||||
InetAddress targetAddress = InetAddress.getByName("127.0.0.1"); // 改为飞控IP
|
||||
DatagramPacket udpPacket = new DatagramPacket(
|
||||
packet.encodePacket(),
|
||||
packet.encodePacket().length,
|
||||
targetAddress,
|
||||
14553 // MAVLink标准端口
|
||||
);
|
||||
MyBoundService.serverSocket.send(udpPacket);
|
||||
} catch (Exception e) {
|
||||
Log.e("cuijinggzhou-发送", "发送失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@ -116,9 +96,8 @@ public class FlyVoid {
|
||||
sendMavlinkMessage(type,request);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置参数 (MAVLINK_MSG_ID_PARAM_SET)
|
||||
* 方法:设置参数 (MAVLINK_MSG_ID_PARAM_SET)
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
@ -133,8 +112,27 @@ public class FlyVoid {
|
||||
paramSet.param_type = Short.parseShort(paramType); // 参数类型
|
||||
// 发送命令
|
||||
sendMavlinkMessage(MyBoundService.type,paramSet);
|
||||
paramList.get(paramId).setParam_value(paramValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法:设置参数 (MAVLINK_MSG_ID_PARAM_SET)
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
public void requestParamSet(String paramId,String paramValue) {
|
||||
msg_param_set paramSet = new msg_param_set();
|
||||
paramSet.target_system = 1; // 目标系统ID (飞控)
|
||||
paramSet.target_component = 1; // 目标组件ID
|
||||
// 设置参数ID (最多16字符)
|
||||
byte[] paramIdBytes = paramId.getBytes();
|
||||
System.arraycopy(paramIdBytes, 0, paramSet.param_id, 0, Math.min(paramIdBytes.length, 16));
|
||||
paramSet.param_value = Float.parseFloat(paramValue);// 参数值
|
||||
paramSet.param_type = Short.parseShort(paramList.get(paramId).getParam_type()); // 参数类型
|
||||
// 发送命令
|
||||
sendMavlinkMessage(MyBoundService.type,paramSet);
|
||||
paramList.get(paramId).setParam_value(paramValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法:控制电机旋转 param1=电机ID param3=转速 param4=超时
|
||||
@ -163,13 +161,159 @@ public class FlyVoid {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 方法:起飞指令
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
public void requestTakeOff(String height) {
|
||||
msg_command_long command = new msg_command_long();
|
||||
command.target_system = 1;
|
||||
command.target_component = 1;
|
||||
command.command = MAV_CMD_NAV_TAKEOFF;
|
||||
command.confirmation = 0;
|
||||
command.param1 = 0;
|
||||
command.param2 = 0;
|
||||
command.param3 = 0;
|
||||
command.param4 = 0;
|
||||
command.param5 = 0;
|
||||
command.param6 = 0;
|
||||
command.param7 = Float.parseFloat(height);
|
||||
|
||||
// 发送命令
|
||||
sendMavlinkMessage(MyBoundService.type,command);
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法:返航指令
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
public void requestTurnBack() {
|
||||
// 构造命令
|
||||
msg_command_long command = new msg_command_long();
|
||||
command.target_system = 1;
|
||||
command.target_component = 1;
|
||||
command.command = MAV_CMD_NAV_RETURN_TO_LAUNCH;
|
||||
command.confirmation = 0;
|
||||
command.param1 = 0;
|
||||
command.param2 = 0;
|
||||
command.param3 = 0;
|
||||
command.param4 = 0;
|
||||
command.param5 = 0;
|
||||
command.param6 = 0;
|
||||
command.param7 = 0;
|
||||
|
||||
// 发送命令
|
||||
sendMavlinkMessage(MyBoundService.type,command);
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法:降落指令
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
public void requestLand() {
|
||||
// 构造命令
|
||||
msg_command_long command = new msg_command_long();
|
||||
command.target_system = 1; // 目标系统ID(飞控)
|
||||
command.target_component = 1; // 目标组件ID
|
||||
command.command = MAV_CMD_NAV_LAND; // 返航命令
|
||||
command.confirmation = 0; // 确认位
|
||||
command.param1 = 0; // 通常不需要参数
|
||||
command.param2 = 0;
|
||||
command.param3 = 0;
|
||||
command.param4 = 0;
|
||||
command.param5 = 0;
|
||||
command.param6 = 0;
|
||||
command.param7 = 0;
|
||||
|
||||
// 发送命令
|
||||
sendMavlinkMessage(MyBoundService.type,command);
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法:投弹
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
public void requestBombing(String str) {
|
||||
// 构造命令
|
||||
byte byteData = SerialTool.decStringToHexByte(str);
|
||||
byte byteData2 = SerialTool.calculateChecksum(byteData);
|
||||
byte[] testData = new byte[]{(byte) 0xFF, byteData, byteData2};
|
||||
|
||||
Log.d("串口2发送的数据", SerialTool.bytesToHex(testData));
|
||||
// 发送命令
|
||||
sendMessage_com2(MyBoundService.type,testData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 通用MAVLink消息发送方法-串口1 mavlink通道
|
||||
*/
|
||||
public void sendMavlinkMessage(int type,MAVLinkMessage msg) {
|
||||
MAVLinkPacket packet = msg.pack();
|
||||
|
||||
if (type == 0) { // 串口
|
||||
if (MyBoundService.serialHelper != null) {
|
||||
MyBoundService.serialHelper.send(packet.encodePacket());
|
||||
}
|
||||
} else { // UDP
|
||||
try {
|
||||
InetAddress targetAddress = InetAddress.getByName("127.0.0.1"); // 改为飞控IP
|
||||
DatagramPacket udpPacket = new DatagramPacket(
|
||||
packet.encodePacket(),
|
||||
packet.encodePacket().length,
|
||||
targetAddress,
|
||||
14553 // MAVLink标准端口
|
||||
);
|
||||
MyBoundService.serverSocket.send(udpPacket);
|
||||
} catch (Exception e) {
|
||||
Log.e("cuijinggzhou-发送", "发送失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用MAVLink消息发送方法-串口2 其它硬件通道
|
||||
*/
|
||||
public void sendMessage_com2(int type,byte[] testData) {
|
||||
if (type == 0) { // 串口
|
||||
if (MyBoundService.serialHelper2 != null) {
|
||||
MyBoundService.serialHelper2.send(testData);
|
||||
Log.e("cuijinggzhou-发送", "发送成功 " );
|
||||
}
|
||||
} else { // UDP
|
||||
try {
|
||||
if (MyBoundService.serverSocket2 != null) {
|
||||
InetAddress targetAddress = InetAddress.getByName("127.0.0.1"); // IP
|
||||
DatagramPacket udpPacket = new DatagramPacket(
|
||||
testData,
|
||||
testData.length,
|
||||
targetAddress,
|
||||
13553 // 标准端口
|
||||
);
|
||||
MyBoundService.serverSocket2.send(udpPacket);
|
||||
Log.e("cuijinggzhou-发送", "发送成功 " );
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e("cuijinggzhou-发送", "发送失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 启动定时任务,用于检查 paramList 的加载进度,并更新 tv_param_load 显示
|
||||
*/
|
||||
private static Handler handler = new Handler(Looper.getMainLooper());
|
||||
private static Runnable updateProgressRunnable;
|
||||
private static TextView tvParamLoad; // 假设 tvParamLoad 是用于显示进度的 TextView
|
||||
|
||||
public static void startParamLoadMonitoring(TextView tvParamLoad) {
|
||||
FlyVoid.tvParamLoad = tvParamLoad;
|
||||
|
||||
@ -201,4 +345,6 @@ public class FlyVoid {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,121 @@
|
||||
package com.example.longyi_groundstation.Main.Void;
|
||||
|
||||
import android.view.GestureDetector;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ScaleGestureDetector;
|
||||
import android.view.View;
|
||||
|
||||
import com.example.longyi_groundstation.R;
|
||||
|
||||
public class FpvGestureHandler implements View.OnTouchListener {
|
||||
private GestureDetector gestureDetector;
|
||||
private ScaleGestureDetector scaleGestureDetector;
|
||||
private OnFpvGestureListener gestureListener;
|
||||
private boolean isSwiping = false; // 标记是否正在滑动
|
||||
private float startX, startY; // 记录初始触摸点
|
||||
|
||||
public FpvGestureHandler(View view) {
|
||||
gestureDetector = new GestureDetector(view.getContext(), new GestureListener());
|
||||
scaleGestureDetector = new ScaleGestureDetector(view.getContext(), new ScaleListener());
|
||||
view.setOnTouchListener(this);
|
||||
view.setLongClickable(true);
|
||||
}
|
||||
|
||||
public void setOnFpvGestureListener(OnFpvGestureListener listener) {
|
||||
this.gestureListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
boolean result = scaleGestureDetector.onTouchEvent(event);
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
startX = event.getX();
|
||||
startY = event.getY();
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (gestureListener != null) {
|
||||
float endX = event.getX();
|
||||
float endY = event.getY();
|
||||
float distanceX = endX - startX;
|
||||
float distanceY = endY - startY;
|
||||
|
||||
// 检查是否是滑动操作(避免微小的移动被识别为滑动)
|
||||
if (Math.abs(distanceX) > 20 || Math.abs(distanceY) > 20) {
|
||||
if (!isSwiping) {
|
||||
isSwiping = true;
|
||||
}
|
||||
gestureListener.onSwipe(startX, startY, endX, endY, distanceX, distanceY);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
if (isSwiping && gestureListener != null) {
|
||||
gestureListener.onSwipeEnd();
|
||||
}
|
||||
isSwiping = false;
|
||||
startX = 0;
|
||||
startY = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
result = gestureDetector.onTouchEvent(event) || result;
|
||||
return result;
|
||||
}
|
||||
|
||||
private class GestureListener extends GestureDetector.SimpleOnGestureListener {
|
||||
@Override
|
||||
public boolean onSingleTapConfirmed(MotionEvent e) {
|
||||
if (gestureListener != null) {
|
||||
gestureListener.onTap(e.getX(), e.getY());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDoubleTap(MotionEvent e) {
|
||||
if (gestureListener != null) {
|
||||
gestureListener.onDoubleTap(e.getX(), e.getY());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongPress(MotionEvent e) {
|
||||
if (gestureListener != null) {
|
||||
gestureListener.onLongPress(e.getX(), e.getY());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
|
||||
// 我们在onTouch中处理滑动,这里不再处理
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
|
||||
@Override
|
||||
public boolean onScale(ScaleGestureDetector detector) {
|
||||
if (gestureListener != null) {
|
||||
gestureListener.onZoom(detector.getScaleFactor());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnFpvGestureListener {
|
||||
void onTap(float x, float y);
|
||||
void onDoubleTap(float x, float y);
|
||||
void onLongPress(float x, float y);
|
||||
void onSwipe(float startX, float startY, float endX, float endY, float distanceX, float distanceY);
|
||||
void onSwipeUp();
|
||||
void onSwipeDown();
|
||||
void onSwipeLeft();
|
||||
void onSwipeRight();
|
||||
void onZoom(float scaleFactor);
|
||||
void onSwipeEnd(); // 添加滑动结束(抬起)事件
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,163 @@
|
||||
// LogManager.java
|
||||
package com.example.longyi_groundstation.Main.Void.LogCat;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Process;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Collections;
|
||||
|
||||
public class LogManager {
|
||||
private static final String TAG = "LogManager";
|
||||
private static LogManager instance;
|
||||
private HandlerThread logThread;
|
||||
private Handler logHandler;
|
||||
private File logDir;
|
||||
private SimpleDateFormat dateFormat;
|
||||
private SimpleDateFormat fileDateFormat;
|
||||
private String currentDateString;
|
||||
|
||||
private LogManager() {
|
||||
// 初始化日志线程
|
||||
logThread = new HandlerThread("LogThread", Process.THREAD_PRIORITY_BACKGROUND);
|
||||
logThread.start();
|
||||
logHandler = new Handler(logThread.getLooper());
|
||||
|
||||
// 设置日志目录
|
||||
logDir = new File(android.os.Environment.getExternalStorageDirectory(), "LongYiLogs");
|
||||
if (!logDir.exists()) {
|
||||
boolean created = logDir.mkdirs();
|
||||
if (!created) {
|
||||
Log.e(TAG, "Failed to create log directory: " + logDir.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault());
|
||||
fileDateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
|
||||
currentDateString = fileDateFormat.format(new Date());
|
||||
}
|
||||
|
||||
public static synchronized LogManager getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new LogManager();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void saveLog(final String tag, final String msg) {
|
||||
// 直接在日志线程中处理,避免创建额外的Runnables
|
||||
logHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
performSaveLog(tag, msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void performSaveLog(String tag, String msg) {
|
||||
String time = dateFormat.format(new Date());
|
||||
String logEntry = time + " " + tag + ": " + msg + "\n";
|
||||
|
||||
// 检查是否需要创建新文件(新的一天)
|
||||
String dateStr = fileDateFormat.format(new Date());
|
||||
if (!dateStr.equals(currentDateString)) {
|
||||
currentDateString = dateStr;
|
||||
}
|
||||
|
||||
try {
|
||||
// 确保目录存在
|
||||
if (!logDir.exists()) {
|
||||
boolean created = logDir.mkdirs();
|
||||
if (!created) {
|
||||
Log.e(TAG, "Failed to create log directory: " + logDir.getAbsolutePath());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
File logFile = new File(logDir, "log_" + currentDateString + ".txt");
|
||||
|
||||
// 确保文件存在
|
||||
if (!logFile.exists()) {
|
||||
try {
|
||||
boolean created = logFile.createNewFile();
|
||||
if (!created) {
|
||||
Log.e(TAG, "Failed to create log file: " + logFile.getAbsolutePath());
|
||||
return;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "IOException when creating log file: " + logFile.getAbsolutePath(), e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(logFile, true));
|
||||
writer.write(logEntry);
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Failed to write log entry", e);
|
||||
}
|
||||
}
|
||||
|
||||
public File getLogFile(String date) {
|
||||
File logFile = new File(logDir, "log_" + date + ".txt");
|
||||
// 检查文件是否存在
|
||||
if (!logFile.exists()) {
|
||||
return null;
|
||||
}
|
||||
return logFile;
|
||||
}
|
||||
|
||||
public File getCurrentLogFile() {
|
||||
File logFile = new File(logDir, "log_" + currentDateString + ".txt");
|
||||
// 检查文件是否存在
|
||||
if (!logFile.exists()) {
|
||||
return null;
|
||||
}
|
||||
return logFile;
|
||||
}
|
||||
|
||||
public List<String> getAvailableDates() {
|
||||
List<String> dates = new ArrayList<>();
|
||||
|
||||
// 检查目录是否存在
|
||||
if (!logDir.exists()) {
|
||||
return dates;
|
||||
}
|
||||
|
||||
File[] files = logDir.listFiles();
|
||||
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
String name = file.getName();
|
||||
if (name.startsWith("log_") && name.endsWith(".txt")) {
|
||||
String date = name.substring(4, name.length() - 4); // 提取日期部分
|
||||
dates.add(date);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 按日期倒序排列(最新的在前)
|
||||
Collections.sort(dates, Collections.reverseOrder());
|
||||
return dates;
|
||||
}
|
||||
|
||||
public boolean isLogDirAvailable() {
|
||||
return logDir != null && logDir.exists();
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
if (logThread != null) {
|
||||
logThread.quitSafely();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
// LogUtil.java
|
||||
package com.example.longyi_groundstation.Main.Void.LogCat;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class LogUtil {
|
||||
public static void d(String tag, String msg) {
|
||||
// 正常打印日志
|
||||
// Log.d(tag, msg);
|
||||
|
||||
// 保存日志到文件
|
||||
LogManager.getInstance().saveLog(tag, msg);
|
||||
}
|
||||
|
||||
// 可以添加其他级别的日志方法 (e, w, i等)
|
||||
}
|
||||
@ -1,19 +1,29 @@
|
||||
package com.example.longyi_groundstation.Main.Void;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.location.Location;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.amap.api.maps.AMap;
|
||||
import com.amap.api.maps.AMapUtils;
|
||||
import com.amap.api.maps.MapView;
|
||||
import com.amap.api.maps.MapsInitializer;
|
||||
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.MyLocationStyle;
|
||||
import com.amap.api.maps.model.Polyline;
|
||||
import com.amap.api.maps.model.PolylineOptions;
|
||||
import com.example.longyi_groundstation.MAVLink.Messages.MAVLinkPayload;
|
||||
import com.example.longyi_groundstation.Main.Activity.MainActivity;
|
||||
import com.example.longyi_groundstation.R;
|
||||
|
||||
@ -23,7 +33,7 @@ import java.util.List;
|
||||
public class MapVoid {
|
||||
private String TAG = "cui";
|
||||
|
||||
private Activity activity;
|
||||
private Activity activity;
|
||||
|
||||
public AllView allView;
|
||||
|
||||
@ -32,12 +42,18 @@ public class MapVoid {
|
||||
public AMap aMap = null;
|
||||
//初始化地图控制器对象
|
||||
//画线
|
||||
public Polyline polyline;
|
||||
|
||||
//画线
|
||||
public List<LatLng> latLngss;
|
||||
|
||||
public List<Marker> waypointMarkers = new ArrayList<>();
|
||||
public List<LatLng> waypointPositions = new ArrayList<>();
|
||||
public Polyline polyline; // 用于保存航线
|
||||
public int waypointCounter = 1;
|
||||
|
||||
|
||||
public List<LatLng> flyPointList = new ArrayList<>();
|
||||
public List<Marker> textMarkers = new ArrayList<>();
|
||||
|
||||
public MapVoid(Activity activity) {
|
||||
this.activity = activity;
|
||||
@ -45,20 +61,22 @@ public class MapVoid {
|
||||
}
|
||||
|
||||
public void init() {
|
||||
//高德地图用户协议不能删除
|
||||
// 高德地图用户协议不能删除
|
||||
MapsInitializer.updatePrivacyShow(activity, true, true);
|
||||
MapsInitializer.updatePrivacyAgree(activity, true);
|
||||
allView = new AllView(activity);
|
||||
//在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),创建地图
|
||||
// 在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),创建地图
|
||||
allView.map.onCreate(savedInstanceState);
|
||||
aMap = allView.map.getMap();
|
||||
// 禁用POI点击
|
||||
aMap.setMapType(AMap.MAP_TYPE_SATELLITE);// 设置卫星地图模式,aMap是地图控制器对象。
|
||||
aMap.getUiSettings().setZoomControlsEnabled(false);// 隐藏地图上的缩放控件(+ 和 - 按钮)
|
||||
// 隐藏地图上的所有文字标注(地名、道路名等)
|
||||
aMap.showMapText(false);
|
||||
MyLocationStyle myLocationStyle;
|
||||
myLocationStyle = new MyLocationStyle();//初始化定位蓝点样式类
|
||||
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);//定位一次,且将视角移动到地图中心点。
|
||||
aMap.setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style
|
||||
myLocationStyle = new MyLocationStyle();// 初始化定位蓝点样式类
|
||||
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);// 定位一次,且将视角移动到地图中心点。
|
||||
aMap.setMyLocationStyle(myLocationStyle);// 设置定位蓝点的Style
|
||||
aMap.setMyLocationEnabled(false);// 设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false。
|
||||
aMap.setOnMyLocationChangeListener(new AMap.OnMyLocationChangeListener() {
|
||||
@Override
|
||||
@ -67,42 +85,18 @@ public class MapVoid {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//画大地图飞行线
|
||||
polyline = aMap.addPolyline(new PolylineOptions()
|
||||
.width(10)
|
||||
.color(
|
||||
Color.argb(255, 1, 1, 1))
|
||||
);
|
||||
polyline.setVisible(true);
|
||||
latLngss = new ArrayList<>();
|
||||
upLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法:更新线路的线程
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
public void upLine() {
|
||||
new Thread(new Runnable() {
|
||||
// 添加marker点击监听器,确保点击时显示信息窗口
|
||||
aMap.setOnMarkerClickListener(new AMap.OnMarkerClickListener() {
|
||||
@Override
|
||||
public void run() {
|
||||
while (aMap != null){
|
||||
try {
|
||||
polyline.setPoints(latLngss);
|
||||
Thread.sleep(1000);
|
||||
// polyline.setVisible(true);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
public boolean onMarkerClick(Marker marker) {
|
||||
// 检查是否是航点marker
|
||||
if (waypointMarkers.contains(marker)) {
|
||||
marker.showInfoWindow();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public void showLine(boolean isShow) {
|
||||
polyline.setVisible(isShow);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -121,4 +115,12 @@ public class MapVoid {
|
||||
// 保留两位小数
|
||||
return Math.round(distance * 100.0) / 100.0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -18,6 +18,9 @@ public class MyReceiver extends BroadcastReceiver {
|
||||
public static JSONObject STATUSTEXT_json = null;//告警
|
||||
public static JSONObject HEARTBEAT_json = null;//飞机基础飞行模式
|
||||
public static JSONObject PARAM_VALUE_json = null;//飞机基础飞行模式
|
||||
public static JSONObject RC_CHANNELS_json = null;//RC通道监控
|
||||
public static JSONObject VFR_HUD_json = null;//油门量
|
||||
|
||||
|
||||
|
||||
//ATTITUDE
|
||||
@ -68,6 +71,18 @@ public class MyReceiver extends BroadcastReceiver {
|
||||
}
|
||||
private OnParamValueListener ParamValuelistener;
|
||||
|
||||
|
||||
public interface OnRcChannelsListener {
|
||||
void onRcChannels(JSONObject data);
|
||||
}
|
||||
private OnRcChannelsListener RcChannelslistener;
|
||||
|
||||
public interface OnVfrHudListener {
|
||||
void onVfrHud(JSONObject data);
|
||||
}
|
||||
private OnVfrHudListener VfrHudlistener;
|
||||
|
||||
|
||||
public void setATTITUDEListener(OnATTITUDEListener listener) {
|
||||
this.ATTITUDElistener = listener;
|
||||
}
|
||||
@ -93,6 +108,14 @@ public class MyReceiver extends BroadcastReceiver {
|
||||
this.ParamValuelistener = listener;
|
||||
}
|
||||
|
||||
public void setRcChannelsRawlistener(OnRcChannelsListener listener) {
|
||||
this.RcChannelslistener = listener;
|
||||
}
|
||||
|
||||
public void setVfrHudlistener(OnVfrHudListener listener) {
|
||||
this.VfrHudlistener = listener;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
@ -111,7 +134,7 @@ public class MyReceiver extends BroadcastReceiver {
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e("cuijingzhou-e", e.toString());
|
||||
Log.e("cuijingzhou-e Broadcast_ATTITUDE", e.toString());
|
||||
}
|
||||
|
||||
}
|
||||
@ -130,7 +153,7 @@ public class MyReceiver extends BroadcastReceiver {
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e("cuijingzhou-e", e.toString());
|
||||
Log.e("cuijingzhou-e Broadcast_GPS_RAW_INT", e.toString());
|
||||
}
|
||||
|
||||
}
|
||||
@ -148,7 +171,7 @@ public class MyReceiver extends BroadcastReceiver {
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e("cuijingzhou-e", e.toString());
|
||||
// Log.e("cuijingzhou-e Broadcast_GLOBAL_POSITION_INT", e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,7 +189,7 @@ public class MyReceiver extends BroadcastReceiver {
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e("cuijingzhou-e", e.toString());
|
||||
Log.e("cuijingzhou-e Broadcast_POWER_STATUS", e.toString());
|
||||
}
|
||||
|
||||
}
|
||||
@ -185,7 +208,7 @@ public class MyReceiver extends BroadcastReceiver {
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e("cuijingzhou-e", e.toString());
|
||||
Log.e("cuijingzhou-e Broadcast_SYS_STATUS", e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@ -203,7 +226,7 @@ public class MyReceiver extends BroadcastReceiver {
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e("cuijingzhou-e", e.toString());
|
||||
Log.e("cuijingzhou-e Broadcast_STATUSTEXT", e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@ -221,7 +244,7 @@ public class MyReceiver extends BroadcastReceiver {
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e("cuijingzhou-e", e.toString());
|
||||
Log.e("cuijingzhou-e Broadcast_HEARTBEAT", e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,11 +262,46 @@ public class MyReceiver extends BroadcastReceiver {
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e("cuijingzhou-e", e.toString());
|
||||
Log.e("cuijingzhou-e Broadcast_PARAM_VALUE", e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ("Broadcast_RC_CHANNELS".equals(intent.getAction())) {
|
||||
try {
|
||||
String receivedData = intent.getStringExtra("data");
|
||||
if (receivedData != null) {
|
||||
RC_CHANNELS_json = new JSONObject(receivedData);
|
||||
RC_CHANNELS_json.optString("jsonObject");
|
||||
// Log.d("cuijingzhou", "onReceive: " + receivedData);
|
||||
// 触发回调
|
||||
if (RcChannelslistener != null) {
|
||||
RcChannelslistener.onRcChannels(RC_CHANNELS_json);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e("cuijingzhou-e Broadcast_RC_CHANNELS_RAW", e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ("Broadcast_VFR_HUD".equals(intent.getAction())) {
|
||||
try {
|
||||
String receivedData = intent.getStringExtra("data");
|
||||
if (receivedData != null) {
|
||||
VFR_HUD_json = new JSONObject(receivedData);
|
||||
VFR_HUD_json.optString("jsonObject");
|
||||
// Log.d("cuijingzhou", "onReceive: " + receivedData);
|
||||
// 触发回调
|
||||
if (VfrHudlistener != null) {
|
||||
VfrHudlistener.onVfrHud(VFR_HUD_json);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e("cuijingzhou-e Broadcast_RC_CHANNELS_RAW", e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -102,9 +102,61 @@ public class MyTool {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 方法:油门量公式
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
public static double getThrottle(double spin_mins, double spin_maxs, double thrust_curve_expos, double thrusts, double lift_maxs) {
|
||||
double thr_out = 0;//油门量
|
||||
double spin_min = 0.95;//对应MOT_SPIN_MIN,没获取到就用默认的
|
||||
double spin_max = 0.2;//对应MOT_SPIN_MAX,没获取到就用默认的
|
||||
|
||||
double throttle_curve = 0;
|
||||
double thrust_curve_expo = 0.65;//曲线指数
|
||||
double thrust = 0;//获取到的油门
|
||||
double lift_max = 1;//获取到的油门
|
||||
|
||||
if (spin_mins != 0){
|
||||
spin_min = spin_mins;
|
||||
}
|
||||
if (spin_maxs != 0){
|
||||
spin_max = spin_maxs;
|
||||
}
|
||||
if (thrust_curve_expos != 0){
|
||||
thrust_curve_expo = thrust_curve_expos;
|
||||
}
|
||||
if (thrusts != 0){
|
||||
thrust = thrusts;
|
||||
}
|
||||
if (lift_maxs != 0){
|
||||
lift_max = lift_maxs;
|
||||
}
|
||||
|
||||
//公式一
|
||||
throttle_curve = ((thrust_curve_expo - 1.0) + safe_sqrt(
|
||||
(1.0 - thrust_curve_expo) * (1.0 - thrust_curve_expo) + 4.0 * thrust_curve_expo * lift_max * thrust)) / (2.0 * thrust_curve_expo);//对应MOT_SPIN_MIN,没获取到就用默认的
|
||||
//公式二
|
||||
thr_out = spin_min + (spin_max - spin_min) //油门量公式运算
|
||||
* throttle_curve;
|
||||
|
||||
return thr_out;
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法:安全平方根计算
|
||||
* 防止对负数开方导致异常
|
||||
*
|
||||
* @param value 需要开方的数值
|
||||
* @return 开方结果,如果输入为负数则返回0
|
||||
* @cuijingzhou
|
||||
*/
|
||||
public static double safe_sqrt(double value) {
|
||||
if (value < 0) {
|
||||
return 0.0;
|
||||
}
|
||||
return Math.sqrt(value);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,441 @@
|
||||
package com.example.longyi_groundstation.Main.Void;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.util.Log;
|
||||
|
||||
import com.amap.api.maps.model.LatLng;
|
||||
import com.example.longyi_groundstation.Main.Base.CreateLink;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* 方法:SQLClass (飞行航线本地数据库)
|
||||
* // 初始化数据库
|
||||
* SQLClass sqlClass = new SQLClass(context);
|
||||
*
|
||||
* // 添加一个CreateLink列表
|
||||
* ArrayList<CreateLink> createLinkList = new ArrayList<>();
|
||||
* // ... 添加CreateLink对象到列表中
|
||||
* boolean success = sqlClass.addCreateLinkList("路线1", createLinkList);
|
||||
*
|
||||
* // 获取所有列表信息
|
||||
* List<SQLClass.LinkListInfo> listInfos = sqlClass.getAllLinkListInfo();
|
||||
*
|
||||
* // 获取指定ID的完整列表
|
||||
* ArrayList<CreateLink> retrievedList = sqlClass.getCreateLinkList(1);
|
||||
*
|
||||
* // 更新列表
|
||||
* sqlClass.updateCreateLinkList(1, "新路线名称", updatedCreateLinkList);
|
||||
*
|
||||
* // 删除列表
|
||||
* sqlClass.deleteCreateLinkList(1);
|
||||
*
|
||||
* // 获取列表数量
|
||||
* int count = sqlClass.getLinkListCount();
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
|
||||
public class SQLClass extends SQLiteOpenHelper {
|
||||
private static final String TAG = "SQLClass";
|
||||
|
||||
// 数据库名称和版本
|
||||
private static final String DATABASE_NAME = "create_link_list.db";
|
||||
private static final int DATABASE_VERSION = 1;
|
||||
|
||||
// 主表 - 存储列表信息
|
||||
private static final String TABLE_LINK_LIST = "link_list";
|
||||
private static final String COLUMN_LIST_ID = "list_id";
|
||||
private static final String COLUMN_LIST_NAME = "list_name";
|
||||
private static final String COLUMN_CREATED_TIME = "created_time";
|
||||
|
||||
// 详情表 - 存储每个列表中的CreateLink项
|
||||
private static final String TABLE_LINK_ITEMS = "link_items";
|
||||
private static final String COLUMN_ITEM_ID = "item_id";
|
||||
private static final String COLUMN_LIST_REF_ID = "list_ref_id"; // 外键,关联到列表ID
|
||||
private static final String COLUMN_NAME = "name";
|
||||
private static final String COLUMN_HEIGHT = "height";
|
||||
private static final String COLUMN_SPEED = "speed";
|
||||
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_ITEM_ORDER = "item_order"; // 项在列表中的顺序
|
||||
|
||||
// 创建主表的SQL语句
|
||||
private static final String CREATE_LIST_TABLE_SQL =
|
||||
"CREATE TABLE " + TABLE_LINK_LIST + " (" +
|
||||
COLUMN_LIST_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
|
||||
COLUMN_LIST_NAME + " TEXT NOT NULL, " +
|
||||
COLUMN_CREATED_TIME + " INTEGER NOT NULL)";
|
||||
|
||||
// 创建详情表的SQL语句
|
||||
private static final String CREATE_ITEMS_TABLE_SQL =
|
||||
"CREATE TABLE " + TABLE_LINK_ITEMS + " (" +
|
||||
COLUMN_ITEM_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
|
||||
COLUMN_LIST_REF_ID + " INTEGER NOT NULL, " +
|
||||
COLUMN_NAME + " TEXT NOT NULL, " +
|
||||
COLUMN_HEIGHT + " REAL NOT NULL, " +
|
||||
COLUMN_SPEED + " REAL NOT NULL, " +
|
||||
COLUMN_WAYPOINT_INDEX + " INTEGER NOT NULL, " +
|
||||
COLUMN_LATITUDE + " REAL, " +
|
||||
COLUMN_LONGITUDE + " REAL, " +
|
||||
COLUMN_ITEM_ORDER + " INTEGER NOT NULL, " +
|
||||
"FOREIGN KEY(" + COLUMN_LIST_REF_ID + ") REFERENCES " +
|
||||
TABLE_LINK_LIST + "(" + COLUMN_LIST_ID + ") ON DELETE CASCADE)";
|
||||
|
||||
public SQLClass(Context context) {
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
db.execSQL(CREATE_LIST_TABLE_SQL);
|
||||
db.execSQL(CREATE_ITEMS_TABLE_SQL);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigure(SQLiteDatabase db) {
|
||||
super.onConfigure(db);
|
||||
db.setForeignKeyConstraintsEnabled(true); // 启用外键约束
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一个CreateLink列表
|
||||
* @param listName 列表名称
|
||||
* @param createLinkList CreateLink列表
|
||||
* @return 添加成功返回true,否则返回false
|
||||
*/
|
||||
public boolean addCreateLinkList(String listName, ArrayList<CreateLink> createLinkList) {
|
||||
// 检查是否已达到最大数量限制
|
||||
if (getLinkListCount() >= 10) {
|
||||
Log.w(TAG, "已达到最大存储数量限制(10个列表),无法添加新列表");
|
||||
return false;
|
||||
}
|
||||
|
||||
SQLiteDatabase db = this.getWritableDatabase();
|
||||
db.beginTransaction(); // 开始事务以确保数据一致性
|
||||
|
||||
try {
|
||||
// 插入列表信息
|
||||
ContentValues listValues = new ContentValues();
|
||||
listValues.put(COLUMN_LIST_NAME, listName);
|
||||
listValues.put(COLUMN_CREATED_TIME, System.currentTimeMillis());
|
||||
|
||||
long listId = db.insert(TABLE_LINK_LIST, null, listValues);
|
||||
if (listId == -1) {
|
||||
db.endTransaction();
|
||||
return false;
|
||||
}
|
||||
|
||||
// 插入列表中的每个CreateLink项
|
||||
for (int i = 0; i < createLinkList.size(); i++) {
|
||||
CreateLink createLink = createLinkList.get(i);
|
||||
ContentValues itemValues = new ContentValues();
|
||||
|
||||
itemValues.put(COLUMN_LIST_REF_ID, listId);
|
||||
itemValues.put(COLUMN_NAME, createLink.getName());
|
||||
itemValues.put(COLUMN_HEIGHT, createLink.getHeight());
|
||||
itemValues.put(COLUMN_SPEED, createLink.getSpeed());
|
||||
itemValues.put(COLUMN_WAYPOINT_INDEX, createLink.getWaypointIndex());
|
||||
|
||||
if (createLink.getLatLng() != null) {
|
||||
itemValues.put(COLUMN_LATITUDE, createLink.getLatLng().latitude);
|
||||
itemValues.put(COLUMN_LONGITUDE, createLink.getLatLng().longitude);
|
||||
} else {
|
||||
itemValues.put(COLUMN_LATITUDE, 0.0);
|
||||
itemValues.put(COLUMN_LONGITUDE, 0.0);
|
||||
}
|
||||
|
||||
itemValues.put(COLUMN_ITEM_ORDER, i);
|
||||
|
||||
long itemId = db.insert(TABLE_LINK_ITEMS, null, itemValues);
|
||||
if (itemId == -1) {
|
||||
db.endTransaction();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful(); // 标记事务成功
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "添加CreateLink列表时出错", e);
|
||||
return false;
|
||||
} finally {
|
||||
db.endTransaction(); // 结束事务
|
||||
db.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有列表的基本信息(不包含列表内容)
|
||||
* @return 包含列表ID和名称的列表
|
||||
*/
|
||||
public List<LinkListInfo> getAllLinkListInfo() {
|
||||
List<LinkListInfo> listInfoList = new ArrayList<>();
|
||||
String selectQuery = "SELECT " + COLUMN_LIST_ID + ", " + COLUMN_LIST_NAME +
|
||||
", " + COLUMN_CREATED_TIME +
|
||||
" FROM " + TABLE_LINK_LIST +
|
||||
" ORDER BY " + COLUMN_CREATED_TIME + " DESC";
|
||||
|
||||
SQLiteDatabase db = this.getReadableDatabase();
|
||||
Cursor cursor = db.rawQuery(selectQuery, null);
|
||||
|
||||
if (cursor.moveToFirst()) {
|
||||
do {
|
||||
int listId = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_LIST_ID));
|
||||
String listName = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_LIST_NAME));
|
||||
long createdTime = cursor.getLong(cursor.getColumnIndexOrThrow(COLUMN_CREATED_TIME));
|
||||
|
||||
listInfoList.add(new LinkListInfo(listId, listName, createdTime));
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
|
||||
cursor.close();
|
||||
db.close();
|
||||
return listInfoList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据列表ID获取完整的CreateLink列表
|
||||
* @param listId 列表ID
|
||||
* @return CreateLink列表,如果不存在返回null
|
||||
*/
|
||||
public ArrayList<CreateLink> getCreateLinkList(int listId) {
|
||||
// 首先检查列表是否存在
|
||||
if (!isLinkListExists(listId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ArrayList<CreateLink> createLinkList = new ArrayList<>();
|
||||
String selectQuery = "SELECT * FROM " + TABLE_LINK_ITEMS +
|
||||
" WHERE " + COLUMN_LIST_REF_ID + " = ?" +
|
||||
" ORDER BY " + COLUMN_ITEM_ORDER;
|
||||
|
||||
SQLiteDatabase db = this.getReadableDatabase();
|
||||
Cursor cursor = db.rawQuery(selectQuery, new String[]{String.valueOf(listId)});
|
||||
|
||||
if (cursor.moveToFirst()) {
|
||||
do {
|
||||
String name = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_NAME));
|
||||
double height = cursor.getDouble(cursor.getColumnIndexOrThrow(COLUMN_HEIGHT));
|
||||
double speed = cursor.getDouble(cursor.getColumnIndexOrThrow(COLUMN_SPEED));
|
||||
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));
|
||||
|
||||
LatLng latLng = new LatLng(latitude, longitude);
|
||||
CreateLink createLink = new CreateLink(name, height, speed, waypointIndex, latLng);
|
||||
createLinkList.add(createLink);
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
|
||||
cursor.close();
|
||||
db.close();
|
||||
return createLinkList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新指定ID的CreateLink列表
|
||||
* @param listId 列表ID
|
||||
* @param listName 新的列表名称
|
||||
* @param createLinkList 新的CreateLink列表
|
||||
* @return 更新成功返回true,否则返回false
|
||||
*/
|
||||
public boolean updateCreateLinkList(int listId, String listName, ArrayList<CreateLink> createLinkList) {
|
||||
// 检查列表是否存在
|
||||
if (!isLinkListExists(listId)) {
|
||||
Log.w(TAG, "列表ID " + listId + " 不存在,无法更新");
|
||||
return false;
|
||||
}
|
||||
|
||||
SQLiteDatabase db = this.getWritableDatabase();
|
||||
db.beginTransaction(); // 开始事务以确保数据一致性
|
||||
|
||||
try {
|
||||
// 更新列表名称
|
||||
ContentValues listValues = new ContentValues();
|
||||
listValues.put(COLUMN_LIST_NAME, listName);
|
||||
|
||||
int updateResult = db.update(TABLE_LINK_LIST, listValues,
|
||||
COLUMN_LIST_ID + " = ?",
|
||||
new String[]{String.valueOf(listId)});
|
||||
|
||||
if (updateResult <= 0) {
|
||||
db.endTransaction();
|
||||
return false;
|
||||
}
|
||||
|
||||
// 删除原有的列表项
|
||||
db.delete(TABLE_LINK_ITEMS, COLUMN_LIST_REF_ID + " = ?",
|
||||
new String[]{String.valueOf(listId)});
|
||||
|
||||
// 插入新的列表项
|
||||
for (int i = 0; i < createLinkList.size(); i++) {
|
||||
CreateLink createLink = createLinkList.get(i);
|
||||
ContentValues itemValues = new ContentValues();
|
||||
|
||||
itemValues.put(COLUMN_LIST_REF_ID, listId);
|
||||
itemValues.put(COLUMN_NAME, createLink.getName());
|
||||
itemValues.put(COLUMN_HEIGHT, createLink.getHeight());
|
||||
itemValues.put(COLUMN_SPEED, createLink.getSpeed());
|
||||
itemValues.put(COLUMN_WAYPOINT_INDEX, createLink.getWaypointIndex());
|
||||
|
||||
if (createLink.getLatLng() != null) {
|
||||
itemValues.put(COLUMN_LATITUDE, createLink.getLatLng().latitude);
|
||||
itemValues.put(COLUMN_LONGITUDE, createLink.getLatLng().longitude);
|
||||
} else {
|
||||
itemValues.put(COLUMN_LATITUDE, 0.0);
|
||||
itemValues.put(COLUMN_LONGITUDE, 0.0);
|
||||
}
|
||||
|
||||
itemValues.put(COLUMN_ITEM_ORDER, i);
|
||||
|
||||
long itemId = db.insert(TABLE_LINK_ITEMS, null, itemValues);
|
||||
if (itemId == -1) {
|
||||
db.endTransaction();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful(); // 标记事务成功
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "更新CreateLink列表时出错", e);
|
||||
return false;
|
||||
} finally {
|
||||
db.endTransaction(); // 结束事务
|
||||
db.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据列表ID删除CreateLink列表
|
||||
* @param listId 列表ID
|
||||
* @return 删除成功返回true,否则返回false
|
||||
*/
|
||||
public boolean deleteCreateLinkList(int listId) {
|
||||
SQLiteDatabase db = this.getWritableDatabase();
|
||||
db.beginTransaction(); // 开始事务
|
||||
|
||||
try {
|
||||
// 删除列表项
|
||||
db.delete(TABLE_LINK_ITEMS, COLUMN_LIST_REF_ID + " = ?",
|
||||
new String[]{String.valueOf(listId)});
|
||||
|
||||
// 删除列表
|
||||
int result = db.delete(TABLE_LINK_LIST, COLUMN_LIST_ID + " = ?",
|
||||
new String[]{String.valueOf(listId)});
|
||||
|
||||
db.setTransactionSuccessful(); // 标记事务成功
|
||||
return result > 0;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "删除CreateLink列表时出错", e);
|
||||
return false;
|
||||
} finally {
|
||||
db.endTransaction(); // 结束事务
|
||||
db.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除所有CreateLink列表
|
||||
* @return 删除成功返回true,否则返回false
|
||||
*/
|
||||
public boolean deleteAllCreateLinkLists() {
|
||||
SQLiteDatabase db = this.getWritableDatabase();
|
||||
db.beginTransaction(); // 开始事务
|
||||
|
||||
try {
|
||||
// 删除所有列表项
|
||||
db.delete(TABLE_LINK_ITEMS, null, null);
|
||||
|
||||
// 删除所有列表
|
||||
db.delete(TABLE_LINK_LIST, null, null);
|
||||
|
||||
db.setTransactionSuccessful(); // 标记事务成功
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "删除所有CreateLink列表时出错", e);
|
||||
return false;
|
||||
} finally {
|
||||
db.endTransaction(); // 结束事务
|
||||
db.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取存储的列表数量
|
||||
* @return 列表数量
|
||||
*/
|
||||
public int getLinkListCount() {
|
||||
String countQuery = "SELECT COUNT(*) FROM " + TABLE_LINK_LIST;
|
||||
SQLiteDatabase db = this.getReadableDatabase();
|
||||
Cursor cursor = db.rawQuery(countQuery, null);
|
||||
int count = 0;
|
||||
|
||||
if (cursor.moveToFirst()) {
|
||||
count = cursor.getInt(0);
|
||||
}
|
||||
|
||||
cursor.close();
|
||||
db.close();
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查指定ID的列表是否存在
|
||||
* @param listId 列表ID
|
||||
* @return 存在返回true,否则返回false
|
||||
*/
|
||||
public boolean isLinkListExists(int listId) {
|
||||
String query = "SELECT 1 FROM " + TABLE_LINK_LIST +
|
||||
" WHERE " + COLUMN_LIST_ID + " = ? LIMIT 1";
|
||||
SQLiteDatabase db = this.getReadableDatabase();
|
||||
Cursor cursor = db.rawQuery(query, new String[]{String.valueOf(listId)});
|
||||
boolean exists = cursor.getCount() > 0;
|
||||
|
||||
cursor.close();
|
||||
db.close();
|
||||
return exists;
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表信息内部类
|
||||
*/
|
||||
public static class LinkListInfo {
|
||||
private int listId;
|
||||
private String listName;
|
||||
private long createdTime;
|
||||
|
||||
public LinkListInfo(int listId, String listName, long createdTime) {
|
||||
this.listId = listId;
|
||||
this.listName = listName;
|
||||
this.createdTime = createdTime;
|
||||
}
|
||||
|
||||
public int getListId() {
|
||||
return listId;
|
||||
}
|
||||
|
||||
public String getListName() {
|
||||
return listName;
|
||||
}
|
||||
|
||||
public long getCreatedTime() {
|
||||
return createdTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,105 @@
|
||||
package com.example.longyi_groundstation.Main.Void;
|
||||
|
||||
public class SerialTool {
|
||||
|
||||
/**
|
||||
* 将字节数组转换为Hex字符串
|
||||
*
|
||||
* @param bytes 字节数组
|
||||
* @return Hex字符串
|
||||
*/
|
||||
public static String bytesToHex(byte[] bytes) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (byte b : bytes) {
|
||||
result.append(String.format("%02X", b));
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将十进制字符串转换为十六进制byte
|
||||
*
|
||||
* @param decString 十进制字符串
|
||||
* @return 十六进制byte值
|
||||
* @throws IllegalArgumentException 当输入不是有效的十进制字符串或超出范围时
|
||||
*/
|
||||
public static byte decStringToHexByte(String decString) {
|
||||
if (decString == null || decString.isEmpty()) {
|
||||
throw new IllegalArgumentException("输入的十进制字符串不能为空");
|
||||
}
|
||||
|
||||
try {
|
||||
// 将十进制字符串解析为整数
|
||||
int value = Integer.parseInt(decString);
|
||||
|
||||
// 检查范围是否在0-255之间(单字节范围)
|
||||
if (value < 0 || value > 255) {
|
||||
throw new IllegalArgumentException("十进制值超出byte范围(0-255): " + decString);
|
||||
}
|
||||
|
||||
// 直接返回对应的byte值
|
||||
return (byte) value;
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("输入的不是有效的十进制字符串: " + decString);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 计算校验和
|
||||
* 校验和 = 帧头(0xFF) + 发送设置高度,取低8位
|
||||
*
|
||||
* @param heightSetting 发送设置高度的byte值
|
||||
* @return 校验和的byte值
|
||||
*/
|
||||
public static byte calculateChecksum(byte heightSetting) {
|
||||
// 帧头固定为0xFF
|
||||
int frameHeader = 0xFF;
|
||||
|
||||
// 将byte转换为无符号整数进行计算
|
||||
int heightValue = heightSetting & 0xFF;
|
||||
|
||||
// 计算校验和:帧头 + 设置高度
|
||||
int checksum = frameHeader + heightValue;
|
||||
|
||||
// 取低8位
|
||||
checksum = checksum & 0xFF;
|
||||
|
||||
// 转换为byte返回
|
||||
return (byte) checksum;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 解析串口数据,提取特定字节并转换为十进制值
|
||||
* 添加校验:data第4个字节 = data第1个+data第2个+data第3个,取低8位
|
||||
*
|
||||
* @param data 串口数据字节数组
|
||||
* @return 包含解析结果的数组,[0]为第2、3字节组合的值,[1]为第4字节的值;校验失败返回null
|
||||
*/
|
||||
public static int[] parseSerialData(byte[] data) {
|
||||
if (data == null || data.length < 4) {
|
||||
throw new IllegalArgumentException("数据长度不足,无法解析");
|
||||
}
|
||||
|
||||
// 校验:第4个字节应该等于前三个字节之和的低8位
|
||||
int checksum = (data[0] & 0xFF) + (data[1] & 0xFF) + (data[2] & 0xFF);
|
||||
checksum = checksum & 0xFF; // 取低8位
|
||||
|
||||
// 如果校验失败,返回null
|
||||
if ((data[3] & 0xFF) != checksum) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 提取第2、3字节组合成一个16位值 (例如: 01 2C -> 0x012C = 300)
|
||||
int value1 = ((data[1] & 0xFF) << 8) | (data[2] & 0xFF);
|
||||
|
||||
// 提取第4字节转换为十进制 (例如: 12 -> 0x12 = 18)
|
||||
int value2 = data[3] & 0xFF;
|
||||
|
||||
return new int[]{value1, value2};
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,90 @@
|
||||
package com.example.longyi_groundstation.Main.Void.XiangTuo;
|
||||
|
||||
public enum Instruction {
|
||||
|
||||
/**
|
||||
* 云台控制指令:
|
||||
* PTZ_LEFT_AND_DOWN:云台左下移动
|
||||
* PTZ_RIGHT_AND_UP:云台右上移动
|
||||
* PTZ_RIGHT_AND_DOWN:云台右下移动
|
||||
* PTZ_LEFT_AND_UP:云台左上移动
|
||||
* MOTOR_STOP:运动停止(速度控制模式)
|
||||
* 角度控制指令:
|
||||
* PITCH_ANGLE_CONTROL:俯仰角度控制
|
||||
* YAW_ANGLE_CONTROL:航向角度控制
|
||||
* 点动/跟踪指令:
|
||||
* POINT_TO_MOVE:指点移动(画面XY坐标)
|
||||
* POINT_TO_TRACKING:指点跟踪(画面XY坐标)
|
||||
* STOP_TRACKING:停止跟踪
|
||||
* 模式切换指令:
|
||||
* FOLLOW_YAW_MODE:航向跟随模式
|
||||
* LOCK_YAW_MODE:航向锁定模式
|
||||
* VERTICAL_OVERLOOK:垂直俯视(一键按下)90° overlook
|
||||
* ONE_CLICK_RESET:一键回中
|
||||
* 拍照/录像指令:
|
||||
* TAKE_PICTURE:拍照
|
||||
* START_RECORDING:开始录像
|
||||
* STOP_RECORDING:停止录像
|
||||
* 可见光变焦指令:
|
||||
* VIS_LIGHT_ZOOM:可见光变焦
|
||||
* VIS_LIGHT_SPEED_ZOOM:可见光速度变焦
|
||||
* VIS_LIGHT_STOP_ZOOM:可见光停止变焦
|
||||
* VIS_LIGHT_SPEC_OPT_ZOOM:可见光特殊光学变焦
|
||||
* 可见光手动聚焦指令:
|
||||
* TURN_ON_VIS_LIGHT_MAN_FOCUS:开启可见光手动聚焦
|
||||
* TURN_OFF_VIS_LIGHT_MAN_FOCUS:关闭可见光手动聚焦
|
||||
* VIS_LIGHT_MAN_FOCUS_PLUS:可见光手动聚焦(远焦)
|
||||
* VIS_LIGHT_MAN_FOCUS_MINUS:可见光手动聚焦(近焦)
|
||||
* VIS_LIGHT_MAN_FOCUS_STOP:可见光手动聚焦停止
|
||||
* OSD显示指令:
|
||||
* TURN_ON_OSD:打开OSD显示
|
||||
* TURN_OFF_OSD:关闭OSD显示
|
||||
*
|
||||
* @cuijingzhou
|
||||
*/
|
||||
|
||||
PTZ_UP((byte) 0x00, (byte) 0x08),
|
||||
PTZ_DOWN((byte) 0x00, (byte) 0x10),
|
||||
PTZ_LEFT((byte) 0x00, (byte) 0x04),
|
||||
PTZ_RIGHT((byte) 0x00, (byte) 0x02),
|
||||
MOTOR_STOP((byte) 0x00, (byte) 0x00),
|
||||
PITCH_ANGLE_CONTROL((byte) 0x10, (byte) 0x01),
|
||||
YAW_ANGLE_CONTROL((byte) 0x10, (byte) 0x02),
|
||||
POINT_TO_MOVE((byte) 0x10, (byte) 0x00),
|
||||
POINT_TO_TRACKING((byte) 0x11, (byte) 0x00),
|
||||
STOP_TRACKING((byte) 0x11, (byte) 0x01),
|
||||
FOLLOW_YAW_MODE((byte) 0x13, (byte) 0x00),
|
||||
LOCK_YAW_MODE((byte) 0x13, (byte) 0x01),
|
||||
VERTICAL_OVERLOOK((byte) 0x13, (byte) 0x02),
|
||||
ONE_CLICK_RESET((byte) 0x13, (byte) 0x03),
|
||||
TAKE_PICTURE((byte) 0x12, (byte) 0x00),
|
||||
START_RECORDING((byte) 0x12, (byte) 0x01),
|
||||
STOP_RECORDING((byte) 0x12, (byte) 0x02),
|
||||
VIS_LIGHT_ZOOM((byte) 0x00, (byte) 0x40),
|
||||
VIS_LIGHT_SPEED_ZOOM((byte) 0x00, (byte) 0x20),
|
||||
VIS_LIGHT_STOP_ZOOM((byte) 0x00, (byte) 0x60),
|
||||
VIS_LIGHT_SPEC_OPT_ZOOM((byte) 0x1F, (byte) 0x00),
|
||||
TURN_ON_VIS_LIGHT_MAN_FOCUS((byte) 0x1D, (byte) 0x00),
|
||||
TURN_OFF_VIS_LIGHT_MAN_FOCUS((byte) 0x1D, (byte) 0x01),
|
||||
VIS_LIGHT_MAN_FOCUS_PLUS((byte) 0x1D, (byte) 0x03),
|
||||
VIS_LIGHT_MAN_FOCUS_MINUS((byte) 0x1D, (byte) 0x02),
|
||||
VIS_LIGHT_MAN_FOCUS_STOP((byte) 0x1D, (byte) 0x04),
|
||||
TURN_ON_OSD((byte) 0x19, (byte) 0x00),
|
||||
TURN_OFF_OSD((byte) 0x19, (byte) 0x01);
|
||||
|
||||
private final byte code1;
|
||||
private final byte code2;
|
||||
|
||||
Instruction(byte code1, byte code2) {
|
||||
this.code1 = code1;
|
||||
this.code2 = code2;
|
||||
}
|
||||
|
||||
public byte getCode1() {
|
||||
return code1;
|
||||
}
|
||||
|
||||
public byte getCode2() {
|
||||
return code2;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
package com.example.longyi_groundstation.Main.Void.XiangTuo;
|
||||
|
||||
public class Protocol {
|
||||
private static final int SYNC_BYTE = 0xFF;
|
||||
private byte addressCode;
|
||||
private byte instructionCode1;
|
||||
private byte instructionCode2;
|
||||
private byte dataCode1;
|
||||
private byte dataCode2;
|
||||
private byte checkCode;
|
||||
|
||||
public Protocol(byte addressCode, byte instructionCode1, byte instructionCode2, byte dataCode1, byte dataCode2) {
|
||||
this.addressCode = addressCode;
|
||||
this.instructionCode1 = instructionCode1;
|
||||
this.instructionCode2 = instructionCode2;
|
||||
this.dataCode1 = dataCode1;
|
||||
this.dataCode2 = dataCode2;
|
||||
// this.checkCode = calculateCheckCode();
|
||||
}
|
||||
|
||||
public static byte calculateCheckCode(byte addressCode, byte instructionCode1, byte instructionCode2, byte dataCode1, byte dataCode2) {
|
||||
// 校验码计算逻辑:字节2 + 字节3 + 字节4 + 字节5 + 字节6
|
||||
int sum = addressCode & 0xFF;
|
||||
sum += instructionCode1 & 0xFF;
|
||||
sum += instructionCode2 & 0xFF;
|
||||
sum += dataCode1 & 0xFF;
|
||||
sum += dataCode2 & 0xFF;
|
||||
return (byte) (sum & 0xFF);
|
||||
}
|
||||
|
||||
public byte[] toBytes() {
|
||||
return new byte[]{
|
||||
(byte) SYNC_BYTE,
|
||||
addressCode,
|
||||
instructionCode1,
|
||||
instructionCode2,
|
||||
dataCode1,
|
||||
dataCode2,
|
||||
checkCode
|
||||
};
|
||||
}
|
||||
|
||||
public String toHexBytes() {
|
||||
String hexString = String.format("%02X", SYNC_BYTE) + " " +
|
||||
String.format("%02X", addressCode) + " " +
|
||||
String.format("%02X", instructionCode1) + " " +
|
||||
String.format("%02X", instructionCode2) + " " +
|
||||
String.format("%02X", dataCode1) + " " +
|
||||
String.format("%02X", dataCode2) + " " +
|
||||
String.format("%02X", checkCode);
|
||||
|
||||
return hexString;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,295 @@
|
||||
package com.example.longyi_groundstation.Main.Void.XiangTuo;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import okio.Buffer;
|
||||
import okio.Okio;
|
||||
import okio.Sink;
|
||||
import okio.Source;
|
||||
|
||||
public class TcpClientUtil {
|
||||
private static final String TAG = "TcpClientUtil";
|
||||
private Socket socket;
|
||||
private Source source;
|
||||
private Sink sink;
|
||||
private ExecutorService executorService;
|
||||
private Handler mainHandler;
|
||||
private boolean isConnected = false;
|
||||
private TextView infoTextView;
|
||||
|
||||
public TcpClientUtil() {
|
||||
executorService = Executors.newSingleThreadExecutor();
|
||||
mainHandler = new Handler(Looper.getMainLooper());
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接到TCP服务器
|
||||
*
|
||||
* @param host 服务器地址
|
||||
* @param port 服务器端口
|
||||
*/
|
||||
public void connect(String host, int port) {
|
||||
updateInfoTextView("正在连接到 " + host + ":" + port + "...");
|
||||
|
||||
executorService.execute(() -> {
|
||||
try {
|
||||
socket = new Socket();
|
||||
// 设置Socket选项以提高性能
|
||||
socket.setTcpNoDelay(true);
|
||||
socket.setSoTimeout(100000000); // 10秒读取超时
|
||||
socket.connect(new InetSocketAddress(host, port), 5000); // 5秒连接超时
|
||||
source = Okio.source(socket.getInputStream());
|
||||
sink = Okio.sink(socket.getOutputStream());
|
||||
isConnected = true;
|
||||
Log.d(TAG, "连接成功: " + host + ":" + port);
|
||||
updateInfoTextView("连接成功: " + host + ":" + port);
|
||||
|
||||
// 启动接收数据线程
|
||||
// startReceiving();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "连接失败: " + e.getMessage());
|
||||
isConnected = false;
|
||||
updateInfoTextView("连接失败: " + e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 断开连接
|
||||
*/
|
||||
public void disconnect() {
|
||||
updateInfoTextView("正在断开连接...");
|
||||
|
||||
executorService.execute(() -> {
|
||||
try {
|
||||
isConnected = false;
|
||||
if (source != null) {
|
||||
source.close();
|
||||
}
|
||||
if (sink != null) {
|
||||
sink.close();
|
||||
}
|
||||
if (socket != null) {
|
||||
socket.close();
|
||||
}
|
||||
Log.d(TAG, "连接已断开");
|
||||
updateInfoTextView("连接已断开");
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "断开连接时出错: " + e.getMessage());
|
||||
updateInfoTextView("断开连接时出错: " + e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送Hex数据
|
||||
*
|
||||
* @param hexData 以Hex格式表示的数据
|
||||
*/
|
||||
public void sendHexData(String hexData) {
|
||||
if (!isConnected) {
|
||||
Log.e(TAG, "未连接到服务器");
|
||||
updateInfoTextView("错误: 未连接到服务器");
|
||||
return;
|
||||
}
|
||||
|
||||
executorService.execute(() -> {
|
||||
try {
|
||||
// 将Hex字符串转换为字节数组
|
||||
byte[] data = hexStringToByteArray(hexData);
|
||||
|
||||
// 发送数据
|
||||
Buffer buffer = new Buffer();
|
||||
buffer.write(data);
|
||||
sink.write(buffer, data.length);
|
||||
sink.flush();
|
||||
Log.d(TAG, "发送数据: " + hexData);
|
||||
updateInfoTextView("发送: " + hexData);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "发送数据失败: " + e.getMessage());
|
||||
updateInfoTextView("发送失败: " + e.getMessage());
|
||||
} catch (OutOfMemoryError e) {
|
||||
Log.e(TAG, "发送数据时内存不足: " + e.getMessage());
|
||||
updateInfoTextView("发送失败: 内存不足");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送字节数组
|
||||
*
|
||||
* @param data 字节数组
|
||||
*/
|
||||
public void sendBytes(byte[] data) {
|
||||
if (!isConnected) {
|
||||
Log.e(TAG, "未连接到服务器");
|
||||
updateInfoTextView("错误: 未连接到服务器");
|
||||
return;
|
||||
}
|
||||
|
||||
executorService.execute(() -> {
|
||||
try {
|
||||
if (data == null || data.length == 0) {
|
||||
Log.w(TAG, "尝试发送空数据");
|
||||
updateInfoTextView("警告: 尝试发送空数据");
|
||||
return;
|
||||
}
|
||||
|
||||
Buffer buffer = new Buffer();
|
||||
buffer.write(data);
|
||||
sink.write(buffer, data.length);
|
||||
sink.flush();
|
||||
String hexData = bytesToHex(data);
|
||||
Log.d(TAG, "发送数据: " + hexData + " (长度: " + data.length + " 字节)");
|
||||
updateInfoTextView("发送: " + hexData + " (" + data.length + " 字节)");
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "发送数据失败: " + e.getMessage(), e);
|
||||
updateInfoTextView("发送失败: " + e.getMessage());
|
||||
} catch (OutOfMemoryError e) {
|
||||
Log.e(TAG, "发送数据时内存不足: " + e.getMessage());
|
||||
updateInfoTextView("发送失败: 内存不足");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始接收数据
|
||||
*/
|
||||
private void startReceiving() {
|
||||
executorService.execute(() -> {
|
||||
try {
|
||||
Buffer buffer = new Buffer();
|
||||
while (isConnected && socket != null && !socket.isClosed() && !socket.isInputShutdown()) {
|
||||
// 读取数据
|
||||
long bytesRead = source.read(buffer, 1024);
|
||||
|
||||
if (bytesRead > 0) {
|
||||
byte[] data = buffer.readByteArray();
|
||||
String hexData = bytesToHex(data);
|
||||
|
||||
// 在主线程更新UI
|
||||
updateInfoTextView("接收: " + hexData + " (" + data.length + " 字节)");
|
||||
Log.d(TAG, "接收到数据: " + hexData + " (长度: " + data.length + " 字节)");
|
||||
} else if (bytesRead == -1) {
|
||||
// 连接已关闭
|
||||
isConnected = false;
|
||||
updateInfoTextView("连接已关闭");
|
||||
Log.d(TAG, "连接已关闭");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (isConnected) {
|
||||
Log.e(TAG, "接收数据时出错: " + e.getMessage());
|
||||
updateInfoTextView("接收数据时出错: " + e.getMessage());
|
||||
isConnected = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置用于显示信息的TextView
|
||||
*
|
||||
* @param textView TextView控件
|
||||
*/
|
||||
public void setInfoTextView(TextView textView) {
|
||||
this.infoTextView = textView;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新TextView显示内容
|
||||
*
|
||||
* @param data 要显示的数据
|
||||
*/
|
||||
private void updateInfoTextView(String data) {
|
||||
if (infoTextView != null) {
|
||||
mainHandler.post(() -> {
|
||||
String currentText = infoTextView.getText().toString();
|
||||
// 添加时间戳
|
||||
String timestamp = java.text.DateFormat.getTimeInstance().format(new java.util.Date());
|
||||
String newText = currentText + "\n[" + timestamp + "] " + data;
|
||||
|
||||
// 限制文本长度,避免内存问题
|
||||
if (newText.length() > 10000) {
|
||||
newText = newText.substring(newText.length() - 10000);
|
||||
}
|
||||
|
||||
infoTextView.setText(newText);
|
||||
|
||||
// 自动滚动到底部
|
||||
infoTextView.post(() -> {
|
||||
if (infoTextView.getLayout() != null) {
|
||||
int scrollAmount = infoTextView.getLayout().getLineTop(infoTextView.getLineCount()) - infoTextView.getHeight();
|
||||
if (scrollAmount > 0) {
|
||||
infoTextView.scrollTo(0, scrollAmount);
|
||||
} else {
|
||||
infoTextView.scrollTo(0, 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将Hex字符串转换为字节数组
|
||||
*
|
||||
* @param hexString Hex字符串
|
||||
* @return 字节数组
|
||||
*/
|
||||
private byte[] hexStringToByteArray(String hexString) {
|
||||
int len = hexString.length();
|
||||
byte[] data = new byte[len / 2];
|
||||
for (int i = 0; i < len; i += 2) {
|
||||
data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
|
||||
+ Character.digit(hexString.charAt(i+1), 16));
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字节数组转换为Hex字符串
|
||||
*
|
||||
* @param bytes 字节数组
|
||||
* @return Hex字符串
|
||||
*/
|
||||
private String bytesToHex(byte[] bytes) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (byte b : bytes) {
|
||||
result.append(String.format("%02X", b));
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否已连接
|
||||
*
|
||||
* @return 连接状态
|
||||
*/
|
||||
public boolean isConnected() {
|
||||
return isConnected;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Socket状态
|
||||
*
|
||||
* @return Socket状态信息
|
||||
*/
|
||||
public String getSocketStatus() {
|
||||
if (socket == null) {
|
||||
return "Socket未初始化";
|
||||
}
|
||||
return String.format("Socket状态 - 已连接: %s, 已关闭: %s, 输入关闭: %s, 输出关闭: %s",
|
||||
isConnected, socket.isClosed(), socket.isInputShutdown(), socket.isOutputShutdown());
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,12 @@
|
||||
package com.example.longyi_groundstation;
|
||||
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Bundle;
|
||||
import android.os.Message;
|
||||
import android.speech.tts.TextToSpeech;
|
||||
import android.util.Log;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.activity.EdgeToEdge;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
@ -13,33 +14,17 @@ import androidx.core.graphics.Insets;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
|
||||
import com.example.longyi_groundstation.MAVLink.MAVLinkPacket;
|
||||
import com.example.longyi_groundstation.MAVLink.Messages.MAVLinkMessage;
|
||||
import com.example.longyi_groundstation.MAVLink.Parser;
|
||||
import com.example.longyi_groundstation.Util.Serial.SerialPortUtil;
|
||||
import com.example.longyi_groundstation.Util.Tool;
|
||||
import com.example.longyi_groundstation.Util.UdpClient;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Locale;
|
||||
|
||||
import tp.xmaihh.serialport.SerialHelper;
|
||||
import tp.xmaihh.serialport.bean.ComBean;
|
||||
import com.example.longyi_groundstation.Main.Void.XiangTuo.Instruction;
|
||||
import com.example.longyi_groundstation.Main.Void.XiangTuo.Protocol;
|
||||
import com.example.longyi_groundstation.Main.Void.XiangTuo.TcpClientUtil;
|
||||
|
||||
public class MainActivity2 extends AppCompatActivity {
|
||||
private static final String TAG = "MainActivity2";
|
||||
|
||||
private static final String TAG = "UDPServer";
|
||||
private TextView tv_text;
|
||||
private DatagramSocket serverSocket;
|
||||
private boolean isRunning = true;
|
||||
private int serverPort = 14550; // 服务端监听端口
|
||||
|
||||
private UdpClient udpClient;
|
||||
private TcpClientUtil tcpClient;
|
||||
private TextView tvInfo;
|
||||
private Button btnConnect;
|
||||
private Button btnDisconnect;
|
||||
|
||||
@SuppressLint("MissingInflatedId")
|
||||
@Override
|
||||
@ -53,52 +38,148 @@ public class MainActivity2 extends AppCompatActivity {
|
||||
return insets;
|
||||
});
|
||||
|
||||
tv_text = findViewById(R.id.tv_text);
|
||||
initViews();
|
||||
initTcpClient();
|
||||
}
|
||||
|
||||
try {
|
||||
udpClient = new UdpClient("127.0.0.1", 14551); // 服务器的IP地址和端口号
|
||||
isRunning = true;
|
||||
udpClient.send("AA01");
|
||||
getDataTR();
|
||||
private void initViews() {
|
||||
tvInfo = findViewById(R.id.tv_info);
|
||||
btnConnect = findViewById(R.id.btn_connect);
|
||||
btnDisconnect = findViewById(R.id.btn_disconnect);
|
||||
|
||||
} catch (SocketException | UnknownHostException e) {
|
||||
// throw new RuntimeException(e);
|
||||
Log.d(TAG, e + "");
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
if (btnConnect != null) {
|
||||
btnConnect.setOnClickListener(v -> connectToServer());
|
||||
}
|
||||
|
||||
if (btnDisconnect != null) {
|
||||
btnDisconnect.setOnClickListener(v -> disconnectFromServer());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//接收数据线程
|
||||
private void getDataTR() {
|
||||
new Thread(() -> {
|
||||
byte[] buffer = new byte[1024];
|
||||
while (true) {
|
||||
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
|
||||
try {
|
||||
if (udpClient != null) {
|
||||
udpClient.socket.receive(packet);
|
||||
//转成Hex
|
||||
String receivedData = Tool.bytesToHex(packet.getData());
|
||||
Log.d(TAG, receivedData);
|
||||
// 添加测试按钮,用于测试发送数据
|
||||
Button btn_left = findViewById(R.id.btn_left);
|
||||
btn_left.setOnClickListener(v -> {
|
||||
if (!tcpClient.isConnected()) {
|
||||
Toast.makeText(this, "未连接到服务器", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Log.d(TAG, "getDataTR: stop");
|
||||
// Log.e(TAG, " "+ e );
|
||||
}
|
||||
new Thread(() -> {
|
||||
try {
|
||||
// 发送测试数据
|
||||
byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x04, (byte) 0xFF, 0x00, 0x04};
|
||||
tcpClient.sendBytes(testData);
|
||||
Thread.sleep(200);
|
||||
// 发送测试数据
|
||||
byte[] testData1 = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01};
|
||||
tcpClient.sendBytes(testData1);
|
||||
Log.d(TAG, "发送测试数据: " + bytesToHex(testData));
|
||||
|
||||
}
|
||||
}).start();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
);
|
||||
|
||||
// 添加测试按钮,用于测试发送数据
|
||||
Button btn_right = findViewById(R.id.btn_right);
|
||||
btn_right.setOnClickListener(v -> {
|
||||
if (!tcpClient.isConnected()) {
|
||||
Toast.makeText(this, "未连接到服务器", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
new Thread(() -> {
|
||||
try {
|
||||
// 发送测试数据
|
||||
byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x02, (byte) 0xFF, 0x00, 0x02};
|
||||
tcpClient.sendBytes(testData);
|
||||
Thread.sleep(200);
|
||||
// 发送测试数据
|
||||
byte[] testData1 = new byte[]{(byte) 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01};
|
||||
tcpClient.sendBytes(testData1);
|
||||
Log.d(TAG, "发送测试数据: " + bytesToHex(testData));
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
);
|
||||
|
||||
// 添加测试按钮,用于测试发送数据
|
||||
Button btn_centre = findViewById(R.id.btn_centre);
|
||||
btn_centre.setOnClickListener(v -> {
|
||||
if (!tcpClient.isConnected()) {
|
||||
Toast.makeText(this, "未连接到服务器", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
// 发送测试数据
|
||||
byte[] testData = new byte[]{(byte) 0xFF, 0x01, 0x13, 0x03, 0x00, 0x00, 0x17};
|
||||
tcpClient.sendBytes(testData);
|
||||
Log.d(TAG, "发送测试数据: " + bytesToHex(testData));
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// // 添加测试按钮,用于测试发送数据
|
||||
// Button btnTestSend = findViewById(R.id.btn_left);
|
||||
// // 添加测试按钮,用于测试发送数据
|
||||
// Button btnTestSend = findViewById(R.id.btn_left);
|
||||
}
|
||||
|
||||
private void initTcpClient() {
|
||||
tcpClient = new TcpClientUtil();
|
||||
// 设置用于显示信息的TextView
|
||||
if (tvInfo != null) {
|
||||
tcpClient.setInfoTextView(tvInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private void connectToServer() {
|
||||
// 这里使用示例IP和端口,需要根据实际情况修改
|
||||
tcpClient.connect("192.168.144.119", 2000);
|
||||
}
|
||||
|
||||
private void disconnectFromServer() {
|
||||
tcpClient.disconnect();
|
||||
}
|
||||
|
||||
private void testSendData() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
private String bytesToHex(byte[] bytes) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (byte b : bytes) {
|
||||
result.append(String.format("%02X ", b));
|
||||
}
|
||||
return result.toString().trim();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
isRunning = false;
|
||||
if (tcpClient != null) {
|
||||
tcpClient.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 示例方法:发送云台控制指令
|
||||
// private void sendPTZCommand(Instruction instruction) {
|
||||
// if (!tcpClient.isConnected()) {
|
||||
// Toast.makeText(this, "未连接到服务器", Toast.LENGTH_SHORT).show();
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// Protocol protocol = new Protocol(
|
||||
// ADDRESS_CODE,
|
||||
// instruction.getCode1(),
|
||||
// instruction.getCode2(),
|
||||
// (byte) 0x00,
|
||||
// (byte) 0x00
|
||||
// );
|
||||
// byte[] bytes = protocol.toBytes();
|
||||
// tcpClient.sendBytes(bytes);
|
||||
// Log.d(TAG, "发送指令: " + instruction.name() + ", 数据: " + bytesToHex(bytes));
|
||||
// }
|
||||
}
|
||||
|
||||
@ -106,5 +106,45 @@ public class BroadcastUtil {
|
||||
intent.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* MAVLINK_MSG_ID_RC_CHANNELS
|
||||
*
|
||||
* @param context 上下文
|
||||
* @param data 数据-json
|
||||
*/
|
||||
public static void Broadcast_RC_CHANNELS(Context context, String data) {
|
||||
Intent intent = new Intent("Broadcast_RC_CHANNELS");
|
||||
intent.putExtra("data", data);
|
||||
context.sendBroadcast(intent);
|
||||
intent.clone();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* MAVLINK_MSG_ID_RC_CHANNELS_RAW
|
||||
*
|
||||
* @param context 上下文
|
||||
* @param data 数据-json
|
||||
*/
|
||||
public static void Broadcast_RC_CHANNELS_RAW(Context context, String data) {
|
||||
Intent intent = new Intent("Broadcast_RC_CHANNELS_RAW");
|
||||
intent.putExtra("data", data);
|
||||
context.sendBroadcast(intent);
|
||||
intent.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* MAVLINK_MSG_ID_VFR_HUD
|
||||
*
|
||||
* @param context 上下文
|
||||
* @param data 数据-json
|
||||
*/
|
||||
public static void Broadcast_VFR_HUD(Context context, String data) {
|
||||
Intent intent = new Intent("Broadcast_VFR_HUD");
|
||||
intent.putExtra("data", data);
|
||||
context.sendBroadcast(intent);
|
||||
intent.clone();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
9
app/src/main/res/drawable/custom_info_bubble.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#FFFFFF" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#CCCCCC" />
|
||||
<corners android:radius="8dp" />
|
||||
</shape>
|
||||
@ -3,6 +3,6 @@
|
||||
|
||||
<corners android:topLeftRadius="4dp" android:topRightRadius="4dp"/>
|
||||
|
||||
<solid android:color="#49B6E7"/>
|
||||
<solid android:color="#029A45"/>
|
||||
|
||||
</shape>
|
||||
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<corners android:radius="4dp"/>
|
||||
<corners android:radius="2dp"/>
|
||||
|
||||
<solid android:color="#8DECEC"/>
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
android:layout_marginBottom="10dp"/>
|
||||
|
||||
<EditText
|
||||
android:text="admin"
|
||||
android:text="admin1"
|
||||
android:textSize="12sp"
|
||||
android:id="@+id/et_username"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@ -1,18 +1,114 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context=".MainActivity2">
|
||||
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:text="text"
|
||||
android:textColor="#303030"
|
||||
android:id="@+id/tv_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<!-- 添加TCP连接控制按钮 -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="8dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_connect"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="连接"
|
||||
android:layout_marginEnd="4dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_disconnect"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="断开"
|
||||
android:layout_marginStart="4dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 添加TCP连接控制按钮 -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="8dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_left"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="左"
|
||||
android:layout_marginEnd="4dp"/>
|
||||
<Button
|
||||
android:id="@+id/btn_right"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="右"
|
||||
android:layout_marginEnd="4dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_centre"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="回中"
|
||||
android:layout_marginEnd="4dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_up"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="上"
|
||||
android:layout_marginStart="4dp"/>
|
||||
<Button
|
||||
android:id="@+id/btn_down"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="下"
|
||||
android:layout_marginStart="4dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<!-- 添加用于显示TCP数据的TextView -->
|
||||
<TextView
|
||||
android:id="@+id/tv_info"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/black"
|
||||
android:textColor="@android:color/holo_green_light"
|
||||
android:padding="8dp"
|
||||
android:textSize="12sp"
|
||||
android:scrollbars="vertical"
|
||||
android:maxLines="10"
|
||||
android:layout_margin="8dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
591
app/src/main/res/layout/activity_play_back.xml
Normal file
@ -0,0 +1,591 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".Main.Activity.PlayBackActivity">
|
||||
|
||||
<com.amap.api.maps.MapView
|
||||
android:id="@+id/map"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentBottom="true">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#00ffffff"
|
||||
android:elevation="10dp">
|
||||
|
||||
<!-- 标题栏 -->
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginTop="-1dp"
|
||||
android:background="@mipmap/icon_title_bg">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_logo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:src="@mipmap/logo_w" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_connect"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:padding="8dp"
|
||||
android:text="未知模式"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="9sp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="26dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="end|center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="26dp"
|
||||
android:background="@drawable/b2ffffff_4round_1stroke_bg"
|
||||
android:gravity="center"
|
||||
android:padding="5dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="15dp"
|
||||
android:src="@mipmap/icon_satellite" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_satellite"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="-.-"
|
||||
android:textColor="#D8E481"
|
||||
android:textSize="9sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="26dp"
|
||||
android:background="@drawable/b2ffffff_4round_1stroke_bg"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="5dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="15dp"
|
||||
android:src="@mipmap/icon_power" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_power"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="-.-"
|
||||
android:textColor="#D8E481"
|
||||
android:textSize="8sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="26dp"
|
||||
android:background="@drawable/b2ffffff_4round_1stroke_bg"
|
||||
android:gravity="center"
|
||||
android:padding="5dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="15dp"
|
||||
android:src="@mipmap/icon_speed" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_vel"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="-.-"
|
||||
android:textColor="#D8E481"
|
||||
android:textSize="8sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="26dp"
|
||||
android:background="@drawable/b2ffffff_4round_1stroke_bg"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="5dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="15dp"
|
||||
android:src="@mipmap/icon_height_fly" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_height"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="-.-"
|
||||
android:textColor="#D8E481"
|
||||
android:textSize="8sp" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 左侧功能布局 -->
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/ll_title"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="110dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_left_error_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="110dp"
|
||||
android:layout_marginTop="3dp"
|
||||
android:background="@drawable/xbb303030_4round_bg"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_error_list"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
</com.amap.api.maps.MapView>
|
||||
|
||||
<!-- 偏航文字 -->
|
||||
<TextView
|
||||
android:id="@+id/tv_yaw"
|
||||
android:layout_width="25dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@+id/ll_text"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginRight="226dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:background="@drawable/xbb303030_4round_bg"
|
||||
android:elevation="10dp"
|
||||
android:gravity="center"
|
||||
android:padding="3dp"
|
||||
android:text="0°"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="8sp" />
|
||||
|
||||
<!-- 底部数据栏 -->
|
||||
<RelativeLayout
|
||||
android:id="@+id/ll_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="110dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:elevation="10dp"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="visible">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_margin="5dp"
|
||||
android:orientation="vertical"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginRight="20dp"
|
||||
android:background="@drawable/x80000000_4round_bg"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<!-- 自定义进度条 -->
|
||||
<com.example.longyi_groundstation.Main.View.CustomSeekBar
|
||||
android:id="@+id/custom_seekbar"
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_margin="5dp" />
|
||||
|
||||
<!-- 路线规划 -->
|
||||
<LinearLayout
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:id="@+id/ll_link"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/ll_title"
|
||||
android:layout_alignParentRight="true"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="visible">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_link_save"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="25dp"
|
||||
android:background="@drawable/b2101010_4round_1stroke_bg"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="25dp"
|
||||
android:gravity="center"
|
||||
android:text="开始/暂停"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="8sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_marginLeft="10dp"
|
||||
android:id="@+id/ll_link_fun1"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="25dp"
|
||||
android:background="@drawable/b2101010_4round_1stroke_bg"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="25dp"
|
||||
android:gravity="center"
|
||||
android:text="X 1.5"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="8sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_marginLeft="10dp"
|
||||
android:id="@+id/ll_link_fun2"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="25dp"
|
||||
android:background="@drawable/b2101010_4round_1stroke_bg"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="25dp"
|
||||
android:gravity="center"
|
||||
android:text="X 2.0"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="8sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_marginLeft="10dp"
|
||||
android:id="@+id/ll_link_back"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="25dp"
|
||||
android:background="@drawable/b2101010_4round_1stroke_bg"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="25dp"
|
||||
android:gravity="center"
|
||||
android:text="重新播放"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="8sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_margin="5dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="100dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:background="@drawable/ff101010_120round_bg"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:padding="5dp">
|
||||
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="90dp"
|
||||
android:layout_height="90dp"
|
||||
android:layout_marginLeft="2dp">
|
||||
|
||||
<!-- 天地仪 -->
|
||||
<com.example.longyi_groundstation.Main.View.CircularLinearLayout
|
||||
android:id="@+id/cll_layout"
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="72dp"
|
||||
android:layout_centerInParent="true"
|
||||
android:orientation="vertical"
|
||||
android:visibility="invisible">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="72dp">
|
||||
|
||||
<!-- 天地-->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<View
|
||||
android:id="@+id/v_welkin"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="35dp"
|
||||
android:background="#B875C5DB" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 俯仰 -->
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_pitch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="0dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="3dp"
|
||||
android:text="45"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="4sp" />
|
||||
|
||||
<View
|
||||
android:layout_width="14dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginRight="7dp"
|
||||
android:background="#ffffff" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="3dp"
|
||||
android:text="30"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="4sp" />
|
||||
|
||||
<View
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginRight="6dp"
|
||||
android:background="#ffffff" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="3dp"
|
||||
android:text="15"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="4sp" />
|
||||
|
||||
<View
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginRight="6dp"
|
||||
android:background="#ffffff" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="4dp"
|
||||
android:text="0"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="4sp" />
|
||||
|
||||
<View
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="1.5dp"
|
||||
android:layout_marginRight="6dp"
|
||||
android:background="#DBCE16" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="3dp"
|
||||
android:text="15"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="4sp" />
|
||||
|
||||
<View
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginRight="6dp"
|
||||
android:background="#ffffff" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="3dp"
|
||||
android:text="30"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="4sp" />
|
||||
|
||||
<View
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginRight="6dp"
|
||||
android:background="#ffffff" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="3dp"
|
||||
android:text="45"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="4sp" />
|
||||
|
||||
<View
|
||||
android:layout_width="14dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginRight="7dp"
|
||||
android:background="#ffffff" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 翻滚 -->
|
||||
<ImageView
|
||||
android:id="@+id/iv_roll"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerInParent="true"
|
||||
android:src="@mipmap/icon_instrument_roll" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</com.example.longyi_groundstation.Main.View.CircularLinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_yaw"
|
||||
android:layout_width="90dp"
|
||||
android:layout_height="90dp"
|
||||
android:layout_centerInParent="true"
|
||||
android:src="@mipmap/icon_instrument_yaw" />
|
||||
|
||||
<!-- 小飞机 -->
|
||||
<ImageView
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
android:layout_centerInParent="true"
|
||||
android:paddingBottom="3dp"
|
||||
android:src="@mipmap/icon_instrument_fly" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="90dp"
|
||||
android:layout_height="90dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="5dp"
|
||||
android:layout_height="5dp"
|
||||
android:src="@mipmap/icon_instrument_pitch_z" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<!-- 底部状态栏 -->
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="5dp"
|
||||
android:gravity="right"
|
||||
android:orientation="horizontal"
|
||||
tools:ignore="RtlHardcoded">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_type_list"
|
||||
android:layout_width="160dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<!-- 主页面 -->
|
||||
|
||||
</RelativeLayout>
|
||||
@ -65,7 +65,7 @@
|
||||
|
||||
<TextView
|
||||
android:textSize="12sp"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginTop="1dp"
|
||||
android:background="@drawable/b2303030_4round_1stroke_bg"
|
||||
android:textColor="#303030"
|
||||
android:id="@+id/tv_control"
|
||||
@ -76,7 +76,7 @@
|
||||
|
||||
<TextView
|
||||
android:textSize="12sp"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginTop="1dp"
|
||||
android:background="@drawable/b2303030_4round_1stroke_bg"
|
||||
android:textColor="#303030"
|
||||
android:id="@+id/tv_fly"
|
||||
@ -87,7 +87,7 @@
|
||||
|
||||
<TextView
|
||||
android:textSize="12sp"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginTop="1dp"
|
||||
android:background="@drawable/b2303030_4round_1stroke_bg"
|
||||
android:textColor="#303030"
|
||||
android:id="@+id/tv_secure"
|
||||
@ -98,7 +98,7 @@
|
||||
|
||||
<TextView
|
||||
android:textSize="12sp"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginTop="1dp"
|
||||
android:background="@drawable/b2303030_4round_1stroke_bg"
|
||||
android:textColor="#303030"
|
||||
android:id="@+id/tv_motor"
|
||||
@ -109,7 +109,7 @@
|
||||
|
||||
<TextView
|
||||
android:textSize="12sp"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginTop="1dp"
|
||||
android:background="@drawable/b2303030_4round_1stroke_bg"
|
||||
android:textColor="#303030"
|
||||
android:id="@+id/tv_load"
|
||||
@ -118,9 +118,10 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="35dp"/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:textSize="12sp"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginTop="1dp"
|
||||
android:background="@drawable/b2303030_4round_1stroke_bg"
|
||||
android:textColor="#303030"
|
||||
android:id="@+id/tv_sensor"
|
||||
@ -129,10 +130,11 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="35dp"/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:textSize="12sp"
|
||||
android:id="@+id/tv_parameter"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginTop="1dp"
|
||||
android:background="@drawable/b2303030_4round_1stroke_bg"
|
||||
android:textColor="#303030"
|
||||
android:gravity="center"
|
||||
|
||||
99
app/src/main/res/layout/adapter_all_link_item.xml
Normal file
@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="180dp"
|
||||
android:background="@drawable/x80000000_4round_bg"
|
||||
android:padding="5dp"
|
||||
android:orientation="vertical"
|
||||
android:layout_margin="3dp"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_title"
|
||||
android:gravity="center"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="9sp"
|
||||
android:text="名称:"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="22dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_alignParentRight="true"
|
||||
android:id="@+id/tv_del"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:gravity="center"
|
||||
android:textColor="#ffffff"
|
||||
android:background="@drawable/ffdd635a_4round_1stroke_bg"
|
||||
android:textSize="9sp"
|
||||
android:text="删除"
|
||||
android:layout_width="42dp"
|
||||
android:layout_height="20dp"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp"
|
||||
android:background="@drawable/ffffffff_4round_bg"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:gravity="center_vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_marginLeft="10dp"
|
||||
android:textColor="#303030"
|
||||
android:textSize="8sp"
|
||||
android:text="创建时间:"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_time"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:textColor="#303030"
|
||||
android:textSize="7sp"
|
||||
android:text="2010-10-10 12:00:00"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_marginLeft="10dp"
|
||||
android:textColor="#303030"
|
||||
android:textSize="8sp"
|
||||
android:text="点位数量:"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_number"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:textColor="#303030"
|
||||
android:textSize="7sp"
|
||||
android:text="12个"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:layout_margin="6dp"
|
||||
app:cardCornerRadius="8dp"
|
||||
app:cardElevation="4dp">
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
android:padding="8dp">
|
||||
|
||||
<RelativeLayout
|
||||
android:orientation="horizontal"
|
||||
@ -28,6 +28,7 @@
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:layout_centerVertical="true"
|
||||
android:textStyle="bold"
|
||||
android:layout_alignParentRight="true"
|
||||
android:id="@+id/tv_current_value"
|
||||
@ -35,63 +36,40 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:text="1200"
|
||||
android:text="00"
|
||||
android:textColor="#62a7f0"
|
||||
android:textSize="11sp" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
|
||||
<!-- 添加条形图 -->
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_progress_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_height="8dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_max_desc"
|
||||
<View
|
||||
android:id="@+id/view_left_progress"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:text="最大值说明: "
|
||||
android:textColor="#888"
|
||||
android:textSize="10sp" />
|
||||
android:background="#62a7f0" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_min_desc"
|
||||
<View
|
||||
android:id="@+id/view_right_progress"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:text="最小值说明: "
|
||||
android:textColor="#888"
|
||||
android:textSize="10sp" />
|
||||
android:background="#cccccc" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:textSize="11sp"
|
||||
android:id="@+id/tv_max_value"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="最大值: "
|
||||
android:textColor="#666" />
|
||||
|
||||
<TextView
|
||||
android:textSize="11sp"
|
||||
android:id="@+id/tv_min_value"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="最小值: "
|
||||
android:textColor="#666" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
114
app/src/main/res/layout/adapter_create_link_item.xml
Normal file
@ -0,0 +1,114 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="160dp"
|
||||
android:background="@drawable/x80000000_4round_bg"
|
||||
android:padding="5dp"
|
||||
android:orientation="vertical"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_title"
|
||||
android:gravity="center"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="11sp"
|
||||
android:text="名称:"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="22dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_alignParentRight="true"
|
||||
android:id="@+id/tv_del"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:gravity="center"
|
||||
android:textColor="#ffffff"
|
||||
android:background="@drawable/ffdd635a_4round_1stroke_bg"
|
||||
android:textSize="9sp"
|
||||
android:text="删除"
|
||||
android:layout_width="42dp"
|
||||
android:layout_height="20dp"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:padding="10dp"
|
||||
android:background="@drawable/ffffffff_4round_bg"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_marginLeft="10dp"
|
||||
android:textColor="#303030"
|
||||
android:textSize="9sp"
|
||||
android:text="高度:"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<EditText
|
||||
android:gravity="center"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:text="30"
|
||||
android:textSize="9sp"
|
||||
android:background="#ffffff"
|
||||
android:id="@+id/et_height"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:layout_marginLeft="10dp"
|
||||
android:textColor="#303030"
|
||||
android:textSize="9sp"
|
||||
android:text="m"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_marginLeft="10dp"
|
||||
android:textColor="#303030"
|
||||
android:textSize="9sp"
|
||||
android:text="速度:"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<EditText
|
||||
android:gravity="center"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:text="30"
|
||||
android:textSize="9sp"
|
||||
android:background="#ffffff"
|
||||
android:id="@+id/et_speed"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:layout_marginLeft="10dp"
|
||||
android:textColor="#303030"
|
||||
android:textSize="9sp"
|
||||
android:text="m/s"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
@ -24,7 +24,7 @@
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="200dp"
|
||||
android:layout_width="160dp"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
|
||||
@ -4,12 +4,13 @@
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_item"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:layout_margin="6dp"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="16sp"
|
||||
android:padding="12dp"/>
|
||||
android:textSize="10sp"
|
||||
android:padding="6dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
@ -7,11 +7,15 @@
|
||||
android:id="@+id/ll_main">
|
||||
|
||||
<TextView
|
||||
android:textColor="#ffffff"
|
||||
android:id="@+id/text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:textSize="7sp"
|
||||
android:textColor="#ffffff" />
|
||||
android:textSize="8sp"
|
||||
android:maxWidth="400dp"
|
||||
android:minWidth="0dp"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="none" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
32
app/src/main/res/layout/custom_info_window.xml
Normal file
@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/custom_info_bubble"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#000000"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="4dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/delete_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="删除"
|
||||
android:textSize="12sp"
|
||||
android:background="#FF5555"
|
||||
android:textColor="#FFFFFF" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
28
app/src/main/res/layout/custom_marker_layout.xml
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="40dp"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center">
|
||||
|
||||
<!-- 自定义图标 -->
|
||||
<ImageView
|
||||
android:layout_centerHorizontal="true"
|
||||
android:id="@+id/marker_icon"
|
||||
android:layout_width="25dp"
|
||||
android:layout_height="40dp"
|
||||
android:src="@mipmap/icon_marker" />
|
||||
|
||||
<!-- 文字标签 -->
|
||||
<TextView
|
||||
android:layout_alignParentBottom="true"
|
||||
android:id="@+id/marker_text"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="点位1"
|
||||
android:textSize="7sp"
|
||||
android:textColor="#ffffff"
|
||||
android:background="@drawable/x80000000_4round_bg"
|
||||
android:gravity="center" />
|
||||
|
||||
</RelativeLayout>
|
||||
77
app/src/main/res/layout/dialog_bombing.xml
Normal file
@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:background="@drawable/ff029a45_4round_bg"
|
||||
android:gravity="center"
|
||||
android:padding="8dp"
|
||||
android:text="投弹"
|
||||
android:textColor="#fff"
|
||||
android:textSize="13sp" />
|
||||
|
||||
<LinearLayout
|
||||
|
||||
android:layout_margin="8dp"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:textSize="12sp"
|
||||
android:text="高度设置:"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<EditText
|
||||
android:textSize="12sp"
|
||||
android:padding="2dp"
|
||||
android:id="@+id/et_height"
|
||||
android:background="@drawable/b2303030_4round_1stroke_bg"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:textSize="12sp"
|
||||
android:layout_marginLeft="3dp"
|
||||
android:text="M"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
||||
<com.example.longyi_groundstation.Main.View.SlideToUnlockView
|
||||
android:background="#ffffff"
|
||||
android:id="@+id/unlockView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="35dp"
|
||||
android:layout_margin="8dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_message"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="30dp"
|
||||
android:layout_gravity="center"
|
||||
android:background="#C3606060"
|
||||
android:gravity="center"
|
||||
android:text="取消"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="12sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
@ -14,7 +14,7 @@
|
||||
android:padding="8dp"
|
||||
android:gravity="center"
|
||||
android:text="警告"
|
||||
android:background="@drawable/eb51518b_4round_bg"
|
||||
android:background="@drawable/ff029a45_4round_bg"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:id="@+id/tv_title"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:background="@drawable/eb51518b_4round_bg"
|
||||
android:background="@drawable/ff029a45_4round_bg"
|
||||
android:gravity="center"
|
||||
android:padding="8dp"
|
||||
android:text="返航"
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:background="@drawable/eb51518b_4round_bg"
|
||||
android:background="@drawable/ff029a45_4round_bg"
|
||||
android:gravity="center"
|
||||
android:padding="8dp"
|
||||
android:text="起飞"
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:background="@drawable/eb51518b_4round_bg"
|
||||
android:background="@drawable/ff029a45_4round_bg"
|
||||
android:gravity="center"
|
||||
android:padding="8dp"
|
||||
android:text="降落"
|
||||
|
||||
@ -1,28 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#555f75"
|
||||
android:background="#112446"
|
||||
android:orientation="vertical"
|
||||
tools:context=".Main.Setting.Fragment.MotorFragment">
|
||||
|
||||
<TextView
|
||||
android:textSize="10sp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_margin="8dp"
|
||||
android:layout_margin="6dp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"
|
||||
android:textColor="#ffffff"
|
||||
android:id="@+id/tv_calibration"
|
||||
android:gravity="center"
|
||||
android:text="参数校准"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="35dp"/>
|
||||
android:layout_width="100dp"
|
||||
android:padding="6dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:background="@drawable/ff112446_4round_bg"
|
||||
android:id="@+id/rv_data"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginTop="50dp"
|
||||
android:layout_marginLeft="6dp"
|
||||
android:layout_marginRight="6dp"
|
||||
android:layout_marginBottom="6dp"
|
||||
android:padding="6dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
@ -1,13 +1,451 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#555f75"
|
||||
android:background="#112446"
|
||||
android:padding="8dp"
|
||||
android:orientation="horizontal"
|
||||
tools:context=".Main.Setting.Fragment.MotorFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_weight="2.5"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<!-- 功能按钮 -->
|
||||
<RelativeLayout
|
||||
android:paddingRight="30dp"
|
||||
android:paddingLeft="10dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_default"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:gravity="center"
|
||||
android:textColor="#ffffff"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"
|
||||
android:textSize="10sp"
|
||||
android:text="恢复默认"
|
||||
android:paddingLeft="20dp"
|
||||
android:paddingRight="20dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="22dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_alignParentRight="true"
|
||||
android:id="@+id/tv_save"
|
||||
android:gravity="center"
|
||||
android:textColor="#ffffff"
|
||||
android:background="@drawable/ff60b964_4round_1stroke_bg"
|
||||
android:textSize="10sp"
|
||||
android:text="保存"
|
||||
android:layout_width="42dp"
|
||||
android:layout_height="22dp"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<!-- 最大平飞速度 -->
|
||||
<LinearLayout
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:gravity="right"
|
||||
android:textSize="10sp"
|
||||
android:text="最大平飞速度:"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<!-- 减按钮 -->
|
||||
<TextView
|
||||
android:layout_marginLeft="5dp"
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_flight_speed_minus"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:text="-"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
<!-- 滑动条 -->
|
||||
<SeekBar
|
||||
android:id="@+id/seekBar_flight_speed"
|
||||
android:layout_width="140dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:max="3500"
|
||||
android:min="20"
|
||||
android:progress="0"
|
||||
|
||||
/>
|
||||
|
||||
<!-- 加按钮 -->
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_flight_speed_add"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:text="+"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:layout_marginLeft="3dp"
|
||||
android:textSize="10sp"
|
||||
android:id="@+id/tv_flight_speed"
|
||||
android:text="20cm/s"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="50dp"
|
||||
android:gravity="right"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 最大平飞速度 -->
|
||||
<LinearLayout
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:gravity="right"
|
||||
android:textSize="10sp"
|
||||
android:text="最大爬升速度:"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<!-- 减按钮 -->
|
||||
<TextView
|
||||
android:layout_marginLeft="5dp"
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_climb_speed_minus"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:text="-"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
<!-- 滑动条 -->
|
||||
<SeekBar
|
||||
android:id="@+id/seekBar_climb_speed"
|
||||
android:layout_width="140dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:max="500"
|
||||
android:min="50"
|
||||
android:progress="0"
|
||||
|
||||
/>
|
||||
|
||||
<!-- 加按钮 -->
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_climb_speed_add"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:text="+"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:layout_marginLeft="3dp"
|
||||
android:textSize="10sp"
|
||||
android:id="@+id/tv_climb_speed"
|
||||
android:text="50cm/s"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="50dp"
|
||||
android:gravity="right"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 最大平飞速度 -->
|
||||
<LinearLayout
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:gravity="right"
|
||||
android:textSize="10sp"
|
||||
android:text="最大下降速度:"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<!-- 减按钮 -->
|
||||
<TextView
|
||||
android:layout_marginLeft="5dp"
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_decline_speed_minus"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:text="-"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
<!-- 滑动条 -->
|
||||
<SeekBar
|
||||
android:id="@+id/seekBar_decline_speed"
|
||||
android:layout_width="140dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:max="500"
|
||||
android:min="0"
|
||||
android:progress="0"
|
||||
|
||||
/>
|
||||
|
||||
<!-- 加按钮 -->
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_decline_speed_add"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:text="+"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:layout_marginLeft="3dp"
|
||||
|
||||
android:textSize="10sp"
|
||||
android:id="@+id/tv_decline_speed"
|
||||
android:text="0cm/s"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="50dp"
|
||||
android:gravity="right"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 最大平飞速度 -->
|
||||
<LinearLayout
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:gravity="right"
|
||||
android:textSize="10sp"
|
||||
android:text="最大水平角度:"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<!-- 减按钮 -->
|
||||
<TextView
|
||||
android:layout_marginLeft="5dp"
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_horizontal_angle_minus"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:text="-"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
<!-- 滑动条 -->
|
||||
<SeekBar
|
||||
android:id="@+id/seekBar_horizontal_angle"
|
||||
android:layout_width="140dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:max="8000"
|
||||
android:min="1000"
|
||||
android:progress="0"
|
||||
|
||||
/>
|
||||
|
||||
<!-- 加按钮 -->
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_horizontal_angle_add"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:text="+"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:layout_marginLeft="3dp"
|
||||
android:textSize="10sp"
|
||||
android:id="@+id/tv_horizontal_angle"
|
||||
android:text="1000cdeg"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="50dp"
|
||||
android:gravity="right"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 最大平飞速度 -->
|
||||
<LinearLayout
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:gravity="right"
|
||||
android:textSize="10sp"
|
||||
android:text="最大旋转速率:"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<!-- 减按钮 -->
|
||||
<TextView
|
||||
android:layout_marginLeft="5dp"
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_rotation_rate_minus"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:text="-"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
<!-- 滑动条 -->
|
||||
<SeekBar
|
||||
android:id="@+id/seekBar_rotation_rate"
|
||||
android:layout_width="140dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:max="3600"
|
||||
android:progress="10"
|
||||
|
||||
/>
|
||||
|
||||
<!-- 加按钮 -->
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_rotation_rate_add"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:text="+"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:layout_marginLeft="3dp"
|
||||
android:textSize="10sp"
|
||||
android:id="@+id/tv_rotation_rate"
|
||||
android:text="1.0度/s"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="50dp"
|
||||
android:gravity="right"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:background="@drawable/ffffffff_4round_bg"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
|
||||
<TextView
|
||||
android:layout_margin="10dp"
|
||||
android:text=" 1.最大平飞速度:指无人机在水平方向能达到的最高飞行速度。"
|
||||
android:textColor="#606060"
|
||||
android:textSize="12sp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:layout_margin="10dp"
|
||||
android:text=" 2.最大爬升速度:指无人机垂直上升时的最高速率"
|
||||
android:textColor="#606060"
|
||||
android:textSize="12sp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:layout_margin="10dp"
|
||||
android:text=" 3.最大下降速度:指无人机垂直下降时的最高安全速率"
|
||||
android:textColor="#606060"
|
||||
android:textSize="12sp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:layout_margin="10dp"
|
||||
android:text=" 4.最大水平角度:指无人机倾斜飞行的最大角度(以度为单位),影响机动性和抗风能力"
|
||||
android:textColor="#606060"
|
||||
android:textSize="12sp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:layout_margin="10dp"
|
||||
android:text=" 5.最大旋转速率:指无人机绕轴旋转的最高角速度(单位 m/秒),用于快速转向或姿态调整。"
|
||||
android:textColor="#606060"
|
||||
android:textSize="12sp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</ScrollView>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
12
app/src/main/res/layout/fragment_fly_acceleration.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:textColor="#ffffff"
|
||||
android:text="加速度"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</LinearLayout>
|
||||
12
app/src/main/res/layout/fragment_fly_install.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:textColor="#ffffff"
|
||||
android:text="安装设置"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</LinearLayout>
|
||||
12
app/src/main/res/layout/fragment_fly_magnetometer.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:textColor="#ffffff"
|
||||
android:text="磁力"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</LinearLayout>
|
||||
13
app/src/main/res/layout/fragment_fly_model.xml
Normal file
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="6dp">
|
||||
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
@ -1,16 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".Main.Setting.Fragment.MotorFragment">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:background="#555f75"
|
||||
android:orientation="vertical"
|
||||
tools:context=".Main.Setting.Fragment.FoundationFragment">
|
||||
|
||||
<!-- TODO: Update blank fragment layout -->
|
||||
<TextView
|
||||
android:background="#cdcdcd"
|
||||
android:gravity="center"
|
||||
android:text="维护中.."
|
||||
android:background="#cdcdcd"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:text="正在维护.." />
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</FrameLayout>
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginLeft="6dp"
|
||||
android:id="@+id/tab_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="26dp"
|
||||
android:background="#555f75"
|
||||
app:tabIndicatorHeight="0dp"
|
||||
app:tabRippleColor="@null"
|
||||
app:tabBackground="@drawable/tab_background_selector"
|
||||
app:tabTextColor="@drawable/tab_text_color_selector"
|
||||
app:tabTextAppearance="@style/CustomTabTextAppearance"
|
||||
android:contentDescription="载荷选择" />
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:background="@drawable/ff112446_4round_bg"
|
||||
android:layout_margin="6dp"
|
||||
android:id="@+id/view_pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
15
app/src/main/res/layout/fragment_logcat.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:background="#ff112446">
|
||||
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:text="维护中.."
|
||||
android:background="#cdcdcd"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</LinearLayout>
|
||||
@ -3,182 +3,235 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#555f75"
|
||||
android:background="#112446"
|
||||
android:orientation="horizontal"
|
||||
|
||||
tools:context=".Main.Setting.Fragment.MotorFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:gravity="bottom"
|
||||
android:orientation="vertical"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<!-- 持续时间控制区域 -->
|
||||
<LinearLayout
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginBottom="24dp">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:text="持续时间:"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="70dp"
|
||||
<ImageView
|
||||
android:layout_marginTop="30dp"
|
||||
android:layout_gravity="center"
|
||||
android:src="@mipmap/icon_ft60"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<!-- 减按钮 -->
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_time_minus"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:text="-"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_gravity="center"
|
||||
android:text="FT60"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
<!-- 滑动条 -->
|
||||
<SeekBar
|
||||
android:id="@+id/seekBar_time"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:max="10"
|
||||
android:progress="0"
|
||||
|
||||
/>
|
||||
|
||||
|
||||
|
||||
<!-- 加按钮 -->
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_time_add"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:text="+"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_time"
|
||||
android:text="0秒"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="40dp"
|
||||
android:gravity="right"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 持续时间控制区域 -->
|
||||
|
||||
<LinearLayout
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:gravity="bottom"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginBottom="24dp">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:text="油门量:"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<!-- 减按钮 -->
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_power_minus"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:text="-"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
<!-- 滑动条 -->
|
||||
<SeekBar
|
||||
android:id="@+id/seekBar_power"
|
||||
android:layout_width="150dp"
|
||||
<!-- 持续时间控制区域 -->
|
||||
<LinearLayout
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:max="100"
|
||||
android:progress="0"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginBottom="24dp">
|
||||
|
||||
/>
|
||||
<TextView
|
||||
android:textSize="10sp"
|
||||
android:text="持续时间:"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<!-- 加按钮 -->
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_power_add"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:text="+"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
<!-- 减按钮 -->
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_time_minus"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:text="-"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
<!-- 滑动条 -->
|
||||
<SeekBar
|
||||
android:id="@+id/seekBar_time"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:max="10"
|
||||
android:progress="0"
|
||||
|
||||
/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_power"
|
||||
android:text="0%"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="40dp"
|
||||
android:gravity="right"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<!-- 加按钮 -->
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_time_add"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:text="+"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:textSize="10sp"
|
||||
android:id="@+id/tv_time"
|
||||
android:text="0秒"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="40dp"
|
||||
android:gravity="right"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 持续时间控制区域 -->
|
||||
<LinearLayout
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginBottom="24dp">
|
||||
|
||||
<TextView
|
||||
android:textSize="10sp"
|
||||
android:text="油门量:"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<!-- 减按钮 -->
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_power_minus"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:text="-"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
<!-- 滑动条 -->
|
||||
<SeekBar
|
||||
android:id="@+id/seekBar_power"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:max="100"
|
||||
android:progress="0"
|
||||
|
||||
/>
|
||||
|
||||
<!-- 加按钮 -->
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_power_add"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:text="+"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:textSize="10sp"
|
||||
android:id="@+id/tv_power"
|
||||
android:text="0%"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="40dp"
|
||||
android:gravity="right"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_all_test1"
|
||||
android:textColor="#ffffff"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"
|
||||
android:padding="5dp"
|
||||
android:gravity="center"
|
||||
android:text="全部旋转"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_all_test2"
|
||||
android:textColor="#ffffff"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"
|
||||
android:padding="5dp"
|
||||
android:gravity="center"
|
||||
android:text="顺序旋转"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
<LinearLayout
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_margin="6dp"
|
||||
android:orientation="vertical"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:id="@+id/rv_data"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_margin="8dp"/>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
</RelativeLayout>
|
||||
<TextView
|
||||
android:textSize="10sp"
|
||||
android:id="@+id/tv_all_test1"
|
||||
android:textColor="#ffffff"
|
||||
android:background="@drawable/ff60b964_4round_1stroke_bg"
|
||||
android:padding="5dp"
|
||||
android:gravity="center"
|
||||
android:text="全部旋转"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:textSize="10sp"
|
||||
android:id="@+id/tv_all_test2"
|
||||
android:textColor="#ffffff"
|
||||
android:background="@drawable/ffdd635a_4round_1stroke_bg"
|
||||
android:padding="5dp"
|
||||
android:gravity="center"
|
||||
android:text="顺序旋转"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
||||
|
||||
@ -3,24 +3,470 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#555f75"
|
||||
android:orientation="vertical"
|
||||
android:padding="6dp"
|
||||
android:background="#112446"
|
||||
tools:context=".Main.Setting.Fragment.SecureFragment">
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:id="@+id/tab_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="#555f75"
|
||||
android:contentDescription="载荷选择" />
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:layout_margin="10dp"
|
||||
android:id="@+id/view_pager"
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<RelativeLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<View
|
||||
android:layout_centerVertical="true"
|
||||
android:background="@drawable/ffffffff_4round_bg"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1.5dp"/>
|
||||
|
||||
<TextView
|
||||
android:background="@drawable/ff112446_4round_bg"
|
||||
android:gravity="center"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_margin="6dp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="14sp"
|
||||
android:text="电池"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:padding="12dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginBottom="6dp"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<!-- 一级电压 -->
|
||||
<LinearLayout
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:gravity="right"
|
||||
android:textSize="10sp"
|
||||
android:text="一级低电压:"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<!-- 减按钮 -->
|
||||
<TextView
|
||||
android:layout_marginLeft="30dp"
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_one_power_minus"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:text="-"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
<!-- 滑动条 -->
|
||||
<SeekBar
|
||||
android:layout_marginLeft="3dp"
|
||||
android:layout_marginRight="3dp"
|
||||
android:id="@+id/seekBar_one_power"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:max="100"
|
||||
android:progress="40"
|
||||
|
||||
/>
|
||||
|
||||
<!-- 加按钮 -->
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_one_power_add"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:text="+"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:textSize="10sp"
|
||||
android:id="@+id/tv_one_power"
|
||||
android:text="20.0v"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="40dp"
|
||||
android:gravity="right"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:gravity="right"
|
||||
android:textSize="10sp"
|
||||
android:text="保护动作:"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_marginLeft="55dp"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rl_one_power_protect"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"
|
||||
android:id="@+id/tv_one_power_protect"
|
||||
android:gravity="center"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:text="返航"
|
||||
android:layout_width="80dp"
|
||||
android:padding="5dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<ImageView
|
||||
android:layout_marginRight="5dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:src="@mipmap/icon_spinner_dowm"
|
||||
android:layout_width="10dp"
|
||||
android:layout_height="10dp"/>
|
||||
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
<Spinner
|
||||
android:layout_below="@+id/rl_one_power_protect"
|
||||
android:id="@+id/sp_one_power_protect"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="0dp" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 二级电压 -->
|
||||
<LinearLayout
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:gravity="right"
|
||||
android:textSize="10sp"
|
||||
android:text="二级低电压:"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<!-- 减按钮 -->
|
||||
<TextView
|
||||
android:layout_marginLeft="30dp"
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_two_power_minus"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:text="-"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
<!-- 滑动条 -->
|
||||
<SeekBar
|
||||
android:layout_marginLeft="3dp"
|
||||
android:layout_marginRight="3dp"
|
||||
android:id="@+id/seekBar_two_power"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:max="100"
|
||||
android:progress="20"
|
||||
/>
|
||||
|
||||
<!-- 加按钮 -->
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_two_power_add"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:text="+"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:textSize="10sp"
|
||||
android:id="@+id/tv_two_power"
|
||||
android:text="10.0v"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="40dp"
|
||||
android:gravity="right"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:gravity="right"
|
||||
android:textSize="10sp"
|
||||
android:text="保护动作:"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_marginLeft="55dp"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rl_two_power_protect"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_two_power_protect"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"
|
||||
android:gravity="center"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:text="返航"
|
||||
android:layout_width="80dp"
|
||||
android:padding="5dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<ImageView
|
||||
android:layout_marginRight="5dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:src="@mipmap/icon_spinner_dowm"
|
||||
android:layout_width="10dp"
|
||||
android:layout_height="10dp"/>
|
||||
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/sp_two_power_protect"
|
||||
android:layout_below="@+id/rl_two_power_protect"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="0dp"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<RelativeLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<View
|
||||
android:layout_centerVertical="true"
|
||||
android:background="@drawable/ffffffff_4round_bg"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1.5dp"/>
|
||||
|
||||
<TextView
|
||||
android:background="@drawable/ff112446_4round_bg"
|
||||
android:gravity="center"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_margin="6dp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="14sp"
|
||||
android:text="链路保护"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</RelativeLayout>
|
||||
<LinearLayout
|
||||
android:padding="12dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<!-- 一级电压 -->
|
||||
<LinearLayout
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:gravity="right"
|
||||
android:textSize="10sp"
|
||||
android:text="通讯超时:"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<!-- 减按钮 -->
|
||||
<TextView
|
||||
android:layout_marginLeft="30dp"
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_link_minus"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:text="-"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/et_link"
|
||||
android:inputType="number"
|
||||
android:gravity="center"
|
||||
android:padding="5dp"
|
||||
android:text="10"
|
||||
android:textColor="#909090"
|
||||
android:textSize="10sp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:background="@drawable/ffffffff_4round_bg"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<!-- 加按钮 -->
|
||||
<TextView
|
||||
android:gravity="center"
|
||||
android:id="@+id/tv_link_add"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:text="+"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"/>
|
||||
|
||||
|
||||
<TextView
|
||||
android:textSize="10sp"
|
||||
android:id="@+id/tv_link"
|
||||
android:text="秒"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="40dp"
|
||||
android:gravity="right"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:gravity="right"
|
||||
android:textSize="10sp"
|
||||
android:text="保护动作:"
|
||||
android:textColor="#ffffff"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_marginLeft="55dp"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rl_link_protect"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_link_protect"
|
||||
android:background="@drawable/ff62a7f0_2round_1stroke_bg"
|
||||
android:gravity="center"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="10sp"
|
||||
android:text="返航"
|
||||
android:layout_width="80dp"
|
||||
android:padding="5dp"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<ImageView
|
||||
android:layout_marginRight="5dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:src="@mipmap/icon_spinner_dowm"
|
||||
android:layout_width="10dp"
|
||||
android:layout_height="10dp"/>
|
||||
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/sp_link_protect"
|
||||
android:layout_below="@+id/rl_link_protect"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="0dp"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
BIN
app/src/main/res/mipmap-xhdpi/icon_ft60.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
app/src/main/res/mipmap-xhdpi/icon_marker.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/mipmap-xhdpi/icon_ptz_amplify.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
app/src/main/res/mipmap-xhdpi/icon_ptz_down.png
Normal file
|
After Width: | Height: | Size: 928 B |
BIN
app/src/main/res/mipmap-xhdpi/icon_ptz_left.png
Normal file
|
After Width: | Height: | Size: 928 B |
BIN
app/src/main/res/mipmap-xhdpi/icon_ptz_one_bottom.png
Normal file
|
After Width: | Height: | Size: 559 B |
BIN
app/src/main/res/mipmap-xhdpi/icon_ptz_reduce.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/mipmap-xhdpi/icon_ptz_right.png
Normal file
|
After Width: | Height: | Size: 937 B |
BIN
app/src/main/res/mipmap-xhdpi/icon_ptz_top.png
Normal file
|
After Width: | Height: | Size: 885 B |
BIN
app/src/main/res/mipmap-xhdpi/icon_save.png
Normal file
|
After Width: | Height: | Size: 557 B |
BIN
app/src/main/res/mipmap-xhdpi/icon_spinner_dowm.png
Normal file
|
After Width: | Height: | Size: 636 B |