[add]工控机测试程序加入抓取LOG功能

This commit is contained in:
xinfengkun
2022-04-01 15:38:43 +08:00
parent bbcd3b0172
commit 4eee196284
10 changed files with 520 additions and 186 deletions

View File

@@ -5,7 +5,7 @@ android {
defaultConfig {
applicationId "com.zhidao.adas.client"
minSdkVersion 21
targetSdkVersion 31
targetSdkVersion 25
multiDexEnabled true
versionCode 1
versionName "1.0"

View File

@@ -27,6 +27,7 @@ public class InfoTitleAdapter extends BaseAdapter<String, InfoTitleAdapter.ViewH
selectedPosition = position;
}
}
public InfoTitleAdapter(List<String> data, boolean isFragment) {
super(data);
this.isFragment = isFragment;
@@ -37,7 +38,7 @@ public class InfoTitleAdapter extends BaseAdapter<String, InfoTitleAdapter.ViewH
if (data == null) {
return;
}
if (isFragment){
if (isFragment) {
viewHolder.itemView.setSelected(selectedPosition == position);
}
viewHolder.title.setText(data);
@@ -46,7 +47,24 @@ public class InfoTitleAdapter extends BaseAdapter<String, InfoTitleAdapter.ViewH
@Override
protected View getItemViewResource(ViewGroup viewGroup) {
return LayoutInflater.from(mContext).inflate(R.layout.item_info, viewGroup, false);
View view;
if (isFragment) {
view = LayoutInflater.from(mContext).inflate(R.layout.item_info, viewGroup, false);
} else {
view = LayoutInflater.from(mContext).inflate(R.layout.item_info1, viewGroup, false);
}
// if (!isFragment) {
// int h = viewGroup.getHeight() - DensityUtil.dip2px(mContext, 16);
// ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
// if (layoutParams != null) {
// layoutParams.width = DensityUtil.dip2px(mContext, 150);
//// layoutParams.height = DensityUtil.dip2px(mContext, 50);
// layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
//// layoutParams.height = h / 2;
// }
// }
return view;
}
@Override

View File

@@ -49,11 +49,11 @@ public class LineAdapter extends BaseAdapter<AutoPilotMode, LineAdapter.ViewHold
public ViewHolder(View itemView, LineAdapter adapter) {
super(itemView, adapter);
ViewGroup.LayoutParams layoutParams = itemView.getLayoutParams();
if (layoutParams != null) {
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
}
// ViewGroup.LayoutParams layoutParams = itemView.getLayoutParams();
// if (layoutParams != null) {
// layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
//
// }
title = itemView.findViewById(R.id.tv_info_title);
}
}

View File

@@ -0,0 +1,51 @@
package com.zhidao.adas.client.log;
import android.graphics.Color;
import android.text.TextUtils;
//保存的log
public class LogModel {
public interface ACTION {
String SEND = "发送";
String RECEIVE = "接收";
String PARSE = "解析";
}
public long id;
public int op_code;//发送Mask 接收:数据帧类型
public String action;//log标签
public String data;//log数据
public String time;
public LogModel() {
}
public LogModel(String action, int op_code, String data) {
this.action = action;
this.op_code = op_code;
this.data = data;
}
public int getColor() {
if (TextUtils.isEmpty(action)) {
return Color.parseColor("#871f78");
}
switch (action) {
case ACTION.SEND:
// return 0xFA8072;
return Color.parseColor("#FA8072");
case ACTION.RECEIVE:
// return 0xDCDCDC;
return Color.parseColor("#FF00FF");
case ACTION.PARSE:
// return 0xDCDCDC;
return Color.parseColor("#228B22");
default:
// return 0xFFFFFF;
return Color.parseColor("#871f78");
}
}
}

View File

@@ -0,0 +1,167 @@
package com.zhidao.adas.client.log;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import com.zhidao.support.adas.high.common.CupidLogUtils;
import com.zhidao.support.adas.high.common.ThreadPoolManager;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.RandomAccessFile;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
/**
* 与服务器交互日志管理任务
*/
public class LogSave {
private static final String TAG = LogSave.class.getSimpleName();
private static final String ROOT_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "IPCMonitoring" + File.separator;//程序外部存储跟目录
private static final String LOG_FILE_NAME = "data%s.log";//文件名称
private volatile static LogSave INSTANCE;
private static final long MAX_CAPACITY = 2 * 1024 * 1024L;//单文件最大存储容量 kb
private final LinkedBlockingQueue<String> queue;
private BufferedWriter buff = null;
private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.getDefault());
private final SimpleDateFormat FILE_SDF = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss-SSS", Locale.getDefault());
private File file;
private boolean isLogSwitch = false;
private long capacity = MAX_CAPACITY;
private Future future;
private LogSave() {
queue = new LinkedBlockingQueue<>();
start();
}
public static LogSave getInstance() {
if (INSTANCE == null) {
synchronized (LogSave.class) {
if (INSTANCE == null) {
INSTANCE = new LogSave();
}
}
}
return INSTANCE;
}
public void setIsLogSwitch(boolean isLogSwitch) {
this.isLogSwitch = isLogSwitch;
}
public boolean isLogSwitch() {
return isLogSwitch;
}
public boolean isSdcardUse() {
boolean bl = false;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
bl = true;
}
return bl;
}
private void getFile() throws IOException {
if (isSdcardUse()) {
String time = FILE_SDF.format(new Date());
String childPath = time.split("_")[0] + File.separator;
file = new File(ROOT_PATH + childPath + String.format(LOG_FILE_NAME, time));
if (!file.exists()) {
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
file.createNewFile();
}
FileWriter fw = new FileWriter(file, true);
buff = new BufferedWriter(fw);
}
}
public void saveLog(String action, String data) {
if (isLogSwitch) {
long nowTime = System.currentTimeMillis();
String time = sdf.format(new Date(nowTime));
// L.i(TAG, "time=" + time);
data = data.replace("\n", "");
String builder = time + " [action]:" + action + " [data]:" + data;
queue.add(builder);
}
}
public void start() {
if (future == null) {
future = ThreadPoolManager.getsInstance().submit(new WriteThread());
}
}
public void stop() {
queue.clear();
if (future != null && !future.isCancelled()) {
future.cancel(true);
}
future = null;
closeBufferedWriter();
}
private void closeBufferedWriter() {
if (buff != null) {
try {
buff.flush();
buff.close();
} catch (IOException e) {
e.printStackTrace();
}
buff = null;
}
}
private class WriteThread implements Runnable {
@Override
public void run() {
synchronized (this) {
while (!Thread.currentThread().isInterrupted()) {
try {
long size = 0;
if (file != null) {
size = file.length();
}
if (size > capacity || file == null || !file.exists() || buff == null) {
closeBufferedWriter();
getFile();
}
String data = queue.take();
if (!TextUtils.isEmpty(data)) {
buff.write(data);
buff.newLine();
buff.flush();
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
Log.i(TAG, "退出线程");
}
}
}
}

View File

@@ -14,6 +14,7 @@ import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.RadioButton;
@@ -32,6 +33,9 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator;
import com.zhidao.adas.client.bean.Base;
import com.zhidao.adas.client.log.LogSave;
import com.zhidao.support.adas.high.common.Constants.IPC_CONNECTION_STATUS;
import com.google.gson.Gson;
import com.mogo.telematic.MogoProtocolMsg;
import com.mogo.telematic.NSDNettyManager;
@@ -82,6 +86,7 @@ import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadLocalRandom;
import chassis.VehicleStateOuterClass;
import io.netty.channel.Channel;
@@ -104,7 +109,8 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
private AppCompatButton disconnect;
private RadioButton fixation;
private RadioButton assign;
private Switch switchLog;
private CheckBox cb_print;
private CheckBox cb_save;
private RecyclerView infoBtn;
private RecyclerView infoFragment;
private TextView tvConnectState;
@@ -220,7 +226,8 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
disconnect = findViewById(R.id.disconnect);
fixation = findViewById(R.id.fixation);
assign = findViewById(R.id.assign);
switchLog = findViewById(R.id.switch_log);
cb_print = findViewById(R.id.cb_print);
cb_save = findViewById(R.id.cb_save);
title = findViewById(R.id.title);
infoBtn = findViewById(R.id.info_btn);
infoFragment = findViewById(R.id.info_fragment);
@@ -271,18 +278,22 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
manager = getSupportFragmentManager();
transaction = manager.beginTransaction();
switchLog.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
cb_print.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b) {
AdasManager.getInstance().setEnableLog(true);
switchLog.setText("日志:开");
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
AdasManager.getInstance().setEnableLog(isChecked);
}
});
cb_save.setChecked(LogSave.getInstance().isLogSwitch());
cb_save.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
LogSave.getInstance().start();
} else {
AdasManager.getInstance().setEnableLog(false);
switchLog.setText("日志:关");
LogSave.getInstance().stop();
}
LogSave.getInstance().setIsLogSwitch(isChecked);
}
});
connectionType.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@@ -291,7 +302,6 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
int type;
switch (checkedId) {
default:
case R.id.assign:
type = AdasOptions.IPC_CONNECTION_MODE.ASSIGN;
break;
@@ -537,29 +547,28 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
}
private void onUpdateConnectStateView() {
private String onUpdateConnectStateView() {
String status;
int color;
switch (connectStatus) {
case com.zhidao.support.adas.high.common.Constants.IPC_CONNECTION_STATUS.CONNECTED:
case IPC_CONNECTION_STATUS.CONNECTED:
status = "已连接";
color = R.color.connect_status_connected;
break;
default:
case com.zhidao.support.adas.high.common.Constants.IPC_CONNECTION_STATUS.DISCONNECTED:
case IPC_CONNECTION_STATUS.DISCONNECTED:
status = "未连接";
color = R.color.connect_status_disconnected;
break;
case com.zhidao.support.adas.high.common.Constants.IPC_CONNECTION_STATUS.CONNECTING:
case IPC_CONNECTION_STATUS.CONNECTING:
status = "连接中";
color = R.color.connect_status_connecting;
break;
case com.zhidao.support.adas.high.common.Constants.IPC_CONNECTION_STATUS.SEARCH_ADDRESS:
case IPC_CONNECTION_STATUS.SEARCH_ADDRESS:
status = "搜索IP";
color = R.color.connect_status_search_address;
break;
case com.zhidao.support.adas.high.common.Constants.IPC_CONNECTION_STATUS.NOT_FOUND_ADDRESS:
case IPC_CONNECTION_STATUS.NOT_FOUND_ADDRESS:
status = "未找到";
color = R.color.connect_status_disconnecting;
break;
@@ -572,6 +581,7 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
tvConnectState.setTextColor(getResources().getColor(color));
}
});
return status;
}
@@ -588,6 +598,7 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
@Override
public void onSSHResult(final SSHResult info) {
LogSave.getInstance().saveLog("接收", info.toString());
runOnUiThread(new Runnable() {
@Override
public void run() {
@@ -599,47 +610,64 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
@Override
public void onError(ProtocolStatus status, byte[] bytes) {
EventBus.getDefault().postSticky(new ErrorData(status, bytes));
ErrorData base = new ErrorData(status, bytes);
LogSave.getInstance().saveLog("接收", base.toString());
EventBus.getDefault().postSticky(base);
}
@Override
public void onTrajectory(MessagePad.Header header, MessagePad.Trajectory trajectory) {
EventBus.getDefault().postSticky(new Trajectory(header, trajectory));
Trajectory base = new Trajectory(header, trajectory);
LogSave.getInstance().saveLog("接收", base.toString());
EventBus.getDefault().postSticky(base);
}
@Override
public void onTrackedObjects(MessagePad.Header header, MessagePad.TrackedObjects trackedObjects) {
EventBus.getDefault().postSticky(new TrackedObjects(header, trackedObjects));
TrackedObjects base = new TrackedObjects(header, trackedObjects);
LogSave.getInstance().saveLog("接收", base.toString());
EventBus.getDefault().postSticky(base);
}
@Override
public void onGnssInfo(MessagePad.Header header, MessagePad.GnssInfo gnssInfo) {
EventBus.getDefault().postSticky(new GnssInfo(header, gnssInfo));
GnssInfo base = new GnssInfo(header, gnssInfo);
LogSave.getInstance().saveLog("接收", base.toString());
EventBus.getDefault().postSticky(base);
}
@Override
public void onVehicleState(MessagePad.Header header, VehicleStateOuterClass.VehicleState vehicleState) {
EventBus.getDefault().postSticky(new VehicleState(header, vehicleState));
VehicleState base = new VehicleState(header, vehicleState);
LogSave.getInstance().saveLog("接收", base.toString());
EventBus.getDefault().postSticky(base);
}
@Override
public void onAutopilotState(MessagePad.Header header, MessagePad.AutopilotState autopilotState) {
EventBus.getDefault().postSticky(new AutopilotState(header, autopilotState));
AutopilotState base = new AutopilotState(header, autopilotState);
LogSave.getInstance().saveLog("接收", base.toString());
EventBus.getDefault().postSticky(base);
}
@Override
public void onReportMessage(MessagePad.Header header, MogoReportMsg.MogoReportMessage mogoReportMessage) {
EventBus.getDefault().postSticky(new MogoReportMessage(header, mogoReportMessage));
MogoReportMessage base = new MogoReportMessage(header, mogoReportMessage);
LogSave.getInstance().saveLog("接收", base.toString());
EventBus.getDefault().postSticky(base);
}
@Override
public void onPerceptionTrafficLight(MessagePad.Header header, TrafficLightOuterClass.TrafficLights trafficLights) {
EventBus.getDefault().postSticky(new PerceptionTrafficLight(header, trafficLights));
PerceptionTrafficLight base = new PerceptionTrafficLight(header, trafficLights);
LogSave.getInstance().saveLog("接收", base.toString());
EventBus.getDefault().postSticky(base);
}
@Override
public void onBasicInfoReq(MessagePad.Header header, MessagePad.BasicInfoReq basicInfoReq) {
BasicInfoReq info = new BasicInfoReq(header, basicInfoReq);
LogSave.getInstance().saveLog("接收", info.toString());
AdasManager.getInstance().sendBasicInfoResp("X202021111192N41VY", 1);
runOnUiThread(new Runnable() {
@Override
@@ -652,33 +680,44 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
@Override
public void onCarConfigResp(MessagePad.Header header, MessagePad.CarConfigResp carConfigResp) {
EventBus.getDefault().postSticky(new CarConfigResp(header, carConfigResp));
CarConfigResp base = new CarConfigResp(header, carConfigResp);
LogSave.getInstance().saveLog("接收", base.toString());
EventBus.getDefault().postSticky(base);
}
@Override
public void onRecordResult(MessagePad.Header header, RecordPanelOuterClass.RecordPanel recordPanel) {
RecordPanel base = new RecordPanel(header, recordPanel);
LogSave.getInstance().saveLog("接收", base.toString());
recordKey = recordPanel.getKey();
recordFileName = recordPanel.getFilename();
EventBus.getDefault().postSticky(new RecordPanel(header, recordPanel));
EventBus.getDefault().postSticky(base);
}
@Override
public void onGlobalPathResp(MessagePad.Header header, MessagePad.GlobalPathResp globalPathResp) {
EventBus.getDefault().postSticky(new GlobalPathResp(header, globalPathResp));
GlobalPathResp base = new GlobalPathResp(header, globalPathResp);
LogSave.getInstance().saveLog("接收", base.toString());
EventBus.getDefault().postSticky(base);
}
@Override
public void onWarn(MessagePad.Header header, MessagePad.Warn warn) {
EventBus.getDefault().postSticky(new Warn(header, warn));
Warn base = new Warn(header, warn);
LogSave.getInstance().saveLog("接收", base.toString());
EventBus.getDefault().postSticky(base);
}
@Override
public void onArrivalNotification(MessagePad.Header header, MessagePad.ArrivalNotification arrivalNotification) {
EventBus.getDefault().postSticky(new ArrivalNotification(header, arrivalNotification));
ArrivalNotification base = new ArrivalNotification(header, arrivalNotification);
LogSave.getInstance().saveLog("接收", base.toString());
EventBus.getDefault().postSticky(base);
}
@Override
public void onUpgradeStateInfo(final IPCUpgradeStateInfo info) {
LogSave.getInstance().saveLog("接收", info.toString());
EventBus.getDefault().postSticky(info);
}
@@ -714,9 +753,9 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
@Override
public void onClientStatusConnectChanged(int statusCode, String sign) {
if (statusCode == ConnectState.STATUS_CONNECT_SUCCESS) {
connectStatus = com.zhidao.support.adas.high.common.Constants.IPC_CONNECTION_STATUS.CONNECTED;
connectStatus = IPC_CONNECTION_STATUS.CONNECTED;
} else {
connectStatus = com.zhidao.support.adas.high.common.Constants.IPC_CONNECTION_STATUS.DISCONNECTED;
connectStatus = IPC_CONNECTION_STATUS.DISCONNECTED;
}
runOnUiThread(new Runnable() {
@Override
@@ -822,11 +861,13 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
@Override
public void onConnectionIPCStatus(int ipcConnectionStatus, String failedMsg) {
connectStatus = ipcConnectionStatus;
onUpdateConnectStateView();
if (connectStatus == com.zhidao.support.adas.high.common.Constants.IPC_CONNECTION_STATUS.CONNECTED) {
String status = onUpdateConnectStateView();
status += "failedMsg=" + failedMsg;
LogSave.getInstance().saveLog("连接状态", status);
if (connectStatus == IPC_CONNECTION_STATUS.CONNECTED) {
CupidLogUtils.w(TAG, "===>MainActivity onWebSocketConnectSuccess");
showIPCIP(AdasManager.getInstance().getIpcConnectedIp(), AdasManager.getInstance().getIpcConnectedPort());
} else if (connectStatus == com.zhidao.support.adas.high.common.Constants.IPC_CONNECTION_STATUS.DISCONNECTED) {
} else if (connectStatus == IPC_CONNECTION_STATUS.DISCONNECTED) {
toastMsg("连接失败:" + failedMsg);
CupidLogUtils.w(TAG, "===>MainActivity onWebSocketConnectFailed");
showIPCIP(AdasManager.getInstance().getIpcConnectedIp(), AdasManager.getInstance().getIpcConnectedPort());
@@ -889,8 +930,7 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas
@Override
public void onItemClick(int position, String data) {
CupidLogUtils.w(TAG, "TitleAdapter===>name:" + data);
// if (connectStatus == com.zhidao.support.adas.high.common.Constants.IPC_CONNECTION_STATUS.DISCONNECTED) {
// if (connectStatus != IPC_CONNECTION_STATUS.CONNECTED) {
// toastMsg("IPC 未连接");
// return;
// }

View File

@@ -4,6 +4,8 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F5F5F5"
android:focusable="true"
android:focusableInTouchMode="true"
tools:context=".ui.MainActivity">
<include
@@ -38,9 +40,9 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/info_btn"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="10dp"
android:layout_weight=".225" />
</LinearLayout>

View File

@@ -1,10 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="150dp"
android:layout_height="50dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="4dp"
android:background="@drawable/item_bg">
android:background="@drawable/item_bg"
android:gravity="center"
android:minHeight="50dp">
<TextView
android:id="@+id/tv_info_title"
@@ -14,6 +16,6 @@
android:gravity="center"
android:text="INFO"
android:textColor="@drawable/item_text_color"
android:textSize="16dp" />
android:textSize="16sp" />
</LinearLayout>

View File

@@ -0,0 +1,21 @@
<?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="match_parent"
android:layout_gravity="center"
android:layout_margin="4dp"
android:background="@drawable/item_bg"
android:gravity="center"
android:minWidth="150dp">
<TextView
android:id="@+id/tv_info_title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/selectableItemBackground"
android:gravity="center"
android:text="INFO"
android:textColor="@drawable/item_text_color"
android:textSize="16sp" />
</LinearLayout>

View File

@@ -56,145 +56,178 @@
android:textStyle="bold"
android:visibility="gone" />
<TextView
android:id="@+id/tv_connect_state"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="20dp"
android:gravity="right|center_vertical"
android:text="未连接"
android:textColor="@color/colorWhile"
android:textSize="16dp"
android:textStyle="bold" />
<View
android:id="@+id/line2"
android:layout_width="1dp"
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="5dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="5dp"
android:layout_marginBottom="10dp"
android:layout_toStartOf="@+id/tv_connect_state"
android:background="#fff124" />
<Switch
android:id="@+id/switch_log"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="@+id/line2"
android:checked="true"
android:text="日志:开"
android:textColor="@color/colorWhile" />
android:layout_marginStart="20dp"
android:layout_toEndOf="@id/local_ip"
android:layoutDirection="rtl">
<View
android:id="@+id/line1"
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_marginStart="5dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="5dp"
android:layout_marginBottom="10dp"
android:layout_toStartOf="@+id/switch_log"
android:background="#fff124" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/disconnect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="center_vertical"
android:layout_marginStart="5dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:layout_toStartOf="@+id/line1"
android:background="@drawable/btn_bg"
android:text="断开"
android:textColor="@color/colorWhile"
android:textSize="16dp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/connect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="center_vertical"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:layout_toStartOf="@+id/disconnect"
android:background="@drawable/btn_bg"
android:text="连接"
android:textColor="@color/colorWhile"
android:textSize="16dp"
android:textStyle="bold" />
<View
android:id="@+id/line"
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_marginStart="5dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="5dp"
android:layout_marginBottom="10dp"
android:layout_toStartOf="@+id/connect"
android:background="#fff124" />
<RadioGroup
android:id="@+id/connection_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toStartOf="@+id/line"
android:orientation="horizontal">
<RadioButton
android:id="@+id/assign"
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="指定"
android:textColor="#ffffff" />
<RadioButton
android:id="@+id/fixation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="固定"
android:textColor="#ffffff" />
</RadioGroup>
android:layout_height="match_parent">
<EditText
android:id="@+id/et_ip"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginEnd="5dp"
android:layout_toStartOf="@+id/connection_type"
android:digits="0123456789.:"
android:gravity="right|center_vertical"
android:hint="IP地址"
android:imeOptions="flagNoExtractUi"
android:inputType="number"
android:maxLength="21"
android:maxLines="1"
android:minWidth="100dp"
android:textColor="@color/colorWhile"
android:textSize="16dp" />
<TextView
android:id="@+id/tv_connect_state"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="10dp"
android:gravity="right|center_vertical"
android:text="未连接"
android:textColor="@color/colorWhile"
android:textSize="16dp"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_ip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_gravity="center_vertical"
android:layout_toStartOf="@+id/et_ip"
android:gravity="right|center_vertical"
android:text="指定IP"
android:textColor="@color/colorWhile"
android:textSize="16dp"
android:textStyle="bold" />
<View
android:id="@+id/line2"
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_marginStart="5dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="5dp"
android:layout_marginBottom="10dp"
android:layout_toStartOf="@+id/tv_connect_state"
android:background="#fff124" />
<LinearLayout
android:id="@+id/layout_cb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layoutDirection="ltr"
android:orientation="vertical">
<CheckBox
android:id="@+id/cb_print"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:checked="true"
android:text="打印"
android:textColor="#ffffff" />
<CheckBox
android:id="@+id/cb_save"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:text="存储"
android:textColor="#ffffff" />
</LinearLayout>
<TextView
android:id="@+id/log_hint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="日志:"
android:textColor="#ffffff" />
<View
android:id="@+id/line1"
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_marginStart="5dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="5dp"
android:layout_marginBottom="10dp"
android:layout_toStartOf="@+id/log_hint"
android:background="#fff124" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/disconnect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginTop="8dp"
android:layout_marginEnd="5dp"
android:layout_marginBottom="8dp"
android:background="@drawable/btn_bg"
android:text="断开"
android:textColor="@color/colorWhile"
android:textSize="16dp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/connect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:background="@drawable/btn_bg"
android:text="连接"
android:textColor="@color/colorWhile"
android:textSize="16dp"
android:textStyle="bold" />
<View
android:id="@+id/line"
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_marginStart="5dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="5dp"
android:layout_marginBottom="10dp"
android:layout_toStartOf="@+id/connect"
android:background="#fff124" />
<RadioGroup
android:id="@+id/connection_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layoutDirection="ltr"
android:orientation="horizontal">
<RadioButton
android:id="@+id/assign"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="指定"
android:textColor="#ffffff" />
<RadioButton
android:id="@+id/fixation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="固定"
android:textColor="#ffffff" />
</RadioGroup>
<EditText
android:id="@+id/et_ip"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:digits="0123456789.:"
android:gravity="right|center_vertical"
android:hint="IP地址"
android:imeOptions="flagNoExtractUi"
android:inputType="number"
android:maxLength="21"
android:maxLines="1"
android:minWidth="100dp"
android:textColor="@color/colorWhile"
android:textSize="16dp" />
<TextView
android:id="@+id/tv_ip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="right|center_vertical"
android:text="指定IP"
android:textColor="@color/colorWhile"
android:textSize="16dp"
android:textStyle="bold" />
</LinearLayout>
</HorizontalScrollView>
</RelativeLayout>