diff --git a/src/sixaunyi/.idea/sonarlint/issuestore/1/2/12963d86ac5c2888cc2a9ae459de5665bc06b01f b/src/sixaunyi/.idea/sonarlint/issuestore/1/2/12963d86ac5c2888cc2a9ae459de5665bc06b01f
new file mode 100644
index 0000000..5d32c84
--- /dev/null
+++ b/src/sixaunyi/.idea/sonarlint/issuestore/1/2/12963d86ac5c2888cc2a9ae459de5665bc06b01f
@@ -0,0 +1,5 @@
+
+>
+java:S1604"(Make this anonymous inner class a lambda(ʆ��
+P
+java:S1161":Add the "@Override" annotation above this method signature(����
\ No newline at end of file
diff --git a/src/sixaunyi/.idea/sonarlint/issuestore/index.pb b/src/sixaunyi/.idea/sonarlint/issuestore/index.pb
index 9d9b31f..15a33ca 100644
--- a/src/sixaunyi/.idea/sonarlint/issuestore/index.pb
+++ b/src/sixaunyi/.idea/sonarlint/issuestore/index.pb
@@ -16,4 +16,6 @@ i
 @
 app/build.gradle,f\4\f4a01d6a4fcb971362ec00a83903fd3902f52164
 k
-;app/src/main/java/com/example/sixaunyi/ControlActivity.java,c\9\c99a584c2117ed2df42496451bb97ac1147f5ea0
\ No newline at end of file
+;app/src/main/java/com/example/sixaunyi/ControlActivity.java,c\9\c99a584c2117ed2df42496451bb97ac1147f5ea0
+j
+:app/src/main/java/com/example/sixaunyi/SecondFragment.java,1\2\12963d86ac5c2888cc2a9ae459de5665bc06b01f
\ No newline at end of file
diff --git a/src/sixaunyi/app/src/main/AndroidManifest.xml b/src/sixaunyi/app/src/main/AndroidManifest.xml
index fcc33b4..2b1df5b 100644
--- a/src/sixaunyi/app/src/main/AndroidManifest.xml
+++ b/src/sixaunyi/app/src/main/AndroidManifest.xml
@@ -55,5 +55,4 @@
             </intent-filter>
         </activity>
     </application>
-
 </manifest>
\ No newline at end of file
diff --git a/src/sixaunyi/app/src/main/java/com/example/sixaunyi/DetectActivity.java b/src/sixaunyi/app/src/main/java/com/example/sixaunyi/DetectActivity.java
index 9f61cd3..1b676f5 100644
--- a/src/sixaunyi/app/src/main/java/com/example/sixaunyi/DetectActivity.java
+++ b/src/sixaunyi/app/src/main/java/com/example/sixaunyi/DetectActivity.java
@@ -208,14 +208,11 @@ public class DetectActivity extends AppCompatActivity {
                     e.printStackTrace();
                 }
             }
-
         }
-
         public void send(String msg) {
             System.out.println("msg的值为：  " + msg);
             list.add(msg);
         }
-
     }
 
 }
\ No newline at end of file
diff --git a/src/sixaunyi/app/src/main/java/com/example/sixaunyi/MainActivity.java b/src/sixaunyi/app/src/main/java/com/example/sixaunyi/MainActivity.java
index cd02c0e..7d9ec3e 100644
--- a/src/sixaunyi/app/src/main/java/com/example/sixaunyi/MainActivity.java
+++ b/src/sixaunyi/app/src/main/java/com/example/sixaunyi/MainActivity.java
@@ -2,6 +2,8 @@ package com.example.sixaunyi;
 
 import static androidx.constraintlayout.motion.utils.Oscillator.TAG;
 
+import static java.lang.Math.PI;
+
 import androidx.annotation.NonNull;
 import androidx.appcompat.app.AppCompatActivity;
 
@@ -9,9 +11,12 @@ import android.Manifest;
 import android.annotation.SuppressLint;
 import android.content.Intent;
 import android.graphics.BitmapFactory;
+import android.location.Location;
 import android.nfc.Tag;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
 import android.util.Log;
 import android.view.View;
 import android.widget.TextView;
