diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/App.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/App.java index f1943a9a49..e89e78ab58 100644 --- a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/App.java +++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/App.java @@ -5,9 +5,11 @@ import android.app.Application; import com.zhidao.adas.client.utils.CrashHandler; public class App extends Application { + public static App INSTANCE; @Override public void onCreate() { super.onCreate(); + INSTANCE = this; CrashHandler.getInstance().init(this); } } diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/DataDistribution.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/DataDistribution.java index bfd0bfb0a0..9421872e3f 100644 --- a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/DataDistribution.java +++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/DataDistribution.java @@ -11,9 +11,9 @@ import com.zhidao.adas.client.bean.ErrorData; import com.zhidao.adas.client.bean.GlobalPathResp; import com.zhidao.adas.client.bean.GnssInfo; import com.zhidao.adas.client.bean.MogoReportMessage; -import com.zhidao.adas.client.bean.MyPointCloud; import com.zhidao.adas.client.bean.OriginalPointCloudData; import com.zhidao.adas.client.bean.PerceptionTrafficLight; +import com.zhidao.adas.client.bean.PlanningDecisionState; import com.zhidao.adas.client.bean.PlanningObjects; import com.zhidao.adas.client.bean.PredictionObstacleTrajectory; import com.zhidao.adas.client.bean.RecordDataConfig; @@ -114,9 +114,9 @@ public class DataDistribution { public final List listStatusInfo = new ArrayList<>(); public final List listRecordDataConfig = new ArrayList<>(); public final List listErrorData = new ArrayList<>(); - public final List listPointCloud = new ArrayList<>(); public final List listOriginalPointCloud = new ArrayList<>(); public final List listPlanningObjects = new ArrayList<>(); + public final List listPlanningDecisionState = new ArrayList<>(); public String cutDown(String str) { if (isCutDown && str.length() > 650) { @@ -144,14 +144,6 @@ public class DataDistribution { if (listener != null && Constants.TITLE.RECEIVE_TRACKED_OBJECTS.equals(listener.first)) { listener.second.onRefresh(); } - } else if (data instanceof MyPointCloud) { - listPointCloud.add(0, time + str); - if (listPointCloud.size() > LIST_SIZE) { - listPointCloud.remove(listPointCloud.size() - 1); - } - if (listener != null && Constants.TITLE.RECEIVE_POINT_CLOUD.equals(listener.first)) { - listener.second.onRefresh(); - } } else if (data instanceof OriginalPointCloudData) { listOriginalPointCloud.add(0, time + str); if (listOriginalPointCloud.size() > LIST_SIZE) { @@ -168,6 +160,14 @@ public class DataDistribution { if (listener != null && Constants.TITLE.RECEIVE_PLANNING_OBJECTS.equals(listener.first)) { listener.second.onRefresh(); } + } else if (data instanceof PlanningDecisionState) { + listPlanningDecisionState.add(0, time + str); + if (listPlanningDecisionState.size() > LIST_SIZE) { + listPlanningDecisionState.remove(listPlanningDecisionState.size() - 1); + } + if (listener != null && Constants.TITLE.RECEIVE_PLANNING_DECISION_STATE.equals(listener.first)) { + listener.second.onRefresh(); + } } else if (data instanceof GnssInfo) { listGnssInfo.add(0, time + str); if (listGnssInfo.size() > LIST_SIZE) { diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/adapter/InterfaceAdapter.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/adapter/InterfaceAdapter.java new file mode 100644 index 0000000000..7e4fa74544 --- /dev/null +++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/adapter/InterfaceAdapter.java @@ -0,0 +1,217 @@ +package com.zhidao.adas.client.adapter; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.zhidao.adas.client.R; +import com.zhidao.adas.client.bean.InterfaceModel; +import com.zhidao.support.adas.high.common.MessageType; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +public class InterfaceAdapter extends RecyclerView.Adapter { + + private List mDatas; + private boolean isEnabled = true;//是否可操作 + private boolean oldIsEnabled = isEnabled; + private int isCheckAll = 2;//0:全选 1:全不选 2:任意选 + private int checkNum; + private boolean oldIsCheckAll = false; + + private OnInterfaceAdapterListener listener; + + public void setListener(OnInterfaceAdapterListener listener) { + this.listener = listener; + } + + public interface OnInterfaceAdapterListener { + void onCheckAll(boolean isCheckAll); + + void onCheckNum(int checkNum); + } + + public int getCheckNum() { + return checkNum; + } + + //获取已选中的 + public Set getCheckedModel() { + Set messageTypes = new HashSet<>(); + if (mDatas != null) { + for (InterfaceModel model : mDatas) { + if (model.isSelected()) { + messageTypes.add(model.getMessageType()); + } + } + } + return messageTypes; + } + + private void init() { + isEnabled = true; + oldIsEnabled = true; + isCheckAll = 2; + checkNum = 0; + } + + public void setData(List mDatas, int checkNum) { + init(); + this.mDatas = mDatas; + if (mDatas != null && !mDatas.isEmpty()) { + this.checkNum = checkNum; + updateCheckAllStatus(true); + } + } + + //全选 全不选 + public void setCheckAll(boolean checkAll) { + isCheckAll = checkAll ? 0 : 1; + checkNum = checkAll ? getItemCount() : 0; + notifyDataSetChanged(); + updateCheckNumStatusCall(); + updateCheckAllStatus(false); + } + + public void setEnabled(boolean isEnabled) { + if (oldIsEnabled != isEnabled) { + oldIsEnabled = isEnabled; + this.isEnabled = isEnabled; + notifyDataSetChanged(); + } + + } + + //创建ViewHolder + @NonNull + @Override + public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + //实例化得到Item布局文件的View对象 + View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_interface, parent, false); + //返回MyViewHolder的对象 + return new MyViewHolder(v); + } + + //绑定数据 + @Override + public void onBindViewHolder(@NonNull MyViewHolder holder, int position) { + holder.index.setEnabled(isEnabled); + holder.name.setEnabled(isEnabled); + holder.itemView.setEnabled(isEnabled); + holder.itemCheck.setEnabled(isEnabled); + InterfaceModel model = mDatas.get(position); + holder.name.setText(model.getMessageType().desc); + holder.index.setText((position + 1) + "."); + if (isCheckAll == 0) { + model.setSelected(true); + } else if (isCheckAll == 1) { + model.setSelected(false); + } + holder.itemCheck.setChecked(model.isSelected()); + + } + + //返回Item的数量 + @Override + public int getItemCount() { + return mDatas == null ? 0 : mDatas.size(); + } + + /*** + * 获取制定 位置的Data + * @param position 下标 + * @return Data + */ + public InterfaceModel getItem(int position) { + return mDatas == null ? null : mDatas.get(position); + } + + //继承RecyclerView.ViewHolder抽象类的自定义ViewHolder + class MyViewHolder extends RecyclerView.ViewHolder { + TextView name; + TextView index; + CheckBox itemCheck; + + MyViewHolder(View itemView) { + super(itemView); + index = itemView.findViewById(R.id.index); + name = itemView.findViewById(R.id.name); + name.setSelected(true); + itemCheck = itemView.findViewById(R.id.item_check); + init(); + + } + + private void init() { + itemView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + InterfaceModel model = getItem(getBindingAdapterPosition()); + model.setSelected(!model.isSelected()); + updateCheckNum(model.isSelected()); + itemCheck.setChecked(model.isSelected()); + } + }); + itemCheck.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (buttonView.isPressed()) { + updateCheckNum(isChecked); + InterfaceModel model = getItem(getBindingAdapterPosition()); + model.setSelected(isChecked); + } + } + }); + } + } + + //更新选中个数 + private void updateCheckNum(boolean isChecked) { + if (isChecked) { + checkNum++; + } else { + checkNum--; + } + updateCheckNumStatusCall(); + updateCheckAllStatus(true); + } + + private void updateCheckNumStatusCall() { + if (listener != null) + listener.onCheckNum(checkNum); + } + + //更新全选状态 + private void updateCheckAllStatus(boolean isNotice) { + if (getItemCount() == checkNum) { + isCheckAll = 0; + updateCheckAllStatusCall(isNotice, true); + } else if (0 == checkNum) { + isCheckAll = 1; + updateCheckAllStatusCall(isNotice, false); + } else { + isCheckAll = 2; + updateCheckAllStatusCall(isNotice, false); + } + + } + + private void updateCheckAllStatusCall(boolean isNotice, boolean isCheckAll) { + if (isNotice) + if (oldIsCheckAll != isCheckAll) { + oldIsCheckAll = isCheckAll; + if (listener != null) + listener.onCheckAll(isCheckAll); + } + + } +} diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/adapter/SpecialVehicleAdapter.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/adapter/SpecialVehicleAdapter.java new file mode 100644 index 0000000000..a7eedf2245 --- /dev/null +++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/adapter/SpecialVehicleAdapter.java @@ -0,0 +1,60 @@ +package com.zhidao.adas.client.adapter; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.zhidao.adas.client.R; +import com.zhidao.adas.client.base.BaseAdapter; +import com.zhidao.adas.client.base.BaseViewHolder; +import com.zhidao.adas.client.bean.SpecialVehicleBean; + +import java.util.List; + +/** + * @author song kenan + * @des 线路 + * @date 2021/8/13 + */ +public class SpecialVehicleAdapter extends BaseAdapter { + + + public SpecialVehicleAdapter(List data) { + super(data); + } + + @Override + public void setData(List mDatas) { + super.setData(mDatas); + } + + @Override + protected void onBindDataToItem(ViewHolder viewHolder, SpecialVehicleBean data, int position) { + viewHolder.title.setText(data.name); + } + + @Override + protected View getItemViewResource(ViewGroup viewGroup) { + return LayoutInflater.from(mContext).inflate(R.layout.item_info, viewGroup, false); + } + + @Override + protected ViewHolder getViewHolder(View view) { + return new ViewHolder(view, this); + } + + class ViewHolder extends BaseViewHolder { + TextView title; + + public ViewHolder(View itemView, SpecialVehicleAdapter adapter) { + super(itemView, adapter); +// ViewGroup.LayoutParams layoutParams = itemView.getLayoutParams(); +// if (layoutParams != null) { +// layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT; +// +// } + title = itemView.findViewById(R.id.tv_info_title); + } + } +} diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/base/BaseFragment.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/base/BaseFragment.java index 0516493d30..9dcf870c14 100644 --- a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/base/BaseFragment.java +++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/base/BaseFragment.java @@ -27,6 +27,7 @@ import perception.TrafficLightOuterClass; public abstract class BaseFragment extends Fragment { protected final String TAG = this.getClass().getSimpleName(); private static final int WHAT_REFRESH = 0x01; + private static final int WHAT_UPDATE_CONNECT_STATUS = 0x02; protected static final int WHAT_REFRESH_TRAFFIC_LIGHTS = 0x02; protected String title; @@ -64,6 +65,18 @@ public abstract class BaseFragment extends Fragment { } } + public void updateConnectStatus(int ipcConnectionStatus) { + if (getHandler() != null) { + Message msg = Message.obtain(); + msg.what = WHAT_UPDATE_CONNECT_STATUS; + msg.arg1 = ipcConnectionStatus; + getHandler().sendMessage(msg); + } + } + + protected void onConnectionIPCStatus(int ipcConnectionStatus) { + + } @Override public void onDestroyView() { @@ -197,6 +210,11 @@ public abstract class BaseFragment extends Fragment { if (isVisible()) onRefreshView(); break; + + case WHAT_UPDATE_CONNECT_STATUS: + if (isVisible()) + onConnectionIPCStatus(msg.arg1); + break; } } diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/bean/InterfaceModel.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/bean/InterfaceModel.java new file mode 100644 index 0000000000..e63d64b336 --- /dev/null +++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/bean/InterfaceModel.java @@ -0,0 +1,34 @@ +package com.zhidao.adas.client.bean; + +import com.zhidao.support.adas.high.common.MessageType; + + +public class InterfaceModel { + private boolean isSelected = false;//是否选择 + private final MessageType messageType; + + public InterfaceModel(MessageType messageType) { + this.messageType = messageType; + } + + public boolean isSelected() { + return isSelected; + } + + public void setSelected(boolean selected) { + isSelected = selected; + } + + public MessageType getMessageType() { + return messageType; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + InterfaceModel that = (InterfaceModel) o; + return messageType == that.messageType; + } + +} diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/bean/PlanningDecisionState.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/bean/PlanningDecisionState.java new file mode 100644 index 0000000000..c443774c36 --- /dev/null +++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/bean/PlanningDecisionState.java @@ -0,0 +1,23 @@ +package com.zhidao.adas.client.bean; + +import com.google.protobuf.TextFormat; + +import java.text.SimpleDateFormat; + +import mogo.telematics.pad.MessagePad; + +public class PlanningDecisionState extends BaseInfo { + public final MessagePad.PlanningActionMsg bean; + + public PlanningDecisionState(MessagePad.Header header, MessagePad.PlanningActionMsg bean, SimpleDateFormat sdf) { + super("接收", bean.getSerializedSize(), header, sdf); + this.bean = bean; + } + + + @Override + public String toString() { + return super.toString() + TextFormat.printer().escapingNonAscii(false).printToString(bean); + } + +} diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/bean/SpecialVehicleBean.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/bean/SpecialVehicleBean.java new file mode 100644 index 0000000000..f911f61830 --- /dev/null +++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/bean/SpecialVehicleBean.java @@ -0,0 +1,228 @@ +package com.zhidao.adas.client.bean; + +import android.content.Context; +import android.text.TextUtils; + +import androidx.annotation.NonNull; + +import com.google.protobuf.TextFormat; +import com.zhidao.adas.client.ui.special.SpecialVehicleFloatWindowManager; +import com.zhidao.adas.client.utils.PreferencesUtils; +import com.zhidao.support.adas.high.AdasManager; + +import java.util.ArrayList; +import java.util.List; + +import chassis.SpecialVehicleTaskCmdOuterClass; + +public class SpecialVehicleBean { + private interface TAG { + String FTQSC = "ftqsc";//福田清扫车 + String KWXB = "kwxb";//开沃小巴 + } + + public interface SEND_TYPE { + int ONE = 0;//单次发送 + int MORE = 1;//多次发送 + int ALL = 2;//两种方式都支持 + } + + public final String name; + public final String simpleName;//简单名字 两个字 + public final List options; + private final String tag;//用于存储 + public int sendType = SEND_TYPE.ONE;//发送类型 + private SpecialVehicleFloatWindowManager manager; + + public static final int SCREEN_MARGIN = 20; + + private final String FLOAT_WINDOW_LOCATION_MIN_X; + private final String FLOAT_WINDOW_LOCATION_MIN_Y; + private final String FLOAT_WINDOW_LOCATION_MAX_X; + private final String FLOAT_WINDOW_LOCATION_MAX_Y; + + private SpecialVehicleBean(@NonNull String name, @NonNull String simpleName, String tag, List options) { + this.name = name; + this.simpleName = simpleName; + this.tag = tag; + this.options = options; + FLOAT_WINDOW_LOCATION_MIN_X = tag + "_float_window_location_min_x"; + FLOAT_WINDOW_LOCATION_MIN_Y = tag + "_float_window_location_min_y"; + FLOAT_WINDOW_LOCATION_MAX_X = tag + "_float_window_location_max_X"; + FLOAT_WINDOW_LOCATION_MAX_Y = tag + "_float_window_location_max_y"; + + } + + public void showFloat(Context context) { + if (manager == null) + manager = new SpecialVehicleFloatWindowManager(context, this); + manager.show(); + } + + public void dismissFloat() { + if (manager != null) { + manager.onBack(); + manager = null; + } + } + + /************************悬浮窗位置******************/ + + + public void setFloatWindowLocationMinX(Context context, int x) { + PreferencesUtils.putInt(context, FLOAT_WINDOW_LOCATION_MIN_X, x); + } + + public int getFloatWindowLocationMinX(Context context) { + return PreferencesUtils.getInt(context, FLOAT_WINDOW_LOCATION_MIN_X, SCREEN_MARGIN); + } + + public void setFloatWindowLocationMinY(Context context, int y) { + PreferencesUtils.putInt(context, FLOAT_WINDOW_LOCATION_MIN_Y, y); + } + + public int getFloatWindowLocationMinY(Context context) { + return PreferencesUtils.getInt(context, FLOAT_WINDOW_LOCATION_MIN_Y, SCREEN_MARGIN); + } + + + /************************悬浮窗位置******************/ + + public void setFloatWindowLocationMaxX(Context context, int x) { + PreferencesUtils.putInt(context, FLOAT_WINDOW_LOCATION_MAX_X, x); + } + + public int getFloatWindowLocationMaxX(Context context) { + return PreferencesUtils.getInt(context, FLOAT_WINDOW_LOCATION_MAX_X, SCREEN_MARGIN); + } + + public void setFloatWindowLocationMaxY(Context context, int y) { + PreferencesUtils.putInt(context, FLOAT_WINDOW_LOCATION_MAX_Y, y); + } + + public int getFloatWindowLocationMaxY(Context context) { + return PreferencesUtils.getInt(context, FLOAT_WINDOW_LOCATION_MAX_Y, SCREEN_MARGIN); + } + + /** + * 命令下发 + * + * @param index -1一次性发送所有命令 其他 单个命令发送 + * @return + */ + public String sendCmd(int index) { + String str = ""; + if (TextUtils.equals(this.tag, TAG.FTQSC)) { //福田清扫车 + SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianCleanCmd.Builder builder = SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianCleanCmd.newBuilder(); + if (index < 0) { + for (index = 0; index < options.size(); index++) { + SpecialVehicleOption option = options.get(index); + if (option.moreCheckPos != -1) { + option.checkPos = option.moreCheckPos; + option.moreCheckPos = -1; + } + setFuTianCleanValue(builder, index, option.checkPos); + } + } else { + int checkPos = options.get(index).checkPos; + setFuTianCleanValue(builder, index, checkPos); + } + + SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianCleanCmd fuTianCleanCmd = builder.build(); + SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianTaskCmd fuTianTaskCmd = SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianTaskCmd.newBuilder() + .setRoboSweeperFutianCleanCmd(fuTianCleanCmd).build(); + AdasManager.getInstance().sendRoboSweeperFuTianTaskCmd(fuTianTaskCmd); + str = TextFormat.printer().escapingNonAscii(false).printToString(fuTianTaskCmd).replaceAll("\n", ""); + } else if (TextUtils.equals(this.tag, TAG.KWXB)) { //开沃小巴 + SpecialVehicleTaskCmdOuterClass.RoboVanSkywellTaskCmd vanSkywellTaskCmd = SpecialVehicleTaskCmdOuterClass.RoboVanSkywellTaskCmd.newBuilder() + .build(); + AdasManager.getInstance().sendRoboVanSkywellTaskCmd(vanSkywellTaskCmd); + } + return str; + } + + private void setFuTianCleanValue(SpecialVehicleTaskCmdOuterClass.RoboSweeperFuTianCleanCmd.Builder builder, int index, int checkPos) { + switch (index) { + case 0: + builder.setCleanOpenRequirement(checkPos); + break; + case 1: + builder.setCleanModeRequirement(checkPos); + break; + case 2: + builder.setCleanDirectionRequirement(checkPos); + break; + case 3: + builder.setCleanIntensityRequirement(checkPos); + break; + case 4: + builder.setDuskCloseRequirement(checkPos); + break; + case 5: + builder.setSuctionNozzlefleOpenRequirement(checkPos); + break; + case 6: + builder.setSprayGunOpenRequirement(checkPos); + break; + case 7: + builder.setSweepdiskSpeedRequirement(checkPos); + break; + } + } + + + public static List init() { + List list = new ArrayList<>(); + List optionsF = new ArrayList<>(); + int tag = 0; + String[] value = new String[3]; + value[0] = "0-No Req"; + value[1] = "1-Start"; + value[2] = "2-Stop"; + optionsF.add(new SpecialVehicleOption("清扫作业", tag++, value, 0)); + value = new String[5]; + value[0] = "0-No Req"; + value[1] = "1-Sweeping"; + value[2] = "2-Wash Sweeper"; + value[3] = "3-Pure Wash"; + value[4] = "4-Pure Draw"; + optionsF.add(new SpecialVehicleOption("清扫模式", tag++, value, 0)); + value = new String[4]; + value[0] = "0-No Req"; + value[1] = "1-Both"; + value[2] = "2-Left"; + value[3] = "3-Right"; + optionsF.add(new SpecialVehicleOption("清扫方向", tag++, value, 0)); + value = new String[3]; + value[0] = "0-No Req"; + value[1] = "1-Stand"; + value[2] = "2-Strong"; + optionsF.add(new SpecialVehicleOption("作业强度", tag++, value, 0)); + value = new String[3]; + value[0] = "0-No Req"; + value[1] = "1-Close"; + value[2] = "2-Open"; + optionsF.add(new SpecialVehicleOption("降尘", tag++, value, 0)); + value = new String[3]; + value[0] = "0-No Req"; + value[1] = "1-Open"; + value[2] = "2-Close"; + optionsF.add(new SpecialVehicleOption("吸嘴挡板", tag++, value, 0)); + value = new String[3]; + value[0] = "0-No Req"; + value[1] = "1-Open"; + value[2] = "2-Close"; + optionsF.add(new SpecialVehicleOption("喷雾枪", tag++, value, 0)); + value = new String[3]; + value[0] = "0-No Req"; + value[1] = "1-Decelerate"; + value[2] = "2-Accelerate"; + optionsF.add(new SpecialVehicleOption("扫盘加速", tag, value, 0)); + SpecialVehicleBean beanF = new SpecialVehicleBean("福田清扫车", "福清", TAG.FTQSC, optionsF); + SpecialVehicleBean beanK = new SpecialVehicleBean("开沃小巴", "开巴", TAG.KWXB, null); + list.add(beanF); + list.add(beanK); + return list; + } + +} diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/bean/SpecialVehicleOption.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/bean/SpecialVehicleOption.java new file mode 100644 index 0000000000..26f2ec883a --- /dev/null +++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/bean/SpecialVehicleOption.java @@ -0,0 +1,16 @@ +package com.zhidao.adas.client.bean; + +public class SpecialVehicleOption { + public final String name; + public final int tag; + public final String[] value; + public int checkPos = 0;//选中的下标 + public int moreCheckPos = -1;//发送模式下多条模式时选中的下标 + + public SpecialVehicleOption(String name, int tag, String[] value, int checkPos) { + this.name = name; + this.tag = tag; + this.value = value; + this.checkPos = checkPos; + } +} diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/InfoFragment.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/InfoFragment.java index 784cd76c99..7cf79e26e6 100644 --- a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/InfoFragment.java +++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/InfoFragment.java @@ -129,12 +129,12 @@ public class InfoFragment extends BaseFragment { adapter.setData(DataDistribution.getInstance().listPerceptionTrafficLight); } else if (Constants.TITLE.RECEIVE_PREDICTION_OBSTACLE_TRAJECTORY.equals(title)) { adapter.setData(DataDistribution.getInstance().listPredictionObstacleTrajectory); - } else if (Constants.TITLE.RECEIVE_POINT_CLOUD.equals(title)) { - adapter.setData(DataDistribution.getInstance().listPointCloud); } else if (Constants.TITLE.RECEIVE_POINT_CLOUD_ORIGINAL.equals(title)) { adapter.setData(DataDistribution.getInstance().listOriginalPointCloud); } else if (Constants.TITLE.RECEIVE_PLANNING_OBJECTS.equals(title)) { adapter.setData(DataDistribution.getInstance().listPlanningObjects); + } else if (Constants.TITLE.RECEIVE_PLANNING_DECISION_STATE.equals(title)) { + adapter.setData(DataDistribution.getInstance().listPlanningDecisionState); } else { adapter.setData(DataDistribution.getInstance().listErrorData); } diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/MainActivity.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/MainActivity.java index c96b79002f..caacd35d10 100644 --- a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/MainActivity.java +++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/MainActivity.java @@ -35,7 +35,6 @@ import android.widget.Toast; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.AppCompatButton; -import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; import androidx.recyclerview.widget.GridLayoutManager; @@ -54,6 +53,7 @@ import com.zhidao.adas.client.R; import com.zhidao.adas.client.adapter.InfoTitleAdapter; import com.zhidao.adas.client.base.BaseActivity; import com.zhidao.adas.client.base.BaseAdapter; +import com.zhidao.adas.client.base.BaseFragment; import com.zhidao.adas.client.bean.ArrivalNotification; import com.zhidao.adas.client.bean.AutopilotState; import com.zhidao.adas.client.bean.BasicInfoReq; @@ -65,10 +65,12 @@ import com.zhidao.adas.client.bean.IPCConnectState; import com.zhidao.adas.client.bean.MogoReportMessage; import com.zhidao.adas.client.bean.OriginalPointCloudData; import com.zhidao.adas.client.bean.PerceptionTrafficLight; +import com.zhidao.adas.client.bean.PlanningDecisionState; import com.zhidao.adas.client.bean.PlanningObjects; import com.zhidao.adas.client.bean.PredictionObstacleTrajectory; import com.zhidao.adas.client.bean.RecordDataConfig; import com.zhidao.adas.client.bean.RecordPanel; +import com.zhidao.adas.client.bean.SpecialVehicleBean; import com.zhidao.adas.client.bean.StatusInfo; import com.zhidao.adas.client.bean.TrackedObjects; import com.zhidao.adas.client.bean.Trajectory; @@ -76,6 +78,7 @@ import com.zhidao.adas.client.bean.VehicleState; import com.zhidao.adas.client.bean.Warn; import com.zhidao.adas.client.log.ConnectStatusSave; import com.zhidao.adas.client.log.LogSave; +import com.zhidao.adas.client.ui.special.SpecialVehicleDialog; import com.zhidao.adas.client.utils.Constants; import com.zhidao.adas.client.utils.PreferencesUtils; import com.zhidao.support.adas.high.AdasManager; @@ -87,11 +90,13 @@ import com.zhidao.support.adas.high.bean.VersionCompatibility; import com.zhidao.support.adas.high.common.ByteUtil; import com.zhidao.support.adas.high.common.Constants.IPC_CONNECTION_STATUS; import com.zhidao.support.adas.high.common.CupidLogUtils; +import com.zhidao.support.adas.high.common.MessageType; import com.zhidao.support.adas.high.common.ProtocolStatus; import com.zhidao.support.adas.high.common.ReceiveTimeoutManager; import com.zhidao.support.adas.high.other.permission.BackgrounderPermission; import com.zhidao.support.adas.high.other.permission.OnAdasPermissionListener; import com.zhidao.support.adas.high.other.router.RouterActivity; +import com.zhidao.support.adas.high.subscribe.SubscribeInterfaceOptions; import java.net.Inet4Address; import java.net.InetAddress; @@ -101,8 +106,10 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; +import java.util.HashSet; import java.util.List; import java.util.Locale; +import java.util.Set; import java.util.concurrent.ScheduledExecutorService; import chassis.VehicleStateOuterClass; @@ -148,7 +155,7 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas private final List titleBtnData = new ArrayList<>(); private final List connectStatusList = new ArrayList<>(); private InfoTitleAdapter fragmentAdapter; - private Fragment fromFragment; + private BaseFragment fromFragment; private FragmentManager manager; private String ftpTime; private boolean isPad; @@ -156,9 +163,11 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas private String recordFileName; private int connectStatus; private AutoPilotModeDialog autoPilotModeDialog; + private SpecialVehicleDialog specialVehicleDialog; private ListPopupWindow listPopupWindow; private FloatWindow floatWindow; private View include_title; + private List specialVehicleBeanList;//特种车辆 // @Override // protected void onStart() { // super.onStart(); @@ -248,6 +257,14 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas wakeLock.release(); if (wifiLock != null) wifiLock.release(); + if (autoPilotModeDialog != null && autoPilotModeDialog.isShowing()) { + autoPilotModeDialog.dismiss(); + autoPilotModeDialog = null; + } + if (specialVehicleDialog != null && specialVehicleDialog.isShowing()) { + specialVehicleDialog.dismiss(); + specialVehicleDialog = null; + } } private void canDrawOverlays() { @@ -613,9 +630,9 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas titleFragmentData.add(Constants.TITLE.RECEIVE_REPORT_MESSAGE); titleFragmentData.add(Constants.TITLE.RECEIVE_PERCEPTION_TRAFFIC_LIGHT); titleFragmentData.add(Constants.TITLE.RECEIVE_PREDICTION_OBSTACLE_TRAJECTORY); - titleFragmentData.add(Constants.TITLE.RECEIVE_POINT_CLOUD); titleFragmentData.add(Constants.TITLE.RECEIVE_POINT_CLOUD_ORIGINAL); titleFragmentData.add(Constants.TITLE.RECEIVE_PLANNING_OBJECTS); + titleFragmentData.add(Constants.TITLE.RECEIVE_PLANNING_DECISION_STATE); titleFragmentData.add(Constants.TITLE.RECEIVE_CAR_CONFIG_RESP); titleFragmentData.add(Constants.TITLE.RECEIVE_RECORD_DATA_CONFIG_RESP); titleFragmentData.add(Constants.TITLE.RECEIVE_RECORD_RESULT); @@ -628,6 +645,7 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas titleBtnData.add(Constants.TITLE.SEND_SET_AUTOPILOT_MODE_REQ); titleBtnData.add(Constants.TITLE.SEND_GLOBAL_PATH_REQ); + titleBtnData.add(Constants.TITLE.SEND_SPECIAL_VEHICLE_TASK_CMD); titleBtnData.add(Constants.TITLE.SEND_STATUS_QUERY_REQ); titleBtnData.add(Constants.TITLE.SEND_BASIC_INFO_RESP); titleBtnData.add(Constants.TITLE.SEND_RECORD_DATA_CONFIG_RESP); @@ -882,7 +900,7 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas public void onBasicInfoReq(MessagePad.Header header, MessagePad.BasicInfoReq basicInfoReq) { BasicInfoReq info = new BasicInfoReq(header, basicInfoReq, sdf); DataDistribution.getInstance().addData(info); - AdasManager.getInstance().sendBasicInfoResp("X202021111192N41VY", 0); + AdasManager.getInstance().sendBasicInfoResp("", 0, com.zhidao.support.adas.high.common.Constants.TERMINAL_ROLE.DEBUG); showToastCenter("收到车机基础信息请求:" + info.toString()); } @@ -930,6 +948,12 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas DataDistribution.getInstance().addData(base); } + @Override + public void onPlanningActionMsg(MessagePad.Header header, MessagePad.PlanningActionMsg planningActionMsg) { + PlanningDecisionState base = new PlanningDecisionState(header, planningActionMsg, sdf); + DataDistribution.getInstance().addData(base); + } + private void initAdas() { CupidLogUtils.e(TAG, "--->初始化"); @@ -961,13 +985,19 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas } else { /*—————————————作为司机端———————————*/ int mode = Constants.getIpcConnectionMode(this); + Set messageTypes = new HashSet<>(); + messageTypes.add(MessageType.TYPE_RECEIVE_POINT_CLOUD); + SubscribeInterfaceOptions subscribeInterfaceOptions = SubscribeInterfaceOptions.newBuilder() + .setRole(com.zhidao.support.adas.high.common.Constants.TERMINAL_ROLE.DEBUG) + .setType(com.zhidao.support.adas.high.common.Constants.SUBSCRIBE_TYPE.UNSUBSCRIBE) + .setMessageTypes(messageTypes).build(); switch (mode) { default: case AdasOptions.IPC_CONNECTION_MODE.FIXATION: - options = new AdasOptions.Builder().setClient(false).setIpcFixationIP(AdasManager.getInstance().getIPCFixationIPList(this)).setIpcConnectionMode(mode).build(); + options = new AdasOptions.Builder().setSubscribeInterfaceOptions(subscribeInterfaceOptions).setClient(false).setIpcFixationIP(AdasManager.getInstance().getIPCFixationIPList(this)).setIpcConnectionMode(mode).build(); break; case AdasOptions.IPC_CONNECTION_MODE.ASSIGN: - options = new AdasOptions.Builder().setClient(false).setIpcAssignIP(Constants.getIPCIp(this)).setIpcConnectionMode(mode).build(); + options = new AdasOptions.Builder().setSubscribeInterfaceOptions(subscribeInterfaceOptions).setClient(false).setIpcAssignIP(Constants.getIPCIp(this)).setIpcConnectionMode(mode).build(); break; } @@ -1024,6 +1054,9 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas @Override public void onConnectionIPCStatus(int ipcConnectionStatus, String reason) { + if (fromFragment != null) { + fromFragment.updateConnectStatus(ipcConnectionStatus); + } // Log.i(TAG, "连接状态=" + (reason == null ? "主动断开连接" : reason)); String time = sdf.format(new Date()); ConnectStatusSave.getInstance().saveLog(time + " ipcConnectionStatus=" + ipcConnectionStatus + " reason=" + reason); @@ -1033,15 +1066,14 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas } connectStatus = ipcConnectionStatus; String status = onUpdateConnectStateView(); + getHandler().sendEmptyMessage(WHAT_IPC_IP); if (connectStatus == IPC_CONNECTION_STATUS.CONNECTED) { - getHandler().sendEmptyMessage(WHAT_IPC_IP); + String tem = getIPCIP(); if (!TextUtils.isEmpty(tem)) { List ips = Constants.getIpcUsedIps(this); Constants.addIpcUsedIps(this, ips, tem); } - } else if (connectStatus == IPC_CONNECTION_STATUS.DISCONNECTED) { - getHandler().sendEmptyMessage(WHAT_IPC_IP); } // LogSave.getInstance().saveLog("连接状态", status); // CupidLogUtils.i(TAG, "connectStatus=" + status); @@ -1089,7 +1121,7 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas } private void showFragment(String title) { - Fragment to = manager.findFragmentByTag(title); + BaseFragment to = (BaseFragment) manager.findFragmentByTag(title); if (to == null) { if (Constants.TITLE.RECEIVE_CAR_CONFIG_RESP.equals(title)) { to = new VersionFragment(Constants.TITLE.TITLE_CAR_CONFIG_RESP); @@ -1144,12 +1176,58 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas //自动驾驶路径查询 AdasManager.getInstance().sendGlobalPathReq(); break; + case Constants.TITLE.SEND_SPECIAL_VEHICLE_TASK_CMD: + if (specialVehicleBeanList == null) { + specialVehicleBeanList = SpecialVehicleBean.init(); + } + if (specialVehicleDialog == null) { + specialVehicleDialog = new SpecialVehicleDialog(this, specialVehicleBeanList); + } + if (!specialVehicleDialog.isShowing()) { + specialVehicleDialog.show(); + } + break; case Constants.TITLE.SEND_STATUS_QUERY_REQ: AdasManager.getInstance().sendStatusQueryReq(); break; case Constants.TITLE.SEND_BASIC_INFO_RESP: //发送sn - AdasManager.getInstance().sendBasicInfoResp("X202021111192N41VY", 0); + //速度设置 + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("发送SN"); + View view = getLayoutInflater().inflate(R.layout.dialog_sn, null); + final EditText et = view.findViewById(R.id.et); + final EditText ev = view.findViewById(R.id.ev); + final EditText role = view.findViewById(R.id.role); + builder.setView(view);// + builder.setCancelable(false);// + builder.setPositiveButton("发送", null); + //设置反面按钮,并做事件处理 + builder.setNegativeButton("取消", null); + AlertDialog alertDialog = builder.show();//显示Dialog对话框 + alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Editable editable = et.getText(); + if (TextUtils.isEmpty(editable)) { + // 条件不成立不能关闭 AlertDialog 窗口 + Toast.makeText(MainActivity.this, "请输入SN", Toast.LENGTH_SHORT).show(); + return; + } + int evInt = 0; + Editable evEd = ev.getText(); + if (!TextUtils.isEmpty(evEd)) { + evInt = Integer.parseInt(evEd.toString().trim()); + } + int roleInt = com.zhidao.support.adas.high.common.Constants.TERMINAL_ROLE.DEBUG; + Editable roleEd = role.getText(); + if (!TextUtils.isEmpty(roleEd)) { + roleInt = Integer.parseInt(roleEd.toString().trim()); + } + AdasManager.getInstance().sendBasicInfoResp(editable.toString().trim(), evInt, roleInt); + alertDialog.dismiss(); + } + }); break; case Constants.TITLE.SEND_RECORD_DATA_5: //数据采集5秒 @@ -1192,30 +1270,31 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas break; case Constants.TITLE.SEND_SET_AUTOPILOT_SPEED_REQ: //速度设置 - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle("自动驾驶限速"); - View view = getLayoutInflater().inflate(R.layout.dialog_speed, null); - final EditText et = (EditText) view.findViewById(R.id.et); - builder.setView(view);// - builder.setCancelable(false);// - builder.setPositiveButton("设置", new DialogInterface.OnClickListener() { + AlertDialog.Builder builder1 = new AlertDialog.Builder(this); + builder1.setTitle("自动驾驶限速"); + View view1 = getLayoutInflater().inflate(R.layout.dialog_speed, null); + final EditText et1 = (EditText) view1.findViewById(R.id.et); + builder1.setView(view1);// + builder1.setCancelable(false);// + builder1.setPositiveButton("设置", null); + //设置反面按钮,并做事件处理 + builder1.setNegativeButton("取消", null); + AlertDialog alertDialog1 = builder1.show();//显示Dialog对话框 + alertDialog1.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() { @Override - public void onClick(DialogInterface dialogInterface, int i) { - Editable editable = et.getText(); + public void onClick(View v) { + Editable editable = et1.getText(); if (TextUtils.isEmpty(editable)) { // 条件不成立不能关闭 AlertDialog 窗口 Toast.makeText(MainActivity.this, "请输入速度", Toast.LENGTH_SHORT).show(); return; } - String temp = et.getText().toString().trim(); + String temp = et1.getText().toString().trim(); double speed = Double.parseDouble(temp) / 3.6; AdasManager.getInstance().sendAutopilotSpeedReq(speed); + alertDialog1.dismiss(); } }); - //设置反面按钮,并做事件处理 - builder.setNegativeButton("取消", null); - builder.show();//显示Dialog对话框 - break; case Constants.TITLE.SEND_SYSTEM_CMD_REQ_REBOOT: //重启所有节点 @@ -1256,6 +1335,12 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas switch (msg.what) { case WHAT_IPC_IP: showIPCIP(); + if (specialVehicleBeanList != null && !specialVehicleBeanList.isEmpty()) { + for (SpecialVehicleBean bean : specialVehicleBeanList) { + bean.dismissFloat(); + } + specialVehicleBeanList = null; + } break; case WHAT_DRIVER_IP: ipcIp.setVisibility(View.VISIBLE); diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/VersionFragment.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/VersionFragment.java index a150e0619c..23e8c12b62 100644 --- a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/VersionFragment.java +++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/VersionFragment.java @@ -7,8 +7,13 @@ import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; import android.widget.Button; +import android.widget.CheckBox; +import android.widget.CompoundButton; import android.widget.EditText; +import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; @@ -21,12 +26,15 @@ import androidx.recyclerview.widget.SimpleItemAnimator; import com.zhidao.adas.client.BuildConfig; import com.zhidao.adas.client.R; import com.zhidao.adas.client.adapter.ConfigAdapter; +import com.zhidao.adas.client.adapter.InterfaceAdapter; import com.zhidao.adas.client.base.BaseFragment; import com.zhidao.adas.client.bean.Config; +import com.zhidao.adas.client.bean.InterfaceModel; import com.zhidao.support.adas.high.AdasManager; import com.zhidao.support.adas.high.bean.VersionCompatibility; import com.zhidao.support.adas.high.common.Constants; import com.zhidao.support.adas.high.common.CupidLogUtils; +import com.zhidao.support.adas.high.common.MessageType; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -34,6 +42,7 @@ import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Locale; +import java.util.Set; import mogo.telematics.pad.MessagePad; @@ -42,11 +51,26 @@ import mogo.telematics.pad.MessagePad; */ public class VersionFragment extends BaseFragment { private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS ", Locale.getDefault()); + private TextView ipsView; + private EditText ipView; + private RecyclerView recyclerView; + private RecyclerView rec_registered; + private RecyclerView rec_unregistered; + private CheckBox registered_check_all; + private CheckBox unregistered_check_all; + private TextView hint_registered; + private TextView hint_unregistered; + + private ConfigAdapter adapter; + private InterfaceAdapter unregisteredAdapter; + private InterfaceAdapter registeredAdapter; + + + private int role = Constants.TERMINAL_ROLE.DEBUG;//角色 默认调试屏 public VersionFragment() { } - private ConfigAdapter adapter; public VersionFragment(String title) { super(title); @@ -87,7 +111,7 @@ public class VersionFragment extends BaseFragment { for (String ip : ips) { i++; builder.append(ip); - if (i % 2 == 0) { + if (i % 4 == 0) { builder.append("\n"); } else { builder.append("\t\t\t\t"); @@ -98,9 +122,6 @@ public class VersionFragment extends BaseFragment { } - private TextView ipsView; - private EditText ipView; - private RecyclerView recyclerView; private void initView(View view) { TextView tvTitle = view.findViewById(R.id.tv_title); @@ -113,7 +134,7 @@ public class VersionFragment extends BaseFragment { CupidLogUtils.w("InfoFragment===>" + title); tvTitle.setText(title); tvTitle.setGravity(Gravity.CENTER); - + initRegistrationView(view); btn1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -154,6 +175,18 @@ public class VersionFragment extends BaseFragment { } + //根据连接状态更新数据 + @Override + public void onConnectionIPCStatus(int ipcConnectionStatus) { + super.onConnectionIPCStatus(ipcConnectionStatus); + if (ipcConnectionStatus == Constants.IPC_CONNECTION_STATUS.DISCONNECTED || ipcConnectionStatus == Constants.IPC_CONNECTION_STATUS.CONNECTED) { + showVersion(); + initRegistrationData(); + if (ipcConnectionStatus == Constants.IPC_CONNECTION_STATUS.DISCONNECTED) { + clearRegistrationViewState(); + } + } + } public void showVersion() { List list = new ArrayList<>(); @@ -204,4 +237,197 @@ public class VersionFragment extends BaseFragment { adapter = new ConfigAdapter(); recyclerView.setAdapter(adapter); } + + + private void initRegistrationView(View view) { + recyclerView = view.findViewById(R.id.config_list); + rec_registered = view.findViewById(R.id.rec_registered); + rec_unregistered = view.findViewById(R.id.rec_unregistered); + registered_check_all = view.findViewById(R.id.registered_check_all); + unregistered_check_all = view.findViewById(R.id.unregistered_check_all); + hint_unregistered = view.findViewById(R.id.hint_unregistered); + hint_registered = view.findViewById(R.id.hint_registered); + Button update = view.findViewById(R.id.update); + initFragmentRecyclerView(); + initRegisteredRecyclerView(); + initUnregisteredRecyclerView(); + initSpinner(view); + registered_check_all.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (buttonView.isPressed()) { + registeredAdapter.setCheckAll(isChecked); + unregisteredAdapter.setCheckAll(false); + unregisteredAdapter.setEnabled(!isChecked); + unregistered_check_all.setEnabled(!isChecked); + } + } + }); + registeredAdapter.setListener(new InterfaceAdapter.OnInterfaceAdapterListener() { + @Override + public void onCheckAll(boolean isCheckAll) { + registered_check_all.setChecked(isCheckAll); + } + + @Override + public void onCheckNum(int checkNum) { + boolean isEnable = checkNum == 0; + unregisteredAdapter.setEnabled(isEnable); + unregistered_check_all.setEnabled(isEnable); + } + }); + unregistered_check_all.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (buttonView.isPressed()) { + unregisteredAdapter.setCheckAll(isChecked); + registeredAdapter.setCheckAll(false); + registeredAdapter.setEnabled(!isChecked); + registered_check_all.setEnabled(!isChecked); + } + } + }); + unregisteredAdapter.setListener(new InterfaceAdapter.OnInterfaceAdapterListener() { + @Override + public void onCheckAll(boolean isCheckAll) { + unregistered_check_all.setChecked(isCheckAll); + } + + @Override + public void onCheckNum(int checkNum) { + boolean isEnable = checkNum == 0; + registeredAdapter.setEnabled(isEnable); + registered_check_all.setEnabled(isEnable); + } + }); + update.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + update(); + } + }); + initRegistrationData(); + } + + + private void update() { + if (registeredAdapter.getCheckNum() == 0 && unregisteredAdapter.getCheckNum() == 0) { + Toast.makeText(getContext(), "请选择后在更新", Toast.LENGTH_SHORT).show(); + return; + } + Set set; + if (registeredAdapter.getCheckNum() == 0) { + //注册 + set = unregisteredAdapter.getCheckedModel(); + if (set == null || set.isEmpty()) { + Toast.makeText(getContext(), "请选择要注册的接口", Toast.LENGTH_SHORT).show(); + return; + } + if (set.size() == 1) { + AdasManager.getInstance().subscribeInterface(role, Constants.SUBSCRIBE_TYPE.SUBSCRIBE, set.iterator().next()); + } else { + AdasManager.getInstance().subscribeInterface(role, Constants.SUBSCRIBE_TYPE.SUBSCRIBE, set); + } + } else { + //取消注册 + set = registeredAdapter.getCheckedModel(); + if (set == null || set.isEmpty()) { + Toast.makeText(getContext(), "请选择要取消注册的接口", Toast.LENGTH_SHORT).show(); + return; + } + if (set.size() == 1) { + AdasManager.getInstance().subscribeInterface(role, Constants.SUBSCRIBE_TYPE.UNSUBSCRIBE, set.iterator().next()); + } else { + AdasManager.getInstance().subscribeInterface(role, Constants.SUBSCRIBE_TYPE.UNSUBSCRIBE, set); + } + } + clearRegistrationViewState(); + initRegistrationData(); + + } + + private void clearRegistrationViewState() { + registered_check_all.setChecked(false); + unregistered_check_all.setChecked(false); + registered_check_all.setEnabled(true); + unregistered_check_all.setEnabled(true); + if (registeredAdapter != null) + registeredAdapter.notifyDataSetChanged(); + if (unregisteredAdapter != null) + unregisteredAdapter.notifyDataSetChanged(); + } + + private void initRegistrationData() { + //初始化数据 + Set set = AdasManager.getInstance().getSubscribedInterface(); + List registeredList = new ArrayList<>(); + List unregisteredList = new ArrayList<>(); + if (set != null && !set.isEmpty()) { + registered_check_all.setVisibility(View.VISIBLE); + for (MessageType messageType : set) { + registeredList.add(new InterfaceModel(messageType)); + } + } else { + registered_check_all.setVisibility(View.INVISIBLE); + } + set = AdasManager.getInstance().getUnsubscribedInterface(); + if (set != null && !set.isEmpty()) { + unregistered_check_all.setVisibility(View.VISIBLE); + for (MessageType messageType : set) { + unregisteredList.add(new InterfaceModel(messageType)); + } + } else { + unregistered_check_all.setVisibility(View.INVISIBLE); + } + registeredAdapter.setData(registeredList, 0); + unregisteredAdapter.setData(unregisteredList, 0); + hint_registered.setText("已注册接口(" + registeredAdapter.getItemCount() + ")"); + hint_unregistered.setText("未注册接口(" + unregisteredAdapter.getItemCount() + ")"); + } + + + private void initRegisteredRecyclerView() { + //创建默认的线性LayoutManager 横向的GridLayoutManager + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext()); + linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); + rec_registered.setLayoutManager(linearLayoutManager); + //如果可以确定每个item的高度是固定的,设置这个选项可以提高性能 + rec_registered.setHasFixedSize(false); + rec_registered.setNestedScrollingEnabled(false); + registeredAdapter = new InterfaceAdapter(); + rec_registered.setAdapter(registeredAdapter); + } + + private void initUnregisteredRecyclerView() { + //创建默认的线性LayoutManager 横向的GridLayoutManager + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext()); + linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); + rec_unregistered.setLayoutManager(linearLayoutManager); + //如果可以确定每个item的高度是固定的,设置这个选项可以提高性能 + rec_unregistered.setHasFixedSize(false); + rec_unregistered.setNestedScrollingEnabled(false); + unregisteredAdapter = new InterfaceAdapter(); + rec_unregistered.setAdapter(unregisteredAdapter); + } + + + private void initSpinner(View view) { + String[] s = {"司机", "乘客", "调试"}; + ArrayAdapter dataAdapter = new ArrayAdapter(getContext(), android.R.layout.simple_spinner_item, s); + dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + Spinner sp = view.findViewById(R.id.spinner); + sp.setAdapter(dataAdapter); + sp.setSelection(2); + sp.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + role = position; + } + + @Override + public void onNothingSelected(AdapterView parent) { + + } + }); + } } diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/special/SpecialVehicleDialog.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/special/SpecialVehicleDialog.java new file mode 100644 index 0000000000..0903180db1 --- /dev/null +++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/special/SpecialVehicleDialog.java @@ -0,0 +1,116 @@ +package com.zhidao.adas.client.ui.special; + +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.SimpleItemAnimator; + +import com.zhidao.adas.client.App; +import com.zhidao.adas.client.R; +import com.zhidao.adas.client.adapter.SpecialVehicleAdapter; +import com.zhidao.adas.client.base.BaseAdapter; +import com.zhidao.adas.client.bean.SpecialVehicleBean; +import com.zhidao.adas.client.ui.AutopilotConfigActivity; + +import java.util.List; + + +/** + * 特种车辆 + */ +public class SpecialVehicleDialog extends Dialog { + private RecyclerView recyclerView; + private List list; + + + public SpecialVehicleDialog(@NonNull Context context, List list) { + super(context, R.style.CustomDialog); + this.list = list; + } + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.dialog_autopilot_mode); + //初始化界面控件 + initView(); + //初始化界面控件的事件 + initListener(); + initBtnRecyclerView(); + setOnDismissListener(new OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + } + }); + + } + + @Override + public void show() { + super.show(); + } + + + private void initBtnRecyclerView() { + //初始info-recycle + LinearLayoutManager nodLinearLayoutManage = new LinearLayoutManager(getContext()); + nodLinearLayoutManage.setOrientation(LinearLayoutManager.VERTICAL); + recyclerView.setLayoutManager(nodLinearLayoutManage); + //如果可以确定每个item的高度是固定的,设置这个选项可以提高性能 + recyclerView.setHasFixedSize(true); + //解决局部刷新闪屏问题 + SimpleItemAnimator animatorInfo = (SimpleItemAnimator) recyclerView.getItemAnimator(); + if (animatorInfo != null) + animatorInfo.setSupportsChangeAnimations(false); + //创建并设置Adapter + SpecialVehicleAdapter adapter = new SpecialVehicleAdapter(list); + recyclerView.setAdapter(adapter); + adapter.setOnItemClickListener(new BaseAdapter.OnItemClickListener() { + @Override + public void onItemClick(int position, SpecialVehicleBean data) { + if (data.options == null) { + Toast.makeText(getContext(), "“" + data.name + "”暂未支持", Toast.LENGTH_SHORT).show(); + } else { + data.showFloat(App.INSTANCE); + SpecialVehicleDialog.this.dismiss(); + } + + } + }); + } + + /** + * 初始化界面的确定和取消监听器 + */ + private void initListener() { + findViewById(R.id.settings).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getContext().startActivity(new Intent(getContext(), AutopilotConfigActivity.class)); + } + }); + } + + + /** + * 初始化界面控件 + */ + private void initView() { + recyclerView = findViewById(R.id.recyclerView); + findViewById(R.id.settings).setVisibility(View.GONE); + TextView textView = findViewById(R.id.title); + textView.setText("特种车辆"); + } + + +} \ No newline at end of file diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/special/SpecialVehicleFloatWindow.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/special/SpecialVehicleFloatWindow.java new file mode 100644 index 0000000000..c60756c777 --- /dev/null +++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/special/SpecialVehicleFloatWindow.java @@ -0,0 +1,477 @@ +package com.zhidao.adas.client.ui.special; + +import android.content.Context; +import android.graphics.Color; +import android.os.Handler; +import android.os.Message; +import android.util.DisplayMetrics; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.FrameLayout; +import android.widget.HorizontalScrollView; +import android.widget.LinearLayout; +import android.widget.RadioButton; +import android.widget.RadioGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.AppCompatButton; + +import com.zhidao.adas.client.R; +import com.zhidao.adas.client.bean.SpecialVehicleBean; +import com.zhidao.adas.client.bean.SpecialVehicleOption; + +import java.lang.ref.WeakReference; +import java.lang.reflect.Field; + + +/** + * 2017/1/10. + * Description:全局悬浮窗口 + */ + +public class SpecialVehicleFloatWindow extends LinearLayout { + + /*********************悬浮窗相关***********************/ + + private int sW; + private int sH; + private boolean isMaximize = true;//是否是最大化 + private WindowManager wm; + //此wmParams变量为获取的全局变量,用以保存悬浮窗口的属性 + private WindowManager.LayoutParams wmParams; + private int btnMaximizeW; + private int btnMaximizeH; + + /*********************CAN数据配置相关***********************/ + private final static int WHAT_UPDATE_DATA = 1; + private BaseHandler mBaseHandler; + private LinearLayout layout_btn; + private HorizontalScrollView btn_list; + private AppCompatButton btn_send; + private RadioGroup rg_send_type; + private TextView text; + private TextView title; + private TextView btn_maximize; + private View can_parent; + + private OnFloatWindowListener listener; + private final SpecialVehicleBean specialVehicleBean; + + public interface OnFloatWindowListener { + void onBack(); + + void onMinimality(); + + void onMaximize(); + } + + public boolean isMaximize() { + return isMaximize; + } + + public void setOnFloatWindowListener(OnFloatWindowListener listener) { + this.listener = listener; + } + + public void setWmParams(WindowManager.LayoutParams wmParams) { + this.wmParams = wmParams; + } + + public SpecialVehicleFloatWindow(@NonNull Context context, @NonNull SpecialVehicleBean specialVehicleBean) { + super(context, null, 0); + this.specialVehicleBean = specialVehicleBean; + wm = (WindowManager) context.getApplicationContext().getSystemService(Context.WINDOW_SERVICE); + //加载布局 + LayoutInflater.from(context).inflate(R.layout.dialog_special_vehicle_config, this, true); + initParameter(); + initCanView(); + } + + private void initParameter() { + DisplayMetrics metrics2 = getResources().getDisplayMetrics(); + sW = metrics2.widthPixels; + sH = metrics2.heightPixels; + } + + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if (event.getAction() == KeyEvent.ACTION_UP) { + if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { + if (isMaximize) { + minimality(); + return true; + } + } + } + return super.dispatchKeyEvent(event); + } + + private float mInViewX; + private float mInViewY; + private float mDownInScreenX; + private float mDownInScreenY; + private float mInScreenX; + private float mInScreenY; + + @Override + public boolean onTouchEvent(MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + // 获取相对View的坐标,即以此View左上角为原点 + mInViewX = event.getX(); + mInViewY = event.getY(); + // 获取相对屏幕的坐标,即以屏幕左上角为原点 + mDownInScreenX = event.getRawX(); + mDownInScreenY = event.getRawY() - getSysBarHeight(getContext()); + mInScreenX = event.getRawX(); + mInScreenY = event.getRawY() - getSysBarHeight(getContext()); + + if (!isMaximize) { + btn_maximize.setPressed(true); + btnMaximizeW = btn_maximize.getWidth(); + btnMaximizeH = btn_maximize.getHeight(); + } + break; + case MotionEvent.ACTION_MOVE: + // 更新浮动窗口位置参数 + mInScreenX = event.getRawX(); + mInScreenY = event.getRawY() - getSysBarHeight(getContext()); + wmParams.x = (int) (mInScreenX - mInViewX); + wmParams.y = (int) (mInScreenY - mInViewY); + updateViewLayout(); + break; + + case MotionEvent.ACTION_UP: + // 如果手指离开屏幕时,xDownInScreen和xInScreen相等,且yDownInScreen和yInScreen相等,则视为触发了单击事件。 +// if (mDownInScreenX == mInScreenX && mDownInScreenY == mInScreenY) { + float temX = Math.abs(mDownInScreenX - mInScreenX); + float temY = Math.abs(mDownInScreenY - mInScreenY); + if (temX + temY < 10) { + maximize(); + } else { + if (isMaximize) { + specialVehicleBean.setFloatWindowLocationMaxX(getContext(), wmParams.x); + specialVehicleBean.setFloatWindowLocationMaxY(getContext(), wmParams.y); + } else { + btn_maximize.setPressed(false); + // 抬起手指时让floatView屏幕左右边缘 距离20个像素 +// wmParams.x = wmParams.x <= (sW / 2) ? AmiConstants.SCREEN_MARGIN : sW - btnMaximizeW - AmiConstants.SCREEN_MARGIN; + int tem = wmParams.x; + if (tem < SpecialVehicleBean.SCREEN_MARGIN) + tem = SpecialVehicleBean.SCREEN_MARGIN; + else if (sW - (tem + btnMaximizeW) < SpecialVehicleBean.SCREEN_MARGIN) { + tem = sW - btnMaximizeW - SpecialVehicleBean.SCREEN_MARGIN; + } + wmParams.x = tem; + tem = wmParams.y; + if (tem < SpecialVehicleBean.SCREEN_MARGIN) + tem = SpecialVehicleBean.SCREEN_MARGIN; + else if (sH - (tem + btnMaximizeH) < SpecialVehicleBean.SCREEN_MARGIN) { + tem = sH - btnMaximizeH - SpecialVehicleBean.SCREEN_MARGIN; + } + wmParams.y = tem; + updateViewLayout(); + specialVehicleBean.setFloatWindowLocationMinX(getContext(), wmParams.x); + specialVehicleBean.setFloatWindowLocationMinY(getContext(), wmParams.y); + } + } + + break; + } + return true; + } + + public void updateViewLayout() { + wm.updateViewLayout(this, wmParams); + } + + // 获取系统状态栏高度 + private int sbar = -1; + + public int getSysBarHeight(Context contex) { + if (sbar == -1) { + Class c; + Object obj; + Field field; + int x; + try { + c = Class.forName("com.android.internal.R$dimen"); + obj = c.newInstance(); + field = c.getField("status_bar_height"); + x = Integer.parseInt(field.get(obj).toString()); + sbar = contex.getResources().getDimensionPixelSize(x); + } catch (Exception e1) { + e1.printStackTrace(); + } + } + return sbar; + } + + /*****************************业务逻辑*******************************************/ + + + private void initCanView() { + initHandler(); + can_parent = findViewById(R.id.can_parent); + btn_list = findViewById(R.id.btn_list); + btn_send = findViewById(R.id.btn_send); + rg_send_type = findViewById(R.id.rg_send_type); + text = findViewById(R.id.text); + title = findViewById(R.id.title); + title.setText(specialVehicleBean.name); + btn_maximize = findViewById(R.id.btn_maximize); + btn_maximize.setText(specialVehicleBean.simpleName); + initListener(); + initBtnRecyclerView(); + initSendTypeView(); + } + + private void initSendTypeView() { + int resId; + switch (specialVehicleBean.sendType) { + default: + case SpecialVehicleBean.SEND_TYPE.ONE: + resId = R.id.btn_one; + break; + case SpecialVehicleBean.SEND_TYPE.MORE: + resId = R.id.btn_more; + break; + case SpecialVehicleBean.SEND_TYPE.ALL: + resId = R.id.btn_all; + break; + } + rg_send_type.check(resId); + btn_send.setVisibility(specialVehicleBean.sendType == SpecialVehicleBean.SEND_TYPE.ONE ? View.GONE : View.VISIBLE); + rg_send_type.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(RadioGroup group, int checkedId) { + View checkView = group.findViewById(checkedId); + if (!checkView.isPressed()) { + return; + } + int type = SpecialVehicleBean.SEND_TYPE.ONE; + if (checkedId == R.id.btn_more) { + type = SpecialVehicleBean.SEND_TYPE.MORE; + } else { + if (specialVehicleBean.sendType == SpecialVehicleBean.SEND_TYPE.MORE) { + for (int i = 0; i < layout_btn.getChildCount(); i++) { + LinearLayout view = (LinearLayout) layout_btn.getChildAt(i); + RadioGroup radioGroup = view.findViewById(R.id.item_group); + SpecialVehicleOption option = specialVehicleBean.options.get(i); + if (option.moreCheckPos != -1) { + option.moreCheckPos = -1; + radioGroup.check(option.checkPos); + } + } + } + if (checkedId == R.id.btn_one) { + type = SpecialVehicleBean.SEND_TYPE.ONE; + } else if (checkedId == R.id.btn_all) { + type = SpecialVehicleBean.SEND_TYPE.ALL; + } + } + specialVehicleBean.sendType = type; + btn_send.setVisibility(type == SpecialVehicleBean.SEND_TYPE.ONE ? View.GONE : View.VISIBLE); + } + }); + btn_send.setOnClickListener(onClickListener); + } + + + private void initListener() { + findViewById(R.id.btn_back).setOnClickListener(onClickListener); + findViewById(R.id.btn_minimality).setOnClickListener(onClickListener); + } + + public void minimality() { + isMaximize = false; + btn_maximize.setVisibility(VISIBLE); + can_parent.setVisibility(GONE); + if (listener != null) { + listener.onMinimality(); + } + + } + + public void maximize() { + isMaximize = true; + if (listener != null) { + listener.onMaximize(); + } + btn_maximize.setVisibility(GONE); + can_parent.setVisibility(VISIBLE); + + } + + private final OnClickListener onClickListener = new OnClickListener() { + @Override + public void onClick(View v) { + int id = v.getId(); + if (id == R.id.btn_back) { + if (listener != null) { + listener.onBack(); + } + } else if (id == R.id.btn_minimality) { + minimality(); + } else if (id == R.id.btn_send) { + String cmd = specialVehicleBean.sendCmd(-1); + updateText(0, cmd); + } + } + }; + + + private void initBtnRecyclerView() { + + layout_btn = new LinearLayout(getContext()); + btn_list.addView(layout_btn); + layout_btn.setOrientation(LinearLayout.HORIZONTAL); + FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) layout_btn.getLayoutParams(); + lp.gravity = Gravity.CENTER_VERTICAL; + for (int i = 0; i < specialVehicleBean.options.size(); i++) { + SpecialVehicleOption bean = specialVehicleBean.options.get(i); + View view = LayoutInflater.from(getContext()).inflate(R.layout.item_special_vehicle, layout_btn, false); + TextView name = view.findViewById(R.id.name); + RadioGroup radioGroup = view.findViewById(R.id.item_group); + + name.setText(bean.name); + String[] value = bean.value; + for (int j = 0; j < value.length; j++) { + RadioButton button = LayoutInflater.from(getContext()).inflate(R.layout.item_special_vehicle_option_radio_btn, radioGroup, false) + .findViewById(R.id.r_btn); + button.setText(value[j]); + button.setId(j); + if (i == 1 || i == 2 || i == 3 || i == 4) { + ViewGroup.LayoutParams layoutParams = button.getLayoutParams(); + layoutParams.width = 202; + } + radioGroup.addView(button); + } + radioGroup.setTag(bean.tag); + radioGroup.setOnCheckedChangeListener(onCheckedChangeListener); + radioGroup.check(bean.checkPos); + layout_btn.addView(view); + } + } + + private final RadioGroup.OnCheckedChangeListener onCheckedChangeListener = new RadioGroup.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(RadioGroup group, int checkedId) { + View checkView = group.findViewById(checkedId); + if (checkView == null || !checkView.isPressed()) { + return; + } + int tag = (int) group.getTag(); + SpecialVehicleOption bean = specialVehicleBean.options.get(tag); + if (specialVehicleBean.sendType != SpecialVehicleBean.SEND_TYPE.MORE) { + bean.checkPos = checkedId; + String cmd = specialVehicleBean.sendCmd(tag); + updateText(0, cmd); + } else { + bean.moreCheckPos = checkedId; + } + } + }; + + + /** + * 更新文本 + * + * @param tag 0--发送 1--接收 + * @param data 数据 + */ + private void updateText(int tag, String data) { + Message msg = Message.obtain(); + msg.what = WHAT_UPDATE_DATA; + msg.obj = data; + msg.arg1 = tag; + getHandler().sendMessage(msg); + } + + + /** + * 初始化一个Handler,如果需要使用Handler,先调用此方法, + * 然后可以使用postRunnable(Runnable runnable), + * sendMessage在handleMessage(Message msg)中接收msg + */ + public void initHandler() { + mBaseHandler = new BaseHandler(this); + } + + /** + * 返回Handler,在此之前确定已经调用initHandler() + * + * @return Handler + */ + public Handler getHandler() { + return mBaseHandler; + } + + /** + * 同Handler的postRunnable + * 在此之前确定已经调用initHandler() + */ + protected void postRunnable(Runnable runnable) { + postRunnableDelayed(runnable, 0); + } + + /** + * 同Handler的postRunnableDelayed + * 在此之前确定已经调用initHandler() + */ + protected void postRunnableDelayed(Runnable runnable, long delayMillis) { + if (mBaseHandler == null) initHandler(); + mBaseHandler.postDelayed(runnable, delayMillis); + } + + + /** + * 同Handler 的 handleMessage, + * getHandler.sendMessage,发送的Message在此接收 + * 在此之前确定已经调用initHandler() + * + * @param msg + */ + protected void handleMessage(Message msg) { + switch (msg.what) { + case WHAT_UPDATE_DATA: + if (msg.arg1 == 0) { + text.setTextColor(Color.parseColor("#FFFFFF")); + } else { + text.setTextColor(Color.parseColor("#FF0000")); + } + String str = (String) msg.obj; + if (str.length() < 100) { + text.setTextSize(14); + } else { + text.setTextSize(10); + } + text.setText(str); + break; + } + + } + + + protected static class BaseHandler extends Handler { + private final WeakReference mObjects; + + public BaseHandler(SpecialVehicleFloatWindow mPresenter) { + mObjects = new WeakReference(mPresenter); + } + + @Override + public void handleMessage(Message msg) { + SpecialVehicleFloatWindow mPresenter = mObjects.get(); + if (mPresenter != null) + mPresenter.handleMessage(msg); + } + } +} diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/special/SpecialVehicleFloatWindowManager.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/special/SpecialVehicleFloatWindowManager.java new file mode 100644 index 0000000000..45068dee3d --- /dev/null +++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/special/SpecialVehicleFloatWindowManager.java @@ -0,0 +1,94 @@ +package com.zhidao.adas.client.ui.special; + +import android.content.Context; +import android.graphics.PixelFormat; +import android.view.Gravity; +import android.view.WindowManager; + +import com.zhidao.adas.client.bean.SpecialVehicleBean; + + +public class SpecialVehicleFloatWindowManager implements SpecialVehicleFloatWindow.OnFloatWindowListener { + private final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(); + private SpecialVehicleFloatWindow floatWindow = null; + private WindowManager wm = null; + private final Context context; + private final SpecialVehicleBean specialVehicleBean; + + public SpecialVehicleFloatWindowManager(Context context, SpecialVehicleBean specialVehicleBean) { + this.context = context; + this.specialVehicleBean = specialVehicleBean; + } + + public void show() { + if (!createFloatWindow()) { + if (floatWindow.isMaximize()) { + floatWindow.minimality(); + } else { + floatWindow.maximize(); + } + } + } + + private boolean createFloatWindow() { + if (floatWindow == null) { + wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; + layoutParams.format = PixelFormat.RGBA_8888; + layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;//| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + layoutParams.gravity = Gravity.START | Gravity.TOP; + layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT; + layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT; + layoutParams.alpha = 0.9f; + floatWindow = new SpecialVehicleFloatWindow(context, specialVehicleBean); + floatWindow.setWmParams(layoutParams); + floatWindow.setOnFloatWindowListener(this); + layoutParams.x = specialVehicleBean.getFloatWindowLocationMaxX(context); + layoutParams.y = specialVehicleBean.getFloatWindowLocationMaxY(context); + wm.addView(floatWindow, layoutParams); + return true; + } + return false; + } + + private void removeFloatWindow() { + if (floatWindow != null) { + wm.removeView(floatWindow); + floatWindow = null; + wm = null; + } + } + + @Override + public void onBack() { + removeFloatWindow(); + } + + @Override + public void onMinimality() { + layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; + layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT; + layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT; + layoutParams.x = specialVehicleBean.getFloatWindowLocationMinX(context); + layoutParams.y = specialVehicleBean.getFloatWindowLocationMinY(context); + layoutParams.alpha = 1f; + if (floatWindow != null) { + floatWindow.updateViewLayout(); + } + } + + @Override + public void onMaximize() { + layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; + layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT; + layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT; + layoutParams.x = specialVehicleBean.getFloatWindowLocationMaxX(context); + layoutParams.y = specialVehicleBean.getFloatWindowLocationMaxY(context); + layoutParams.alpha = 0.9f; + if (floatWindow != null) { + floatWindow.updateViewLayout(); + } + } + + +} diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/utils/Constants.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/utils/Constants.java index 3bead1cd1c..df45365bf0 100644 --- a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/utils/Constants.java +++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/utils/Constants.java @@ -10,10 +10,8 @@ import com.zhidao.support.adas.high.common.JsonUtil; import com.zhidao.support.adas.high.common.MessageType; import java.io.File; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; -import java.util.Locale; /** * @author song kenan @@ -157,12 +155,12 @@ public class Constants { String RECEIVE_REPORT_MESSAGE = MessageType.TYPE_RECEIVE_REPORT_MESSAGE.desc; String RECEIVE_PERCEPTION_TRAFFIC_LIGHT = MessageType.TYPE_RECEIVE_PERCEPTION_TRAFFIC_LIGHT.desc; String RECEIVE_PREDICTION_OBSTACLE_TRAJECTORY = MessageType.TYPE_RECEIVE_PREDICTION_OBSTACLE_TRAJECTORY.desc; - String RECEIVE_POINT_CLOUD = MessageType.TYPE_RECEIVE_POINT_CLOUD.desc; - String RECEIVE_POINT_CLOUD_ORIGINAL = "点云原始透传"; + String RECEIVE_POINT_CLOUD_ORIGINAL = MessageType.TYPE_RECEIVE_POINT_CLOUD.desc; String RECEIVE_PLANNING_OBJECTS = MessageType.TYPE_RECEIVE_PLANNING_OBJECTS.desc; + String RECEIVE_PLANNING_DECISION_STATE = MessageType.TYPE_RECEIVE_PLANNING_DECISION_STATE.desc; // String RECEIVE_BASIC_INFO_REQ = "自动驾驶设备基础信息请求"; - String TITLE_CAR_CONFIG_RESP = "工控机版本\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t固定IP配置"; + String TITLE_CAR_CONFIG_RESP = "工控机版本\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t配置"; String RECEIVE_CAR_CONFIG_RESP = "信息与配置"; String RECEIVE_RECORD_RESULT = MessageType.TYPE_RECEIVE_RECORD_RESULT.desc; String RECEIVE_RECORD_DATA_CONFIG_RESP = MessageType.TYPE_RECEIVE_RECORD_DATA_CONFIG_RESP.desc; @@ -175,6 +173,7 @@ public class Constants { String SEND_SET_AUTOPILOT_MODE_REQ = "自动驾驶模式"; String SEND_GLOBAL_PATH_REQ = "自动驾驶路径查询"; + String SEND_SPECIAL_VEHICLE_TASK_CMD = "特种车辆"; String SEND_STATUS_QUERY_REQ = "状态查询"; String SEND_BASIC_INFO_RESP = "下发SN"; String SEND_RECORD_DATA_5 = "数据采集5秒"; diff --git a/app_ipc_monitoring/src/main/res/drawable/item_text_color.xml b/app_ipc_monitoring/src/main/res/color/item_text_color.xml similarity index 100% rename from app_ipc_monitoring/src/main/res/drawable/item_text_color.xml rename to app_ipc_monitoring/src/main/res/color/item_text_color.xml diff --git a/app_ipc_monitoring/src/main/res/color/item_text_color1.xml b/app_ipc_monitoring/src/main/res/color/item_text_color1.xml new file mode 100644 index 0000000000..0f67bce160 --- /dev/null +++ b/app_ipc_monitoring/src/main/res/color/item_text_color1.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/app_ipc_monitoring/src/main/res/drawable/bg_radio_button.xml b/app_ipc_monitoring/src/main/res/drawable/bg_radio_button.xml new file mode 100644 index 0000000000..51b99e6dfb --- /dev/null +++ b/app_ipc_monitoring/src/main/res/drawable/bg_radio_button.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app_ipc_monitoring/src/main/res/drawable/bg_special_vehicle_float.xml b/app_ipc_monitoring/src/main/res/drawable/bg_special_vehicle_float.xml new file mode 100644 index 0000000000..f234ac57f3 --- /dev/null +++ b/app_ipc_monitoring/src/main/res/drawable/bg_special_vehicle_float.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app_ipc_monitoring/src/main/res/drawable/btn_maximize_text_color.xml b/app_ipc_monitoring/src/main/res/drawable/btn_maximize_text_color.xml new file mode 100644 index 0000000000..f7b06336e2 --- /dev/null +++ b/app_ipc_monitoring/src/main/res/drawable/btn_maximize_text_color.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app_ipc_monitoring/src/main/res/drawable/btn_special_vehicle_small_bg.xml b/app_ipc_monitoring/src/main/res/drawable/btn_special_vehicle_small_bg.xml new file mode 100644 index 0000000000..35ec4217b8 --- /dev/null +++ b/app_ipc_monitoring/src/main/res/drawable/btn_special_vehicle_small_bg.xml @@ -0,0 +1,13 @@ + + + + + + + diff --git a/app_ipc_monitoring/src/main/res/drawable/ic_special_vehicle_back.xml b/app_ipc_monitoring/src/main/res/drawable/ic_special_vehicle_back.xml new file mode 100644 index 0000000000..907343605c --- /dev/null +++ b/app_ipc_monitoring/src/main/res/drawable/ic_special_vehicle_back.xml @@ -0,0 +1,9 @@ + + + diff --git a/app_ipc_monitoring/src/main/res/drawable/ic_special_vehicle_back_true.xml b/app_ipc_monitoring/src/main/res/drawable/ic_special_vehicle_back_true.xml new file mode 100644 index 0000000000..6e5e50af88 --- /dev/null +++ b/app_ipc_monitoring/src/main/res/drawable/ic_special_vehicle_back_true.xml @@ -0,0 +1,9 @@ + + + diff --git a/app_ipc_monitoring/src/main/res/drawable/ic_special_vehicle_minimality.xml b/app_ipc_monitoring/src/main/res/drawable/ic_special_vehicle_minimality.xml new file mode 100644 index 0000000000..bbe2de802f --- /dev/null +++ b/app_ipc_monitoring/src/main/res/drawable/ic_special_vehicle_minimality.xml @@ -0,0 +1,9 @@ + + + diff --git a/app_ipc_monitoring/src/main/res/drawable/ic_special_vehicle_minimality_true.xml b/app_ipc_monitoring/src/main/res/drawable/ic_special_vehicle_minimality_true.xml new file mode 100644 index 0000000000..5c35a310b5 --- /dev/null +++ b/app_ipc_monitoring/src/main/res/drawable/ic_special_vehicle_minimality_true.xml @@ -0,0 +1,9 @@ + + + diff --git a/app_ipc_monitoring/src/main/res/drawable/radio_btn_bg.xml b/app_ipc_monitoring/src/main/res/drawable/radio_btn_bg.xml new file mode 100644 index 0000000000..31c702bcc5 --- /dev/null +++ b/app_ipc_monitoring/src/main/res/drawable/radio_btn_bg.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app_ipc_monitoring/src/main/res/drawable/selector_special_vehicle_back.xml b/app_ipc_monitoring/src/main/res/drawable/selector_special_vehicle_back.xml new file mode 100644 index 0000000000..6adf0a241c --- /dev/null +++ b/app_ipc_monitoring/src/main/res/drawable/selector_special_vehicle_back.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app_ipc_monitoring/src/main/res/drawable/selector_special_vehicle_minimality.xml b/app_ipc_monitoring/src/main/res/drawable/selector_special_vehicle_minimality.xml new file mode 100644 index 0000000000..f313d33d5a --- /dev/null +++ b/app_ipc_monitoring/src/main/res/drawable/selector_special_vehicle_minimality.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app_ipc_monitoring/src/main/res/layout/dialog_sn.xml b/app_ipc_monitoring/src/main/res/layout/dialog_sn.xml new file mode 100644 index 0000000000..dc2fc2ee34 --- /dev/null +++ b/app_ipc_monitoring/src/main/res/layout/dialog_sn.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app_ipc_monitoring/src/main/res/layout/dialog_special_vehicle_config.xml b/app_ipc_monitoring/src/main/res/layout/dialog_special_vehicle_config.xml new file mode 100644 index 0000000000..cf31149b2c --- /dev/null +++ b/app_ipc_monitoring/src/main/res/layout/dialog_special_vehicle_config.xml @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app_ipc_monitoring/src/main/res/layout/fragment_version.xml b/app_ipc_monitoring/src/main/res/layout/fragment_version.xml index b26df8515a..0b6016f93b 100644 --- a/app_ipc_monitoring/src/main/res/layout/fragment_version.xml +++ b/app_ipc_monitoring/src/main/res/layout/fragment_version.xml @@ -52,7 +52,16 @@ android:layout_height="match_parent" android:layout_weight="1" android:orientation="vertical" - android:padding="10dp"> + android:paddingStart="10dp"> + + + app:layout_constraintTop_toBottomOf="@id/ip_hint" />