From dd170bf880918ce00a1df68e8a3c621ada9b5820 Mon Sep 17 00:00:00 2001
From: whycq <913841844@qq.com>
Date: 星期五, 07 二月 2025 13:54:30 +0800
Subject: [PATCH] #

---
 app/src/main/java/com/example/agvcontroller/action/LoginReset.java         |   31 +++
 app/src/main/java/com/example/agvcontroller/protocol/AGV_03_UP.java        |   42 ++++
 app/src/main/java/com/example/agvcontroller/protocol/HandleCmdType.java    |    3 
 app/src/main/java/com/example/agvcontroller/MainActivity.java              |   19 ++
 app/src/main/java/com/example/agvcontroller/utils/ToDBC.java               |   16 +
 app/src/main/res/layout/activity_log.xml                                   |   27 +++
 app/src/main/java/com/example/agvcontroller/AGVApplication.java            |   33 +++
 app/src/main/java/com/example/agvcontroller/LogActivity.java               |   39 ++++
 app/src/main/java/com/example/agvcontroller/socket/NettyServerHandler.java |   63 ++++--
 app/src/main/res/layout/activity_main.xml                                  |  218 ++++++++++++++---------
 app/src/main/res/drawable/new_logo.png                                     |    0 
 11 files changed, 380 insertions(+), 111 deletions(-)