@@ -41,6 +46,12 @@ import com.amap.api.services.poisearch.PoiResult;
 import com.amap.api.services.poisearch.PoiSearch;
 import com.google.android.material.floatingactionbutton.FloatingActionButton;
 
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.SocketException;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -84,10 +95,17 @@ public class MainActivity extends AppCompatActivity implements AMapLocationListe
     private List<Marker> markerList = new ArrayList<>();
     //标识参数类
     private MarkerOptions markerOption = new MarkerOptions();
-
-
-
-
+    //
+    private DatagramSocket reveSocket;
+    private final static String Recieve_IP = "192.168.240.46";
+    private final static int RECEIVE_PORT = 9999;
+    private boolean listenStatus = true;
+    private InetAddress serverAddr;
+    //private MainActivity.ReceiveHandler receiveHandler = new ReceiveHandler();
+    private String Angle;
+    private String MonitorAngle;
+    private float distance;
+    private float MonitorDistance;
 
     @SuppressLint("MissingInflatedId")
     @Override
@@ -107,6 +125,10 @@ public class MainActivity extends AppCompatActivity implements AMapLocationListe
         initMap(savedInstanceState);
         //检查安卓版本
         checkingAndroidVersion();
+
+        UdpReceiveThread udpReceiveThread = new UdpReceiveThread();
+        udpReceiveThread.startListening();
+
     }
     /**
      * 检查Android版本
@@ -320,10 +342,16 @@ public class MainActivity extends AppCompatActivity implements AMapLocationListe
     //LatLng 为高德地图包自带的存储坐标对象
     @Override
     public void onMapLongClick(LatLng latLng) {
-        float distance = AMapUtils.calculateLineDistance(Current_latlng,latLng);
+        distance = AMapUtils.calculateLineDistance(Current_latlng,latLng);
+        LatLng Monitorlatlng = new LatLng(113.05370390725032,28.256794281117525);
+        MonitorDistance = AMapUtils.calculateLineDistance(Current_latlng,Monitorlatlng);
+        Angle = calcAngle(Current_latlng.latitude, Current_latlng.longitude, latLng.latitude,latLng.longitude);
+        MonitorAngle = calcAngle(Current_latlng.latitude, Current_latlng.longitude, 113.05370390725032,28.256794281117525);
         //showMsg("长按了地图，经度："+latLng.longitude+"，纬度："+latLng.latitude);
-        showMsg("直线距离："+distance+"米");
-        //坐标转地址
+        Log.i(TAG,String.valueOf(latLng.longitude));
+        Log.i(TAG,String.valueOf(latLng.latitude));
+        showMsg("直线距离："+distance+"米"+"角度"+Angle);
+        //坐标转地址113.05370390725032 28.256794281117525
         latlonToAddress(latLng);
         //添加标点
         addMarker(latLng);
@@ -453,20 +481,113 @@ public class MainActivity extends AppCompatActivity implements AMapLocationListe
     public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {
 
     }
-/*
-    @Override
-    public void onPoiSearched(PoiResult poiResult, int i) {
-        //解析result获取POI信息
 
-        //获取POI组数列表
-        ArrayList<PoiItem> poiItems = poiResult.getPois();
-        for (PoiItem poiItem : poiItems) {
-            Log.d("MainActivity", " Title：" + poiItem.getTitle() + " Snippet：" + poiItem.getSnippet());
+    public class UdpReceiveThread extends Thread {
+        private static final String TAG = "UdpReceiveThread";
+        private static final int RECEIVE_PORT = 9999;
+        private boolean mRunning;
+        private String mReceiveIp = Recieve_IP;
+        private String mExpectedData = "Motion detected!";
+        private float mMonitorDistance = MonitorDistance;
+        private String mMonitorAngle = MonitorAngle;
+
+        @Override
+        public void run() {
+            try {
+                DatagramSocket socket = new DatagramSocket(RECEIVE_PORT);
+                byte[] buffer = new byte[1024];
+                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
+                while (mRunning) {
+                    socket.receive(packet);
+                    byte[] data = packet.getData();
+                    String receivedString = new String(data, 0, packet.getLength());
+                    Log.d(TAG, "Received data: " + receivedString);
+                    if (receivedString.equals(mExpectedData)) {
+                        Intent intent = new Intent(MainActivity.this, VideoActivity.class);
+                        Bundle b = new Bundle();
+                        b.putString("Angle", mMonitorAngle);
+                        b.putFloat("Distance", mMonitorDistance);
+                        intent.putExtras(b);
+                        intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
+                        startActivity(intent);
+                        mRunning = false;
+                    }
+                }
+                socket.close();
+
+            } catch (SocketException e) {
+                e.printStackTrace();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
         }
-    }*/
-    /*
-    @Override
-    public void (PoiItem poiItem, int i) {
 
-    }*/
+        public void startListening() {
+            mRunning = true;
+            start();
+        }
+
+        public void stopListening() {
+            mRunning = false;
+        }
+    }
+
+    //以北为0度
+    public static String calcAngle(Double centerLat, Double centerLon, Double anotherLat, Double anotherLon) {
+        //差值
+        double subLat = anotherLat - centerLat;
+        double subLon = anotherLon - centerLon;
+        double angle = 0;
+
+        if (subLat == 0) {
+            //纬度差值为0 表示两点在同一高度 此时点必然在x轴右侧 或者 x轴左侧
+            if (subLon > 0) {
+                //x轴右侧
+                angle = 90;
+            } else if (subLon < 0) {
+                //x轴左侧
+                angle = 270;
+            }
+        } else if (subLon == 0) {
+            //经度差值为0 说明点在y轴上方或者y轴下方
+            if (subLat > 0) {
+                //y轴上方
+                angle = 0;
+            } else if (subLat < 0) {
+                //y轴下方
+                angle = 180;
+            }
+        } else {
+            //根据tan的值，求角度 subLon不能为0  纬度差值 除以 经度差值 = tan的值
+            double v = subLat / subLon;
+            angle = Math.atan(v) * 180 / PI;
+            //angle的值在-180到180之间
+            System.out.println("未处理的角度值:" + (angle));
+            //第二种求角度的方法
+            //angle = Math.atan2(subLat,subLon) * 180 / PI  ;
+            //判断数据在第几象限
+            //1、正切小于0 在二四象限
+            if (angle < 0) {
+                if (subLon > 0) {
+                    //此时的点在中心点的右下角
+                    angle = Math.abs(angle)+ 90;
+                } else if (subLon < 0) {
+                    //此时的点在中心点的左上角
+                    angle = Math.abs(angle) + 270;
+                }
+            }
+            //2、正切大于0 在一三象限
+            else if (angle > 0) {
+                if (subLon > 0) {
+                    //此时的点在中心点的右上角  360-angle
+                    angle = 90-angle;
+                } else if (subLat < 0) {
+                    // 此时的点在中心点的左下角
+                    angle += 180;
+                }
+            }
+        }
+        return String.valueOf(angle);
+    }
+
 }
\ No newline at end of file
diff --git a/src/sixaunyi/app/src/main/java/com/example/sixaunyi/VideoActivity.java b/src/sixaunyi/app/src/main/java/com/example/sixaunyi/VideoActivity.java
index bd41882..eeb5145 100644
--- a/src/sixaunyi/app/src/main/java/com/example/sixaunyi/VideoActivity.java
+++ b/src/sixaunyi/app/src/main/java/com/example/sixaunyi/VideoActivity.java
@@ -4,14 +4,27 @@ import static androidx.constraintlayout.motion.utils.Oscillator.TAG;
 
 import androidx.appcompat.app.AppCompatActivity;
 
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.res.TypedArray;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.RectF;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.util.AttributeSet;
 import android.util.Log;
+import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.Button;
 import android.widget.ImageButton;
 import android.widget.ImageView;
@@ -29,23 +42,20 @@ import java.net.*;
 import android.os.Bundle;
 
 public class VideoActivity extends AppCompatActivity {
-
-
-    private final static String SEND_to_IP = "192.168.43.165"; //填写接收方IP
-    private final static String Recieve_IP = "192.168.43.165";//填服务器IP
+    private final static String SEND_to_IP = "192.168.39.47"; //填写接收方IP
+    private final static String Recieve_IP = "192.168.39.47";//填服务器IP，与send_to_IP为同一个
     private final static int SEND_PORT = 8888;               //发送端口号
     private final static int RECEIVE_PORT = 9999;            //接收端口号
 
-    private boolean listenStatus = true;  //接收线程的循环标识
+    private static boolean listenStatus = true;  //接收线程的循环标识
     private byte[] buf;
-    Bitmap bp;
-
+    static Bitmap bp;
     private DatagramSocket receiveSocket;
     private DatagramSocket sendSocket;
-    private DatagramSocket reveSocket;
-    private InetAddress serverAddr;
+    private static DatagramSocket reveSocket;
+    private static InetAddress serverAddr;
     private SendHandler sendHandler = new SendHandler();
-    private ReceiveHandler receiveHandler = new ReceiveHandler();
+    private static ReceiveHandler receiveHandler;
     private Button Trans_to_Detect;
     private ImageView imgShow;
     private Button btn;
@@ -57,8 +67,11 @@ public class VideoActivity extends AppCompatActivity {
     private ImageButton Up_btn;
     private ImageButton TurnLeft_btn;
     private ImageButton TurnRight_btn;
+    private ImageButton Setting_btn;
     private ImageButton TakeOff_btn;
     private Button Landing_btn;
+    private String angle;
+    private float distance;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -74,28 +87,109 @@ public class VideoActivity extends AppCompatActivity {
         TurnLeft_btn = findViewById(R.id.rotate_left_button);
         TurnRight_btn = findViewById(R.id.rotate_right_button);
         TakeOff_btn = findViewById(R.id.takeoff_button);
-        //Trans_to_Detect = findViewById(R.id.transfer_to_detect);
-        TakeOff_btn.setOnClickListener(new View.OnClickListener() {
+        Setting_btn = findViewById(R.id.setting_button);
+        Button_Init();
+        Intent i = getIntent();
+        distance = i.getFloatExtra("Distance",0);
+        angle = i.getStringExtra("Angle");
+    }
+    private void Button_Init(){
+        Forward_btn.setOnClickListener(new View.OnClickListener() {
+           @Override
+           public void onClick(View v) {
+               try {
+                   InitUdpSend("FORWARD");
+               } catch (UnknownHostException e) {
+                   throw new RuntimeException(e);
+               }
+               Log.i(TAG, "onClick: FFFFFFFForward");
+           }
+       });
+        Back_btn.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                UdpSendThread udpSendThread = new UdpSendThread();
-                udpSendThread.start();
-                udpSendThread.Send("TakeOff");
-                UdpReceiveThread udpReceiveThread = new UdpReceiveThread();
-                udpReceiveThread.start();
-                Log.i(TAG, "onClick: 2222222222222222222222222");
+                try {
+                    InitUdpSend("BACKWORD");
+                } catch (UnknownHostException e) {
+                    throw new RuntimeException(e);
+                }
+                Log.i(TAG, "onClick: BBBBBBBBackward");
+            }
+        });
+        Left_btn.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                try {
+                    InitUdpSend("LEFT");
+                } catch (UnknownHostException e) {
+                    throw new RuntimeException(e);
+                }
+                Log.i(TAG, "onClick: LLLLLLLLLLLLeft");
+            }
+        });
+        Right_btn.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                try {
+                    InitUdpSend("RIGHT");
+                } catch (UnknownHostException e) {
+                    throw new RuntimeException(e);
+                }
+                Log.i(TAG, "onClick: RRRRRRRRRRight");
+            }
+        });
+        Down_btn.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                try {
+                    InitUdpSend("DOWN");
+                } catch (UnknownHostException e) {
+                    throw new RuntimeException(e);
+                }
+                Log.i(TAG, "onClick: DDDDDDDDDown");
+            }
+        });
+        Up_btn.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                try {
+                    InitUdpSend("UP");
+                } catch (UnknownHostException e) {
+                    throw new RuntimeException(e);
+                }
+                Log.i(TAG, "onClick: UUUUUUUUUUUUUUp");
             }
         });