diff --git a/app/src/main/java/com/example/agvcontroller/AGVApplication.java b/app/src/main/java/com/example/agvcontroller/AGVApplication.java
new file mode 100644
index 0000000..e7df4b3
--- /dev/null
+++ b/app/src/main/java/com/example/agvcontroller/AGVApplication.java
@@ -0,0 +1,33 @@
+package com.example.agvcontroller;
+
+import android.app.Application;
+import android.os.Handler;
+import android.os.Looper;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class AGVApplication extends Application {
+    private static List<String> logList = new ArrayList<>();
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+    }
+
+    @Override
+    public void onTerminate() {
+        super.onTerminate();
+        // 娓呯┖鏃ュ織鍒楄〃
+        logList.clear();
+    }
+
+    public static List<String> getLogList() {
+        return logList;
+    }
+
+    public static void addLog(String log) {
+        logList.add(log);
+    }
+
+}
diff --git a/app/src/main/java/com/example/agvcontroller/LogActivity.java b/app/src/main/java/com/example/agvcontroller/LogActivity.java
new file mode 100644
index 0000000..6438c9c
--- /dev/null
+++ b/app/src/main/java/com/example/agvcontroller/LogActivity.java
@@ -0,0 +1,39 @@
+package com.example.agvcontroller;
+
+import static com.example.agvcontroller.utils.ToDBC.toDBC;
+
+import android.os.Bundle;
+import android.widget.TextView;
+import java.util.List;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+public class LogActivity extends AppCompatActivity {
+
+    private TextView logTextView;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_log);
+
+        logTextView = findViewById(R.id.log_text_view);
+
+        // 鑾峰彇浼犻�掔殑鏃ュ織鏁版嵁
+        List<String> logList = getIntent().getStringArrayListExtra("log_list");
+
+
+
+        // 鏇存柊鏃ュ織鏄剧ず
+        updateLogTextView(logList);
+    }
+
+    private void updateLogTextView(List<String> logList) {
+        StringBuilder logBuilder = new StringBuilder();
+        for (String log : logList) {
+            logBuilder.append(log).append("\n");
+        }
+
+        logTextView.setText(toDBC(logBuilder.toString()));
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/agvcontroller/MainActivity.java b/app/src/main/java/com/example/agvcontroller/MainActivity.java
index 33187b5..0c45dd5 100644
--- a/app/src/main/java/com/example/agvcontroller/MainActivity.java
+++ b/app/src/main/java/com/example/agvcontroller/MainActivity.java
@@ -36,6 +36,7 @@
 import com.example.agvcontroller.action.HandLift;
 import com.example.agvcontroller.action.LiftResetAction;
 import com.example.agvcontroller.action.LoadResetAction;
+import com.example.agvcontroller.action.LoginReset;
 import com.example.agvcontroller.action.RotatopnLeftRight;
 import com.example.agvcontroller.action.SingleSwitchAction;
 import com.example.agvcontroller.action.SingleSwitchRunAction;
@@ -68,6 +69,7 @@
     private static final int MAX_RECENT_LOGS = 10; // 鏈�澶氭樉绀� 10 鏉℃渶鏂版棩蹇�
 
     private static TextView agvBattery;
+    private static TextView agvSocket;
     private static TextView agvNo;
     private static TextView agvStatus;
     private static TextView agvPositionId;
@@ -77,6 +79,7 @@
     private static TextView agvForkExtend;
     private static TextView agvForkAngle;
     private static TextView agvError;
+    private Button reLogin;
 
 
 
@@ -406,6 +409,7 @@
         setContentView(R.layout.activity_main);
 
         agvBattery = findViewById(R.id.agv_battery);
+        agvSocket = findViewById(R.id.socket);
         agvNo = findViewById(R.id.agv_no);
         agvStatus = findViewById(R.id.agv_status);
         agvPositionId = findViewById(R.id.agv_position_id);
@@ -415,6 +419,8 @@
         agvForkExtend = findViewById(R.id.agv_ford);
         agvForkAngle = findViewById(R.id.agv_ratio);
         agvError = findViewById(R.id.agv_error);
+        reLogin = findViewById(R.id.relogin_button);
+
 
 
 
@@ -524,6 +530,18 @@
 
         Log.i("message1",clientId);
 
+        reLogin.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                String substring = String.valueOf(new SnowflakeIdWorker().nextId()).substring(0,16);
+                AgvAction agvAction = new AgvAction<>(LoginReset.class)
+                        .setAgvNo(AgvNo)
+                        .setSerialNo(substring)
+                        .setVal(1)
+                        .bodySync((action) -> action.setPwd((short) 1));
+                nettyServerHandler.sendMessageToClient(clientId, agvAction); // 鍙戦�佹秷鎭埌瀹㈡埛绔�
+            }
+        });
         // 鍓嶆嫧鏉嗕几鍑�
         frontPaddleExtendBtn.setOnClickListener(new View.OnClickListener() {
             @Override
@@ -1460,6 +1478,7 @@
         AgvNo = agvCar.getAgvNo();
         agvNo.setText("AGV缂栧彿锛�" + AgvNo);
         agvBattery.setText("鐢甸噺锛�" + agvCar.getBattery() + "%");
+        agvSocket.setText(agvCar.getStatus() == 1 ? "宸茶繛鎺�" : "鏈繛鎺�");
         agvStatus.setText("AGV鐘舵�侊細" + agvCar.getStatus());
         agvPositionId.setText("ID锛�" + agvCar.getPositionID());
         agvPositionX.setText("(X)锛�" + agvCar.getPositionX());
diff --git a/app/src/main/java/com/example/agvcontroller/action/LoginReset.java b/app/src/main/java/com/example/agvcontroller/action/LoginReset.java
new file mode 100644
index 0000000..384ce98
--- /dev/null
+++ b/app/src/main/java/com/example/agvcontroller/action/LoginReset.java
@@ -0,0 +1,31 @@
+package com.example.agvcontroller.action;
+
+import com.example.agvcontroller.protocol.IActionBody;
+import com.example.agvcontroller.socket.RadixTools;
+
+import java.io.Serializable;
+
+public class LoginReset implements IActionBody, Serializable {
+    private static final long serialVersionUID = -3250235107705010315L;
+
+    private Short pwd;
+
+    @Override
+    public byte[] writeToBytes() {
+        byte[] bytes = RadixTools.shortToByte(pwd);
+        return bytes;
+    }
+
+    @Override
+    public void readFromBytes(byte[] messageBodyBytes) {
+
+    }
+
+    public Short getPwd() {
+        return pwd;
+    }
+
+    public void setPwd(Short pwd) {
+        this.pwd = pwd;
+    }
+}
diff --git a/app/src/main/java/com/example/agvcontroller/protocol/AGV_03_UP.java b/app/src/main/java/com/example/agvcontroller/protocol/AGV_03_UP.java
new file mode 100644
index 0000000..0d5b9d8
--- /dev/null
+++ b/app/src/main/java/com/example/agvcontroller/protocol/AGV_03_UP.java
@@ -0,0 +1,42 @@
+package com.example.agvcontroller.protocol;
+
+import com.example.agvcontroller.socket.RadixTools;
+
+import java.io.Serializable;
+
+public class AGV_03_UP implements IMessageBody, Serializable {
+
+    private static final long serialVersionUID = -5588066188890649095L;
+
+    @Override
+    public byte[] writeToBytes() {
+        return new byte[0];
+    }
+
+    @Override
+    public void readFromBytes(byte[] bytes) {
+
+        this.battery = Utils.sliceWithReverse(bytes, 2, 1)[0];
+
+        this.error = Utils.sliceWithReverse(bytes, 26, 4)[0];
+
+
+
+
+    }
+
+    @Override
+    public String getSerialNo() {
+        return "";
+    }
+
+    private int battery;
+
+    private int error;
+    public int getBattery() {
+        return battery;
+    }
+    public int getError() {
+        return error;
+    }
+}
diff --git a/app/src/main/java/com/example/agvcontroller/protocol/HandleCmdType.java b/app/src/main/java/com/example/agvcontroller/protocol/HandleCmdType.java
index 1acdc25..660254e 100644
--- a/app/src/main/java/com/example/agvcontroller/protocol/HandleCmdType.java
+++ b/app/src/main/java/com/example/agvcontroller/protocol/HandleCmdType.java
@@ -16,6 +16,7 @@
 import com.example.agvcontroller.action.HandOutAction;
 import com.example.agvcontroller.action.LiftResetAction;
 import com.example.agvcontroller.action.LoadResetAction;
+import com.example.agvcontroller.action.LoginReset;
 import com.example.agvcontroller.action.RotatopnLeftRight;
 import com.example.agvcontroller.action.SingleSwitchAction;
 import com.example.agvcontroller.action.SingleSwitchRunAction;
@@ -60,6 +61,8 @@
 
     BACK_PADDLE(0x8A, "鎵嬪姩鎺у埗鍚庢嫧鏉�", BackPaddle.class),
 
+    LOGIN_RESET(0x80, "閲嶆柊鐧诲綍", LoginReset.class),
+
 
     ;
 
diff --git a/app/src/main/java/com/example/agvcontroller/socket/NettyServerHandler.java b/app/src/main/java/com/example/agvcontroller/socket/NettyServerHandler.java
index 0c05544..bcc5bad 100644
--- a/app/src/main/java/com/example/agvcontroller/socket/NettyServerHandler.java
+++ b/app/src/main/java/com/example/agvcontroller/socket/NettyServerHandler.java
@@ -46,6 +46,7 @@
     private static final String TAG = "NettyServerHandler";
     private static ConcurrentHashMap<String, Channel> channelMap = new ConcurrentHashMap<>();
     private Map<String, Runnable> pendingRemovals = new HashMap<>();
+    AGVCar agvCar;
     int battery = 0;
     int status = 0;
     int agvStatus = 0;
@@ -58,6 +59,8 @@
     int forkExtend = 0;
     int forkAngle = 0;
     int agvError = 0;
+    String agvNo = "--";
+    String log;
     private Handler handler = new Handler(Looper.getMainLooper()) {
         @Override
         public void handleMessage(Message msg) {
@@ -75,14 +78,19 @@
         String ip = remoteAddress.getAddress().getHostAddress();
         int port = remoteAddress.getPort();
         channelMap.put(clientId, ctx.channel());
-        EventBus.getDefault().post(new AGVCar(clientId,ip,port,"--",0));
-        Log.d(TAG, "Client connected: " + clientId);
+        agvCar = new AGVCar(clientId, ip, port, agvNo, 1, battery,agvStatus,positionID,positionX,positionY,agvAngle,gyroAngle,forkHeight,forkExtend,forkAngle,agvError);
 
-        // 鍙栨秷寤惰繜鍒犻櫎鎿嶄綔
-        if (pendingRemovals.containsKey(clientId)) {
-            handler.removeCallbacks(pendingRemovals.get(clientId));
-            pendingRemovals.remove(clientId);
-        }
+        EventBus.getDefault().post(agvCar);
+//        Log.d(TAG, "Client connected: " + clientId);
+        log = formatDate(new Date(), "yyyy-MM-dd HH:mm:ss.SSS") + " 涓婅: " + ip + "[tcp]>>>宸茶繛鎺�";
+        Log.d("updown", log);
+        AGVApplication.addLog(log);
+
+//        // 鍙栨秷寤惰繜鍒犻櫎鎿嶄綔
+//        if (pendingRemovals.containsKey(clientId)) {
+//            handler.removeCallbacks(pendingRemovals.get(clientId));
+//            pendingRemovals.remove(clientId);
+//        }
 
     }
 
@@ -92,24 +100,38 @@
         InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
         String ip = remoteAddress.getAddress().getHostAddress();
         int port = remoteAddress.getPort();
-        channelMap.remove(clientId);
+//        channelMap.remove(clientId);
         EventBus.getDefault().post(clientId);
-        Log.d(TAG, "Client disconnected: " + clientId);
+//        Log.d(TAG, "Client disconnected: " + clientId);
+        agvCar = new AGVCar(clientId, ip, port, agvNo, 0, battery,agvStatus,positionID,positionX,positionY,agvAngle,gyroAngle,forkHeight,forkExtend,forkAngle,agvError);
 
-        // 鍚姩寤惰繜鍒犻櫎鎿嶄綔
-        Runnable removalRunnable = new Runnable() {
-            @Override
-            public void run() {
-                removeItem(clientId);
-            }
-        };
-        pendingRemovals.put(clientId, removalRunnable);
-        handler.postDelayed(removalRunnable, 20000); // 20绉掑悗鎵ц鍒犻櫎鎿嶄綔
+        EventBus.getDefault().post(agvCar);
+//        Log.d(TAG, "Client connected: " + clientId);
+        log = formatDate(new Date(), "yyyy-MM-dd HH:mm:ss.SSS") + " 涓婅: " + ip + "[tcp]>>>鏂紑杩炴帴";
+        Log.d("updown", log);
+        AGVApplication.addLog(log);
+//        // 鍚姩寤惰繜鍒犻櫎鎿嶄綔
+//        Runnable removalRunnable = new Runnable() {
+//            @Override
+//            public void run() {
+//                removeItem(clientId);
+//            }
+//        };
+//        pendingRemovals.put(clientId, removalRunnable);
+//        handler.postDelayed(removalRunnable, 20000); // 20绉掑悗鎵ц鍒犻櫎鎿嶄綔
 
     }
 
 
     private void removeItem(String clientId) {
+//        鍘熷厛鏄鍒犻櫎鍚庣画涓轰簡鑳藉姩鎬佽嚜鍔ㄨ繛鎺ラ渶瑕佹洿鏂�
+//        if (channelMap.remove(clientId) != null) {
+//            Log.d(TAG, "Client removed after 20 seconds: " + clientId);
+//            EventBus.getDefault().post(clientId);
+//        } else {
+//            Log.d(TAG, "Client already reconnected or not found: " + clientId);
+//        }
+
         if (channelMap.remove(clientId) != null) {
             Log.d(TAG, "Client removed after 20 seconds: " + clientId);
             EventBus.getDefault().post(clientId);
@@ -150,11 +172,6 @@
         // ack
         ProtocolType ackType = isNeedAck(pac);
         final String uniqueNo = pac.getHeader().getUniqueNo();
-        String agvNo;
-        AGVCar agvCar;
-
-        String log;
-
         label : switch (pac.getHeader().getProtocolType()){
             case ACTION_COMPLETE:   // 鍔ㄤ綔瀹屾垚鏁版嵁鍖�
                 AGV_11_UP agv_11_up = (AGV_11_UP) pac.getBody().getMessageBody();
diff --git a/app/src/main/java/com/example/agvcontroller/utils/ToDBC.java b/app/src/main/java/com/example/agvcontroller/utils/ToDBC.java
new file mode 100644
index 0000000..63ffed9
--- /dev/null
+++ b/app/src/main/java/com/example/agvcontroller/utils/ToDBC.java
@@ -0,0 +1,16 @@
+package com.example.agvcontroller.utils;
+
+public class ToDBC {
+    public static String toDBC(String input) {
+        char[] chars = input.toCharArray();
+        for (int i=0;i< chars.length; i++){
+            if(chars[i]== 12288){
+                chars[i]=(char)32;
+                continue;
+            }
+            if(chars[i]> 65280 && chars[i]< 65375)
+                chars[i]=(char)(chars[i]- 65248);
+        }
+        return new String(chars);
+    }
+}
diff --git a/app/src/main/res/drawable/new_logo.png b/app/src/main/res/drawable/new_logo.png
new file mode 100644
index 0000000..ddec72c
--- /dev/null
+++ b/app/src/main/res/drawable/new_logo.png
Binary files differ
diff --git a/app/src/main/res/layout/activity_log.xml b/app/src/main/res/layout/activity_log.xml
new file mode 100644
index 0000000..a096a15
--- /dev/null
+++ b/app/src/main/res/layout/activity_log.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/main"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".LogActivity">
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:fillViewport="true">
+        <TextView
+            android:id="@+id/log_text_view"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textSize="12sp"
+            android:textColor="#FFFFFF"
+            android:background="#000000"
+            android:focusable="true"
+            android:singleLine="false"
+            android:focusableInTouchMode="true"
+            android:breakStrategy="high_quality"
+            android:hyphenationFrequency="normal"
+            android:scrollbars="vertical" />
+    </ScrollView>
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index ba8cf23..773f12c 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -14,116 +14,157 @@
         android:orientation="vertical"
         android:padding="10dp"
         android:layout_weight="4">
-        <LinearLayout
+        <RelativeLayout
             android:layout_width="match_parent"
             android:layout_height="0dp"
-            android:layout_weight="2"
-            android:orientation="vertical">
-            >
-            <TextView
-                android:id="@+id/agv_battery"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:gravity=""
-                android:textSize="14sp"
-                android:text="鐢甸噺锛�100%"
-                android:textColor="#FFFFFF" />
-            <TextView
-                android:id="@+id/agv_no"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:gravity=""
-                android:textSize="14sp"
-                android:text="AGV缂栧彿锛�1"
-                android:textColor="#FFFFFF" />
-            <TextView
-                android:id="@+id/agv_status"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:gravity=""
-                android:textSize="14sp"
-                android:text="AGV鐘舵�侊細绌洪棽"
-                android:textColor="#FFFFFF" />
+            android:layout_weight="2">
             <LinearLayout
                 android:layout_width="match_parent"
-                android:layout_height="wrap_content" >
+                android:layout_height="match_parent"
+                android:orientation="vertical">
+                >
                 <TextView
-                    android:layout_width="wrap_content"
+                    android:id="@+id/agv_battery"
+                    android:layout_width="match_parent"
                     android:layout_height="wrap_content"
                     android:gravity=""
-                    android:textSize="12sp"
-                    android:layout_marginRight="10dp"
-                    android:text="褰撳墠浣嶇疆"
+                    android:textSize="14sp"
+                    android:text="鐢甸噺锛�100%"
                     android:textColor="#FFFFFF" />
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    >
+                    <TextView
+                        android:id="@+id/agv_no"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:gravity=""
+                        android:textSize="14sp"
+                        android:text="AGV缂栧彿锛�1"
+                        android:textColor="#FFFFFF" />
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:gravity=""
+                        android:textSize="14sp"
+                        android:text="  "
+                        android:textColor="#FFFFFF" />
+                    <TextView
+                        android:id="@+id/socket"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:gravity=""
+                        android:textSize="14sp"
+                        android:text="--"
+                        android:textColor="#FFFFFF" />
+                </LinearLayout>
+
                 <TextView
-                    android:id="@+id/agv_position_id"
-                    android:layout_width="wrap_content"
+                    android:id="@+id/agv_status"
+                    android:layout_width="match_parent"
                     android:layout_height="wrap_content"
                     android:gravity=""
-                    android:textSize="12sp"
-                    android:layout_marginRight="10dp"
-                    android:text="ID锛�9987"
+                    android:textSize="14sp"
+                    android:text="AGV鐘舵�侊細绌洪棽"
                     android:textColor="#FFFFFF" />
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content" >
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:gravity=""
+                        android:textSize="12sp"
+                        android:layout_marginRight="10dp"
+                        android:text="褰撳墠浣嶇疆"
+                        android:textColor="#FFFFFF" />
+                    <TextView
+                        android:id="@+id/agv_position_id"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:gravity=""
+                        android:textSize="12sp"
+                        android:layout_marginRight="10dp"
+                        android:text="ID锛�9987"
+                        android:textColor="#FFFFFF" />
+                    <TextView
+                        android:id="@+id/agv_position_x"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:gravity=""
+                        android:textSize="12sp"
+                        android:layout_marginRight="10dp"
+                        android:text="(X)锛�123087"
+                        android:textColor="#FFFFFF" />
+                    <TextView
+                        android:id="@+id/agv_position_y"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:gravity=""
+                        android:textSize="12sp"
+                        android:layout_marginRight="10dp"
+                        android:text="(Y)锛�432311"
+                        android:textColor="#FFFFFF" />
+                </LinearLayout>
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content" >
+                    <TextView
+                        android:id="@+id/agv_position_height"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:gravity=""
+                        android:textSize="12sp"
+                        android:layout_marginRight="10dp"
+                        android:text="褰撳墠楂樺害锛�100mm"
+                        android:textColor="#FFFFFF" />
+                    <TextView
+                        android:id="@+id/agv_ford"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:gravity=""
+                        android:textSize="12sp"
+                        android:layout_marginRight="10dp"
+                        android:text="璐у弶浼稿嚭璺濈锛�30mm"
+                        android:textColor="#FFFFFF" />
+                    <TextView
+                        android:id="@+id/agv_ratio"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:gravity=""
+                        android:textSize="12sp"
+                        android:layout_marginRight="10dp"
+                        android:text="璐у弶鏃嬭浆瑙掑害锛�90掳"
+                        android:textColor="#FFFFFF" />
+                </LinearLayout>
                 <TextView
-                    android:id="@+id/agv_position_x"
+                    android:id="@+id/agv_error"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:gravity=""
                     android:textSize="12sp"
                     android:layout_marginRight="10dp"
-                    android:text="(X)锛�123087"
-                    android:textColor="#FFFFFF" />
-                <TextView
-                    android:id="@+id/agv_position_y"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:gravity=""
-                    android:textSize="12sp"
-                    android:layout_marginRight="10dp"
-                    android:text="(Y)锛�432311"
+                    android:text="AGV鏁呴殰锛氬鑸晠闅� > 寰呮満鐘舵�佷笅涓㈢爜"
                     android:textColor="#FFFFFF" />
             </LinearLayout>
-            <LinearLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content" >
-                <TextView
-                    android:id="@+id/agv_position_height"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:gravity=""
-                    android:textSize="12sp"
-                    android:layout_marginRight="10dp"
-                    android:text="褰撳墠楂樺害锛�100mm"
-                    android:textColor="#FFFFFF" />
-                <TextView
-                    android:id="@+id/agv_ford"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:gravity=""
-                    android:textSize="12sp"
-                    android:layout_marginRight="10dp"
-                    android:text="璐у弶浼稿嚭璺濈锛�30mm"
-                    android:textColor="#FFFFFF" />
-                <TextView
-                    android:id="@+id/agv_ratio"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:gravity=""
-                    android:textSize="12sp"
-                    android:layout_marginRight="10dp"
-                    android:text="璐у弶鏃嬭浆瑙掑害锛�90掳"
-                    android:textColor="#FFFFFF" />
-            </LinearLayout>
-            <TextView
-                android:id="@+id/agv_error"
+            <com.google.android.material.button.MaterialButton
+                android:id="@+id/relogin_button"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:gravity=""
-                android:textSize="12sp"
-                android:layout_marginRight="10dp"
-                android:text="AGV鏁呴殰锛氬鑸晠闅� > 寰呮満鐘舵�佷笅涓㈢爜"
-                android:textColor="#FFFFFF" />
-        </LinearLayout>
+                android:layout_alignParentEnd="true"
+                android:layout_alignParentTop="true"
+                android:layout_marginLeft="20sp"
+                android:layout_centerVertical="true"
+                android:layout_marginRight="10sp"
+                android:backgroundTint="#2196F3"
+                android:minWidth="10dp"
+                android:paddingLeft="10dp"
+                android:paddingRight="10dp"
+                android:text="閲嶆柊鐧诲綍"
+                app:cornerRadius="5dp" />
+        </RelativeLayout>
+
         <RelativeLayout
             android:layout_width="match_parent"
             android:layout_height="0dp"
@@ -136,6 +177,7 @@
                 android:id="@+id/recent_log_text_view"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
+                android:scrollbars="vertical"
                 />
             <com.google.android.material.button.MaterialButton
                 android:id="@+id/view_all_logs_button"

--
Gitblit v1.9.1