-        /*Trans_to_Detect.setOnClickListener(new View.OnClickListener() {
+        TurnLeft_btn.setOnClickListener(new View.OnClickListener() {
             @Override
-            public void onClick(View view) {
-                Intent intent = new Intent(VideoActivity.this, DetectActivity.class);
-                intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
-                startActivity(intent);
+            public void onClick(View v) {
+                try {
+                    InitUdpSend("TURN_LEFT");
+                } catch (UnknownHostException e) {
+                    throw new RuntimeException(e);
+                }
+                Log.i(TAG, "onClick: TTTTTTTTTurnLLLLLLLLLLeft");
             }
-        });*/
+        });
+        TurnRight_btn.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                try {
+                    InitUdpSend("TURN_RIGHT");
+                } catch (UnknownHostException e) {
+                    throw new RuntimeException(e);
+                }
+                Log.i(TAG, "onClick: TTTTTTTTTTTTurnRRRRRRRRRRight");
+            }
+        });
+        Setting_btn.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                //Intent intent = new Intent(VideoActivity.this, SpeedActivity.class);
+                //startActivity(intent);
+            }
+        });
     }
-
     class ReceiveHandler extends Handler{
         @Override
         public void handleMessage(Message msg) {
@@ -114,7 +208,7 @@ public class VideoActivity extends AppCompatActivity {
     /*
      *   UDP数据接受线程
      * */
-    public class UdpReceiveThread extends Thread
+    public static class UdpReceiveThread extends Thread
     {
         @Override
         public void run()
@@ -149,43 +243,240 @@ public class VideoActivity extends AppCompatActivity {
     /*
      *   UDP数据发送线程
      * */
-    public class UdpSendThread extends Thread {
+    public static class UdpSendThread extends Thread {
+
+        private InetAddress sendToIP;  // 目标 IP 地址
+        private int sendPort;  // 目标端口号
+        private byte[] sendData;  // 要发送的数据
+
+        public UdpSendThread(InetAddress sendToIP, int sendPort, byte[] sendData) {
+            this.sendToIP = sendToIP;
+            this.sendPort = sendPort;
+            this.sendData = sendData;
+        }
+
         @Override
         public void run() {
             try {
-                buf ="test".getBytes();
-                // 创建DatagramSocket对象，使用端口8888
-                sendSocket = new DatagramSocket(8888);
+                DatagramSocket sendSocket = new DatagramSocket();  // 创建一个新的 DatagramSocket 对象
+                DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, sendToIP, sendPort);  // 将要发送的数据打包成一个 DatagramPacket 对象
+                sendSocket.send(sendPacket);  // 发送 DatagramPacket
+                sendSocket.close();  // 发送完毕后关闭 DatagramSocket
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+    //初始化UDP发送线程
+    private static void InitUdpSend(String Sendstr) throws UnknownHostException {
+        InetAddress sendIP = InetAddress.getByName(SEND_to_IP);  // 目标 IP 地址
+        int sendPort = 8888;  // 目标端口号
+        byte[] sendData = Sendstr.getBytes();  // 要发送的数据
+        UdpSendThread sendThread = new UdpSendThread(sendIP, sendPort, sendData);  // 创建新的线程对象
+        sendThread.start();  // 启动线程发送数据
+    }
+//设置按钮
+    public void showDialog(View view) {
+        Dialog dialog = new Dialog(VideoActivity.this);
+        dialog.setContentView(R.layout.dialog_takeoff);
 
-                serverAddr = InetAddress.getByName(SEND_to_IP);
+        SlideUnlockView slideUnlockView = (SlideUnlockView) dialog.findViewById(R.id.slide_unlock_view);
+        slideUnlockView.setOnUnlockListener(new SlideUnlockView.OnUnlockListener() {
+            @Override
+            public void onUnlock() {
+                // 在用户滑动解锁后执行操作
+                try {
+                    InitUdpSend("TAKEOFF"+"___"+angle+"___"+String.valueOf(distance));
+                } catch (UnknownHostException e) {
+                    throw new RuntimeException(e);
+                }
+                UdpReceiveThread udpReceiveThread = new UdpReceiveThread();
+                udpReceiveThread.start();
+                Log.i(TAG, "onClick: 2222222222222222222222222");
 
-                DatagramPacket outPacket = new DatagramPacket(buf, buf.length, serverAddr, SEND_PORT);
-                sendSocket.send(outPacket);
+            }
+        });
+        dialog.show();
+    }
+//////////////////////////////滑动开关//////////////////////////////
+    public static class SlideUnlockView extends View{
 
-                sendSocket.close();
-                sendHandler.sendEmptyMessage(1);
-                Log.i(TAG, "run: 111111111111111111111111111111111111111111111111");
-            } catch (Exception e) {
-                e.printStackTrace();
+        private final int BG_COLOR = Color.parseColor("#2D2E32");  // 背景颜色
+        private static final int GUIDE_TEXT_COLOR = Color.WHITE;  // 引导文本颜色
+        private static final int GUIDE_TEXT_SIZE = 100;  // 引导文本大小
+        private static final int INDICATOR_COLOR = Color.WHITE;  // 指示器颜色
+        private static final int INDICATOR_RADIUS = 40;  // 指示器半径
+        private static final int INDICATOR_GAP = 300;  // 指示器间距
+        private static final int ARROW_COLOR = Color.WHITE;  // 箭头颜色
+        private static final int ARROW_SIZE = 20;  // 箭头大小
+
+        private static final int STATE_LOCKED = 0;  // 锁屏状态
+        private static final int STATE_DRAGGING = 1;  // 拖动状态
+        private static final int STATE_UNLOCKED = 2;  // 解锁状态
+
+        private Paint mPaint;
+        private Path mPath;
+        private int mViewWidth;
+        private int mViewHeight;
+        private int mIndicatorCount;
+        private int mCurrentIndex;
+        private float mLastX;
+        private boolean mIsUnlocked;
+        private int mState;
+
+        private OnUnlockListener mOnUnlockListener;
+
+        public abstract static class OnUnlockListener {
+            public class SimpleOnUnlockListener extends OnUnlockListener {
+                @Override
+                public void onUnlock() {
+                    // 默认空实现
+                }
             }
+            public abstract void onUnlock();
         }
-        public void Send(String str){
-            try {
-                buf =str.getBytes();
-                // 创建DatagramSocket对象，使用端口8888
-                sendSocket = new DatagramSocket(8888);
-                serverAddr = InetAddress.getByName(SEND_to_IP);
-                DatagramPacket outPacket = new DatagramPacket(buf, buf.length, serverAddr, SEND_PORT);
-                sendSocket.send(outPacket);
-
-                sendSocket.close();
-                sendHandler.sendEmptyMessage(1);
-                Log.i(TAG, "run: 111111111111111111111111111111111111111111111111");
-            } catch (Exception e) {
-                e.printStackTrace();
+
+        public void setOnUnlockListener(OnUnlockListener listener) {
+            this.mOnUnlockListener = listener;
+        }
+
+        public SlideUnlockView(Context context, AttributeSet attrs) {
+            super(context, attrs);
+            init();
+        }
+
+        private void init() {
+            mPaint = new Paint();
+            mPaint.setAntiAlias(true);  // 抗锯齿
+            mPaint.setStyle(Paint.Style.FILL);
+
+            mPath = new Path();
+
+            mIsUnlocked = false;
+            mState = STATE_LOCKED;
+
+            // 指示器个数为 3
+            mIndicatorCount = 3;
+        }
+
+        @Override
+        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+            super.onSizeChanged(w, h, oldw, oldh);
+            mViewWidth = w;
+            mViewHeight = h;
+        }
+        @Override
+        protected void onDraw(Canvas canvas) {
+            super.onDraw(canvas);
+            switch (mState) {
+                case STATE_LOCKED:
+                    drawGuideText(canvas);
+                    drawIndicatorCircles(canvas);
+                    break;
+                case STATE_DRAGGING:
+                    drawUnlockPath(canvas);
+                    drawUnlockArrow(canvas);
+                    break;
+                case STATE_UNLOCKED:
+                    if (mOnUnlockListener != null) {
+                        mOnUnlockListener.onUnlock();
+                    }
+                    break;
             }
         }
-    }
-}
 
+        private void drawGuideText(Canvas canvas) {
+            mPaint.setColor(BG_COLOR);
+            canvas.drawRect(0, 0, mViewWidth, mViewHeight, mPaint);
+
+            mPaint.setColor(GUIDE_TEXT_COLOR);
+            mPaint.setTextSize(GUIDE_TEXT_SIZE);
+            String guideText = "即将起飞";
+            float textWidth = mPaint.measureText(guideText);
+            float textX = mViewWidth / 2 - textWidth / 2;
+            float textY = mViewHeight * 2 / 3;
+            canvas.drawText(guideText, textX, textY, mPaint);
+        }
 
+        private void drawIndicatorCircles(Canvas canvas) {
+            mPaint.setColor(INDICATOR_COLOR);
+            float cy = mViewHeight / 2;
+            float startX = mViewWidth / 2 - INDICATOR_GAP * (mIndicatorCount - 1) / 2;
+            float radius = INDICATOR_RADIUS;
+            Path path = new Path();
+            for (int i = 0; i < mIndicatorCount; i++) {
+                float cx = startX + INDICATOR_GAP * i;
+                path.addCircle(cx, cy, radius, Path.Direction.CCW);
+            }
+            canvas.drawPath(path, mPaint);
+        }
+
+        private void drawUnlockPath(Canvas canvas) {
+            mPaint.setColor(INDICATOR_COLOR);
+            float cy = mViewHeight / 2;
+            float startX = mViewWidth / 2 - INDICATOR_GAP * (mIndicatorCount - 1) / 2;
+            float currentX = Math.max(Math.min(mLastX, mViewWidth - INDICATOR_RADIUS), startX + INDICATOR_GAP * mCurrentIndex);
+            Path path = new Path();
+            path.moveTo(startX + INDICATOR_RADIUS, cy);
+            path.lineTo(currentX - INDICATOR_RADIUS, cy);
+            path.arcTo(new RectF(currentX - INDICATOR_RADIUS, cy - INDICATOR_RADIUS,
+                    currentX + INDICATOR_RADIUS, cy + INDICATOR_RADIUS), -90, 180);
+            path.lineTo(startX + INDICATOR_GAP * (mIndicatorCount - 1), cy);
+            canvas.drawPath(path, mPaint);
+        }
+
+        private void drawUnlockArrow(Canvas canvas) {
+            mPaint.setColor(ARROW_COLOR);
+            mPaint.setStyle(Paint.Style.STROKE);
+            mPaint.setStrokeWidth(5);
+            Path arrowPath = new Path();
+            float x = Math.max(Math.min(mLastX, mViewWidth - INDICATOR_RADIUS - ARROW_SIZE), mViewWidth / 2 + INDICATOR_GAP * (mCurrentIndex - 1));
+            float y = mViewHeight / 2;
+            arrowPath.moveTo(x - ARROW_SIZE, y - ARROW_SIZE);
+            arrowPath.lineTo(x, y);
+            arrowPath.lineTo(x - ARROW_SIZE, y + ARROW_SIZE);
+            canvas.drawPath(arrowPath, mPaint);
+        }
+
+        @Override
+        public boolean onTouchEvent(MotionEvent event) {
+            float x = event.getX();
+            switch (event.getAction()) {
+                case MotionEvent.ACTION_DOWN:
+                    if (mState == STATE_LOCKED) {
+                        mState = STATE_DRAGGING;
+                        mCurrentIndex = 0;
+                        invalidate();
+                        return true;
+                    }
+                    break;
+                case MotionEvent.ACTION_MOVE:
+                    if (mState == STATE_DRAGGING) {
+                        mLastX = x;
+                        int index = (int) ((x - mViewWidth / 2) / INDICATOR_GAP);
+                        index = Math.max(Math.min(index, mIndicatorCount - 1), 0);
+                        if (index != mCurrentIndex) {
+                            mCurrentIndex = index;
+                            invalidate();
+                        }
+                        if (mCurrentIndex == mIndicatorCount - 1) {
+                            mState = STATE_UNLOCKED;
+                            mIsUnlocked = true;
+                        }
+                        return true;
+                    }
+                    break;
+                case MotionEvent.ACTION_UP:
+                case MotionEvent.ACTION_CANCEL:
+                    if (mState == STATE_DRAGGING) {
+                        mState = STATE_LOCKED;
+                        mCurrentIndex = 0;
+                        invalidate();
+                        return true;
+                    }
+                    break;
+            }
+            return super.onTouchEvent(event);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/sixaunyi/app/src/main/res/layout-land/activity_control.xml b/src/sixaunyi/app/src/main/res/layout-land/activity_control.xml
index 1fff7c2..2404caa 100644
--- a/src/sixaunyi/app/src/main/res/layout-land/activity_control.xml
+++ b/src/sixaunyi/app/src/main/res/layout-land/activity_control.xml
@@ -2,6 +2,8 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
+
+
     <!-- 显示无人机回传图像的控件 -->
     <ImageView
         android:id="@+id/imageView"
@@ -178,6 +180,7 @@
             android:scaleType="centerCrop"
             android:src="@drawable/takeoff"
             android:text="起飞"
+            android:onClick="showDialog"
             android:contentDescription="@string/takeoff_button"
             />
 
@@ -229,3 +232,5 @@
     </LinearLayout>
 
 </FrameLayout>
+
+
diff --git a/src/sixaunyi/app/src/main/res/layout/dialog_takeoff.xml b/src/sixaunyi/app/src/main/res/layout/dialog_takeoff.xml
new file mode 100644
index 0000000..f0075de
--- /dev/null
+++ b/src/sixaunyi/app/src/main/res/layout/dialog_takeoff.xml
@@ -0,0 +1,21 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:orientation="vertical">
+
+    <view
+        android:id="@+id/slide_unlock_view"
+        class="com.example.sixaunyi.VideoActivity$SlideUnlockView"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:backgroundColor="#03A9F4"
+        app:lockText="Slide to unlock"
+        app:sliderColor="@color/purple_200"
+        app:textColor="@color/purple_500"
+        app:textSize="50sp"
+        app:unlockText="Unlocked!" />
+
+    <!-- 其他控件 -->
+
+</LinearLayout>
\ No newline at end of file
diff --git a/src/sixaunyi/app/src/main/res/values/attrs.xml b/src/sixaunyi/app/src/main/res/values/attrs.xml
new file mode 100644
index 0000000..ef817d5
--- /dev/null
+++ b/src/sixaunyi/app/src/main/res/values/attrs.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <declare-styleable name="SlideUnlockView">
+        <attr name="textSize" format="dimension" />
+        <attr name="textColor" format="color" />
+        <attr name="sliderColor" format="color" />
+        <attr name="backgroundColor" format="color" />
+        <attr name="unlockText" format="string" />
+        <attr name="lockText" format="string" />
+    </declare-styleable>
+</resources>
\ No newline at end of file
diff --git a/src/sixaunyi/app/src/main/res/values/styles.xml b/src/sixaunyi/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..83c6f8d
--- /dev/null
+++ b/src/sixaunyi/app/src/main/res/values/styles.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <style name="MyDialogStyle" parent="Theme.AppCompat.Light.Dialog">
+        <item name="android:background">@android:color/transparent</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowIsFloating">true</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowAnimationStyle">@style/MyDialogAnimation</item>
+    </style>
+
+    <style name="MyDialogAnimation" parent="@android:style/Animation">
+        <item name="android:windowEnterAnimation">@android:anim/fade_in</item>
+        <item name="android:windowExitAnimation">@android:anim/fade_out</item>
+    </style>
+
+</resources>
\ No newline at end of file
