From 9404fc9fce1d2f8678a5d1e6da2374b7a67783fe Mon Sep 17 00:00:00 2001
From: 18034727885 <973609879@qq.com>
Date: 星期四, 10 九月 2026 16:55:57 +0800
Subject: [PATCH] 修复问题,升级版本

---
 app/src/main/res/values-fr/strings.xml                                    |    9 
 app/src/main/java/com/driver/igotrip/ui/DialogUtil.kt                     |    6 
 app/src/main/res/values/styles.xml                                        |    1 
 app/src/main/java/com/driver/igotrip/utils/glide/GlideUtil.java           |   68 +-
 app/src/main/res/values/colors.xml                                        |    1 
 app/src/main/res/layout/activity_setting.xml                              |  429 ++++++++++---------
 build.gradle                                                              |    2 
 app/src/main/res/layout/activity_main.xml                                 |   18 
 app/src/main/java/com/driver/igotrip/netUtls/MyObserver.java              |    3 
 app/src/main/java/com/driver/igotrip/utils/MyUtils.java                   |    3 
 app/build.gradle                                                          |    8 
 app/src/main/java/com/driver/igotrip/ui/main/MainActivity.kt              |  119 +++--
 app/src/main/res/layout/fx_card.xml                                       |   51 ++
 app/src/main/res/values/strings.xml                                       |    9 
 app/src/main/AndroidManifest.xml                                          |   24 +
 app/src/main/res/color/selector_switch_track_tint.xml                     |    5 
 app/src/main/java/com/driver/igotrip/base/Const.java                      |    1 
 app/src/main/java/com/driver/igotrip/service/LocationForegroundService.kt |  181 ++++++++
 app/src/main/java/com/driver/igotrip/ui/mine/setting/SettingActivity.kt   |   42 ++
 app/src/main/java/com/driver/igotrip/base/MyApplication.kt                |  187 ++++++-
 app/src/main/java/com/driver/igotrip/ui/mine/MineActivity.kt              |    5 
 xldUtils/src/main/java/cn/sinata/xldutils/activitys/BaseActivity.java     |    2 
 app/src/main/java/com/driver/igotrip/netUtls/MyNoMsgObserver.java         |    3 
 app/src/main/res/values-en/strings.xml                                    |   17 
 app/src/main/java/com/driver/igotrip/ui/mine/setting/LanghActivity.kt     |    5 
 app/src/main/res/color/selector_switch_thumb_tint.xml                     |    5 
 26 files changed, 836 insertions(+), 368 deletions(-)

diff --git a/app/build.gradle b/app/build.gradle
index dfe3839..7873cf1 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -29,8 +29,8 @@
         applicationId "com.driver.goposttrip"
         minSdkVersion 23
         targetSdkVersion 36
-        versionCode 58
-        versionName "1.7.9"
+        versionCode 59
+        versionName "1.8.0"
         multiDexEnabled true
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
 
@@ -177,7 +177,7 @@
     implementation 'androidx.activity:activity-ktx:1.8.0'
     implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs')
     implementation "com.facebook.soloader:soloader:0.12.1"
-    implementation "org.jetbrains.kotlin:kotlin-stdlib:1.9.0"
+    implementation "org.jetbrains.kotlin:kotlin-stdlib:2.2.21"
     implementation 'com.tencent.mm.opensdk:wechat-sdk-android:6.8.34'
     implementation 'androidx.appcompat:appcompat:1.1.0'
     implementation 'androidx.core:core-ktx:1.2.0'
@@ -272,4 +272,6 @@
 //    implementation 'com.umeng.umsdk:asms:1.8.7.2' //必选
     //微信
 //    implementation 'com.umeng.umsdk:share-wx:7.3.7'
+    implementation "io.github.petterpx:floatingx-app:3.0.0"       // App 级全局浮窗(跟随 Activity)
+    implementation "io.github.petterpx:floatingx-system:3.0.0"    // 系统级浮窗(WindowManager + 权限)
 }
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 90bfd7f..b2fb8f0 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -42,7 +42,9 @@
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <!-- 用于申请调用A-GPS模块 -->
     <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> <!-- 用于申请获取蓝牙信息进行室内定位 -->
     <uses-permission android:name="android.permission.BLUETOOTH" />
-    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
+    <uses-permission
+        android:name="android.permission.FOREGROUND_SERVICE"
+        tools:ignore="ForegroundServicesPolicy" />
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
 
@@ -54,6 +56,15 @@
     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <!-- <uses-permission android:name="android.permission.READ_CONTACTS" /> -->
     <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" /> <!-- 诱导悬浮窗 -->
     <uses-permission android:name="android.permission.MANAGE_OVERLAY_PERMISSION" />
+    <!-- Android 10+ 后台定位权限 -->
+    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"
+        tools:ignore="BackgroundLocationPolicy" />
+
+    <!-- Android 14+ 定位前台服务专属权限 -->
+    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
+
+    <!-- Android 13+ 通知权限 -->
+    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
 
     <application
         android:name=".base.MyApplication"
@@ -66,6 +77,13 @@
         android:theme="@style/AppTheme"
         android:usesCleartextTraffic="true"
         tools:replace="android:allowBackup">
+        <service
+            android:name=".service.LocationForegroundService"
+            android:enabled="true"
+            android:foregroundServiceType="location"
+            android:exported="true"
+            android:permission="android.permission.FOREGROUND_SERVICE" />
+
         <activity
             android:name=".ui.main.ShowPictureActivity"
             android:exported="false" />
@@ -113,7 +131,9 @@
             android:name=".ui.pub.AreaCodeActivity"
             android:launchMode="singleTask" />
         <activity android:name=".ui.pub.ForgetPwdActivity" />
-        <activity android:name=".ui.main.MainActivity" />
+        <activity
+            android:name=".ui.main.MainActivity"
+            android:launchMode="singleTask" />
         <activity android:name=".ui.mine.MineActivity" />
         <activity android:name=".ui.mine.money_bag.MinePurseActivity" />
         <activity android:name=".ui.mine.money_bag.MineAwardActivity" />
diff --git a/app/src/main/java/com/driver/igotrip/base/Const.java b/app/src/main/java/com/driver/igotrip/base/Const.java
index b7deaf4..9b612e4 100644
--- a/app/src/main/java/com/driver/igotrip/base/Const.java
+++ b/app/src/main/java/com/driver/igotrip/base/Const.java
@@ -89,6 +89,7 @@
 
     public static String FIRST_LOGIN = "FIRST_LOGIN";
     public static String REFUSE_LOCATION = "REFUSE_LOCATION";
+    public static String REFUSE_FLOATING_WINDOW = "REFUSE_FLOATING_WINDOW";
 
 
 }
diff --git a/app/src/main/java/com/driver/igotrip/base/MyApplication.kt b/app/src/main/java/com/driver/igotrip/base/MyApplication.kt
index 9ac11c8..30293d7 100644
--- a/app/src/main/java/com/driver/igotrip/base/MyApplication.kt
+++ b/app/src/main/java/com/driver/igotrip/base/MyApplication.kt
@@ -12,6 +12,8 @@
 import android.os.*
 import android.util.Log
 import android.view.View
+import android.widget.ImageView
+import android.widget.TextView
 import androidx.fragment.app.Fragment
 import androidx.fragment.app.FragmentManager
 import cn.sinata.rxnetty.LogHelper.initLogs
@@ -24,16 +26,31 @@
 import com.driver.igotrip.bean.OrderSimpleData
 import com.driver.igotrip.bean.websocket.HeartBean
 import com.driver.igotrip.netUtls.*
+import com.driver.igotrip.service.LocationForegroundService
+import com.driver.igotrip.ui.main.MainActivity
 import com.driver.igotrip.ui.main.small_cargo.SmallCargoActivity
 import com.driver.igotrip.ui.pub.LoginActivity
 import com.driver.igotrip.utils.AudioRecoderUtils
 import com.driver.igotrip.utils.Cache.CacheKey
 import com.driver.igotrip.utils.Cache.CacheUtil
+import com.driver.igotrip.utils.LanguageSP
+import com.driver.igotrip.utils.LanguageSP.LanguageConst
 import com.driver.igotrip.utils.LogUtils
 import com.driver.igotrip.utils.crash.CrashHandler
+import com.driver.igotrip.utils.glide.GlideUtil
 import com.google.android.gms.maps.model.LatLng
 import com.google.cloud.texttospeech.v1.*
 import com.google.gson.Gson
+import com.petterp.floatingx.app.AppHost
+import com.petterp.floatingx.core.FloatingX
+import com.petterp.floatingx.core.FxControl
+import com.petterp.floatingx.core.FxListener
+import com.petterp.floatingx.core.layout.FxAdsorb
+import com.petterp.floatingx.core.layout.FxEdge
+import com.petterp.floatingx.core.layout.FxGravity
+import com.petterp.floatingx.core.storage.FxSpStorage
+import com.petterp.floatingx.system.permission.FxPermissionStrategy
+import com.petterp.floatingx.system.systemHost
 import com.xuexiang.xui.XUI
 import org.greenrobot.eventbus.EventBus
 import org.jetbrains.anko.startActivity
@@ -92,7 +109,7 @@
     private val MSG_ORDER_CANCEL = 1002
 
     @SuppressLint("HandlerLeak")
-    private val mHandler: Handler = object : Handler() {
+    private val mHandler: Handler = object : Handler(Looper.getMainLooper()) {
         override fun handleMessage(msg: Message) {
             super.handleMessage(msg)
             when (msg.what) {
@@ -158,32 +175,6 @@
         }
     }
 
-//    private val mAliasCallback =
-//        TagAliasCallback { code, alias, tags ->
-//            val logs: String
-//            when (code) {
-//                0 -> {
-//                    logs = "Set tag and alias success"
-//                    Log.i("TAG", logs)
-//                }
-//
-//                6002 -> {
-//                    logs = "Failed to set alias and tags due to timeout. Try again after 60s."
-//                    Log.i("TAG", logs)
-//                    // 延迟 60 秒来调用 Handler 设置别名
-//                    var alisa = "DRIVER" + CacheKey.getUserId()
-//                    Handler().postDelayed({
-//                        JPushInterface.setAliasAndTags(this, alisa, null, null)
-//                    }, 60 * 1000)
-//                }
-//
-//                else -> {
-//                    logs = "Failed with errorCode = $code"
-//                    Log.e("TAG", logs)
-//                }
-//            }
-//        }
-
     private fun initSocket() {
         NettyClient.getInstance().init(this, Api.SOCKET_SERVER, Api.SOCKET_PORT, true)
         NettyClient.getInstance().addOnMessageListener { message: String ->
@@ -220,6 +211,8 @@
                         CacheUtil.get().clear()
                         CacheKey.putKeyStr("isAgreen", "1")
                         NettyClient.getInstance().stopService()
+                        couldShowFloatingWindow = false
+                        LocationForegroundService.stop()
                         isLogin = false
                         val intent = Intent()
                         intent.setClass(this, LoginActivity::class.java)
@@ -391,18 +384,15 @@
                         logRecord("socket==>订单超时:$jsob")
                         val act = getTopActivity()
 
-                        /**
-                         * 司机超时推送
-                         * @param timeOutType  超时类型(1=用户可免费取消提醒,2=预约单接单提醒,3=超时循环提醒)
-                         * @param orderId  订单id
-                         * @param orderType  订单类型(1=打车,4=包裹)
-                         * @param describe  展示内容
-                         * @param audioUrl  语音播报音频地址
-                         */
+                        //超时类型(1=用户可免费取消提醒,2=预约单接单提醒,3=超时循环提醒)
                         val timeOutType = jsob.optString("timeOutType")
+                        //订单id
                         val orderId = jsob.optString("orderId")
+                        //订单类型(1=打车,4=包裹)
                         val orderType = jsob.optString("orderType")
+                        //展示内容
                         val describe = jsob.optString("describe")
+                        //语音播报音频地址
                         val audioUrl = jsob.optString("audioUrl")
 
                         if (timeOutType == "1" || timeOutType == "3") { // 仅提示
@@ -528,6 +518,31 @@
         var lastPlayTime = 0L //上次提示播放时间
         var hasAutoGoTripping = false //true 本次启动已经自动跳转过
         var isLogin: Boolean = true
+
+        //是否在上班
+        var isWorking = false
+            set(value) {
+                field = value
+                refreshFloatingWindow()
+            }
+        private var aMapLocation: LatLng? = null
+        var currentOrderId: String = ""
+        var currentOrderType: String = ""
+        var orderStatueViews: MutableList<OrderStatueView> = mutableListOf()
+
+        //悬浮窗tag
+        private const val FLOATING_X_TAG = "GO POST DRIVER"
+
+        //是否能显示悬浮窗
+        @JvmStatic
+        var couldShowFloatingWindow = false
+            set(value) {
+                field = value
+                if (!value) {
+                    dismissFloatingWindow()
+                }
+            }
+
         fun getInstance(): MyApplication? {
             if (appContext == null) {
                 appContext = MyApplication()
@@ -545,11 +560,6 @@
         fun getLocation(): LatLng? {
             return aMapLocation
         }
-
-        private var aMapLocation: LatLng? = null
-        var currentOrderId: String = ""
-        var currentOrderType: String = ""
-        var orderStatueViews: MutableList<OrderStatueView> = mutableListOf()
 
         //设置定位
         fun setLocation(latLng: LatLng) {
@@ -570,12 +580,94 @@
         fun removeOrderView(view: OrderStatueView?) {
             orderStatueViews.remove(view)
         }
+
+        //显示悬浮窗
+        fun showFloatingWindow() {
+            (FloatingX.controlOrNull(FLOATING_X_TAG) ?: FloatingX.install(FLOATING_X_TAG) {
+                view { ctx ->
+                    View.inflate(ctx, R.layout.fx_card, null).apply {
+                        findViewById<TextView>(R.id.tv1).apply {
+                            val language = LanguageSP.getLanguage(ctx)
+                            text = when (language) {
+                                LanguageConst.ZH_CN -> {
+                                    if (isWorking) "听单中" else "休息中"
+                                }
+
+                                LanguageConst.EN_US -> {
+                                    if (isWorking) "GO" else "On break"
+                                }
+
+                                else -> {
+                                    if (isWorking) "Aller" else "En pause"
+                                }
+                            }
+                        }
+                        findViewById<ImageView>(R.id.iv_logo).apply {
+                            GlideUtil.loadResource(this, R.mipmap.ic_launcher, true)
+                        }
+                    }
+                }
+                anchor(FxGravity.CENTER_START)
+                adsorb(FxAdsorb.Edges(setOf(FxEdge.START, FxEdge.END)))
+                persist(FxSpStorage(appContext!!))
+                enableLog("GO POST floating")
+                systemHost(appContext!!) {
+                    theme(R.style.Theme_FloatingX)
+                    permission(FxPermissionStrategy.auto())
+                    // this. 消歧:这里的 fallback / keyboard 既是 Builder 方法名也是本函数的参数名
+                    this.fallback(AppHost.builder(appContext!!).theme(R.style.Theme_FloatingX).build())
+                }
+            }.also {
+                it.addListener(object : FxListener {
+                    override fun onClick(control: FxControl, view: View) {
+                        dismissFloatingWindow()
+                        val activity = appContext?.getTopActivity()
+                        if (activity == null) {
+                            view.context.startActivity(Intent(view.context, MainActivity::class.java).apply {
+                                addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                            })
+                        } else {
+                            activity.startActivity<MainActivity>()
+                        }
+                    }
+
+                    override fun onLongClick(control: FxControl, view: View) {
+
+                    }
+                })
+            }).show()
+        }
+
+        //隐藏悬浮窗
+        @JvmStatic
+        fun dismissFloatingWindow() {
+            FloatingX.controlOrNull(FLOATING_X_TAG)?.hide()
+        }
+
+        //刷新悬浮窗
+        fun refreshFloatingWindow() {
+            val language = LanguageSP.getLanguage(appContext)
+            FloatingX.controlOrNull(FLOATING_X_TAG)?.contentView?.findViewById<TextView>(R.id.tv1)?.text =
+                when (language) {
+                    LanguageConst.ZH_CN -> {
+                        if (isWorking) "听单中" else "休息中"
+                    }
+
+                    LanguageConst.EN_US -> {
+                        if (isWorking) "GO" else "On break"
+                    }
+
+                    else -> {
+                        if (isWorking) "Aller" else "En pause"
+                    }
+                }
+        }
     }
 
     private val activities = ArrayList<Activity?>()
 
     //获取顶部activity
-    private fun getTopActivity(): Activity? {
+    fun getTopActivity(): Activity? {
         return activities.lastOrNull()
     }
 
@@ -621,6 +713,7 @@
 
     override fun onActivityStarted(activity: Activity) {
         showNum++
+        dismissFloatingWindow()
     }
 
     override fun onActivityResumed(activity: Activity) {
@@ -643,15 +736,27 @@
             }
             isPlayVoice = true
         }, 600)
+        if (showNum == 0 && couldShowFloatingWindow) {
+            showFloatingWindow()
+        }
     }
 
     override fun onActivityDestroyed(activity: Activity) {
         logRecord("onActivityDestroyed: " + activity.javaClass.name)
         activities.remove(activity)
+        if (activities.isEmpty()) {
+            couldShowFloatingWindow = false
+            dismissFloatingWindow()
+        }
     }
 
     override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
 //        logRecord("onActivitySaveInstanceState: " + activity.javaClass.name)
     }
 
+    override fun onTerminate() {
+        super.onTerminate()
+        couldShowFloatingWindow = false
+        LocationForegroundService.stop()
+    }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/driver/igotrip/netUtls/MyNoMsgObserver.java b/app/src/main/java/com/driver/igotrip/netUtls/MyNoMsgObserver.java
index 88b5180..175e12a 100644
--- a/app/src/main/java/com/driver/igotrip/netUtls/MyNoMsgObserver.java
+++ b/app/src/main/java/com/driver/igotrip/netUtls/MyNoMsgObserver.java
@@ -7,6 +7,7 @@
 
 import com.driver.igotrip.base.BaseEvent;
 import com.driver.igotrip.base.MyApplication;
+import com.driver.igotrip.service.LocationForegroundService;
 import com.driver.igotrip.ui.pub.LoginActivity;
 import com.driver.igotrip.utils.Cache.CacheUtil;
 import com.driver.igotrip.utils.LogUtils;
@@ -88,6 +89,8 @@
                 success(responseString);
             } else {
                 if (baseBean.getCode() == 600) {
+                    MyApplication.setCouldShowFloatingWindow(false);
+                    LocationForegroundService.stop();
                     CacheUtil.get().clear();
                     NettyClient.getInstance().stopService();
                     Intent intent = new Intent();
diff --git a/app/src/main/java/com/driver/igotrip/netUtls/MyObserver.java b/app/src/main/java/com/driver/igotrip/netUtls/MyObserver.java
index 53b8df1..86a63ee 100644
--- a/app/src/main/java/com/driver/igotrip/netUtls/MyObserver.java
+++ b/app/src/main/java/com/driver/igotrip/netUtls/MyObserver.java
@@ -8,6 +8,7 @@
 
 import com.driver.igotrip.base.BaseEvent;
 import com.driver.igotrip.base.MyApplication;
+import com.driver.igotrip.service.LocationForegroundService;
 import com.driver.igotrip.ui.pub.LoginActivity;
 import com.driver.igotrip.utils.Cache.CacheUtil;
 import com.driver.igotrip.utils.LogUtils;
@@ -89,6 +90,8 @@
                 success(responseString);
             } else {
                 if (baseBean.getCode() == 600) {
+                    MyApplication.setCouldShowFloatingWindow(false);
+                    LocationForegroundService.stop();
                     CacheUtil.get().clear();
                     NettyClient.getInstance().stopService();
                     Intent intent = new Intent();
diff --git a/app/src/main/java/com/driver/igotrip/service/LocationForegroundService.kt b/app/src/main/java/com/driver/igotrip/service/LocationForegroundService.kt
new file mode 100644
index 0000000..1488a06
--- /dev/null
+++ b/app/src/main/java/com/driver/igotrip/service/LocationForegroundService.kt
@@ -0,0 +1,181 @@
+package com.driver.igotrip.service
+
+import android.Manifest
+import android.app.Notification
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.app.PendingIntent
+import android.app.Service
+import android.content.Context
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.os.Build
+import android.os.IBinder
+import android.os.Looper
+import android.util.Log
+import androidx.core.app.ActivityCompat
+import androidx.core.app.NotificationCompat
+import androidx.core.content.ContextCompat
+import cn.sinata.rxnetty.LogHelper
+import com.driver.igotrip.R
+import com.driver.igotrip.base.MyApplication
+import com.driver.igotrip.netUtls.MyNoMsgObserver
+import com.driver.igotrip.ui.main.MainActivity
+import com.google.android.gms.location.FusedLocationProviderClient
+import com.google.android.gms.location.LocationCallback
+import com.google.android.gms.location.LocationRequest
+import com.google.android.gms.location.LocationResult
+import com.google.android.gms.location.LocationServices
+import com.google.android.gms.location.Priority
+
+//前台定位服务
+class LocationForegroundService : Service() {
+    private val tag = "LocationService"
+
+    /** 融合定位客户端,系统级 API,自动融合 GPS/Wi-Fi/基站 */
+    private lateinit var fusedClient: FusedLocationProviderClient
+
+    /** 定位请求参数 */
+    private lateinit var locationRequest: LocationRequest
+
+    /** 定位回调 */
+    private lateinit var locationCallback: LocationCallback
+
+    companion object {
+        private const val NOTIFICATION_ID = 1001
+        private const val CHANNEL_ID = "background location"
+        private const val ACTION_STOP = "action_stop_location"
+
+        //是否正在运行
+        private var isRunning = false
+
+        //启动 只能应用处于前台才能调用
+        fun start() {
+            val intent = Intent(MyApplication.appContext!!, LocationForegroundService::class.java)
+            ContextCompat.startForegroundService(MyApplication.appContext!!, intent)
+            isRunning = true
+        }
+
+        // 停止
+        @JvmStatic
+        fun stop() {
+            if (!isRunning) {
+                return
+            }
+            val intent = Intent(MyApplication.appContext, LocationForegroundService::class.java).apply {
+                action = ACTION_STOP
+            }
+            MyApplication.appContext!!.startService(intent)
+        }
+    }
+
+    override fun onCreate() {
+        super.onCreate()
+        // 初始化融合定位客户端
+        fusedClient = LocationServices.getFusedLocationProviderClient(this)
+
+        // 高精度 + 5 秒间隔,出行场景标配
+        locationRequest = LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 5_000L).apply {
+            setMinUpdateIntervalMillis(5_000L)  // 最快 5 秒一次
+            setWaitForAccurateLocation(true)    // 等待精准定位
+        }.build()
+
+        // 定位回调:收到位置后对外分发
+        locationCallback = object : LocationCallback() {
+            override fun onLocationResult(result: LocationResult) {
+                result.lastLocation?.let { location ->
+
+                    Log.d(tag, "location:${location.latitude}  ${location.longitude}")
+                    MyApplication.Companion.setLocation(location.latitude, location.longitude)
+                }
+            }
+        }
+        startTracking()
+    }
+
+    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
+        // 被系统杀死后尝试重启(前提是通知栏仍在)
+        if (intent?.action == ACTION_STOP) {
+            stopTracking()
+        }
+        return START_STICKY
+    }
+
+    //开始定位
+    private fun startTracking() {
+        val hadLocationPermission =
+            ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
+        val hadBackgroundLocationPermission =
+            ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED
+        if (!hadLocationPermission || !hadBackgroundLocationPermission) {
+            LogHelper.logRecord("had not permission hadLocationPermission:$hadLocationPermission hadBackgroundLocationPermission:$hadBackgroundLocationPermission")
+            return
+        }
+
+        // 1. 必须先 startForeground,否则服务会被系统立即回收
+        startForeground(NOTIFICATION_ID, buildNotification())
+        // 2. 注册定位监听
+        fusedClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())
+    }
+
+    //停止定位
+    private fun stopTracking() {
+        isRunning = false
+        fusedClient.removeLocationUpdates(locationCallback)
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            stopForeground(STOP_FOREGROUND_REMOVE)
+        }
+        stopSelf()
+    }
+
+    //构建前台服务通知(保活的门面)
+    private fun buildNotification(): Notification {
+        val notificationManager: NotificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            val channel: NotificationChannel = NotificationChannel(
+                CHANNEL_ID,
+                "background location",
+                NotificationManager.IMPORTANCE_HIGH
+            )
+            channel.description = "background location channel"
+
+            notificationManager.createNotificationChannel(channel)
+        }
+
+        // 点击通知回到应用
+        val contentIntent = PendingIntent.getActivity(
+            this,
+            0,
+            Intent(this, MainActivity::class.java).apply {
+                flags = if (MyApplication.Companion.appContext!!.getTopActivity() == null) {
+                    Intent.FLAG_ACTIVITY_NEW_TASK
+                } else {
+                    Intent.FLAG_ACTIVITY_SINGLE_TOP
+                }
+            },
+            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
+        )
+
+        return NotificationCompat.Builder(this, CHANNEL_ID)
+            .setContentTitle(getString(R.string.定位中))
+            .setContentText(getString(R.string.正在后台持续获取位置))
+            .setSmallIcon(R.mipmap.ic_launcher)
+            .setContentIntent(contentIntent)
+            .setOngoing(true)          // 常驻通知,不可滑动清除
+            .setPriority(NotificationCompat.PRIORITY_HIGH)
+            .build()
+    }
+
+    override fun onDestroy() {
+        isRunning = false
+        // 务必清理,否则会耗电 + 内存泄漏
+        if (::fusedClient.isInitialized) {
+            fusedClient.removeLocationUpdates(locationCallback)
+        }
+        super.onDestroy()
+    }
+
+    override fun onBind(intent: Intent): IBinder? {
+        return null
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/driver/igotrip/ui/DialogUtil.kt b/app/src/main/java/com/driver/igotrip/ui/DialogUtil.kt
index 0817003..8733d19 100644
--- a/app/src/main/java/com/driver/igotrip/ui/DialogUtil.kt
+++ b/app/src/main/java/com/driver/igotrip/ui/DialogUtil.kt
@@ -171,7 +171,7 @@
         }
         pop.contentView.find<View>(R.id.tv_ok_server_mode).setOnClickListener {
             if (adapter.getAllMode().isEmpty()){
-                ToastUtils.showShortToast(context,"请选择内容")
+                ToastUtils.showShortToast(context,context.getString(R.string.请选择内容))
                 return@setOnClickListener
             }
             pop.dismiss()
@@ -192,7 +192,7 @@
         }
         pop.contentView.find<View>(R.id.tv_ok_server_mode).setOnClickListener {
             if (adapter.selectPosition==-1){
-                ToastUtils.showShortToast(context,"请选择内容")
+                ToastUtils.showShortToast(context,context.getString(R.string.请选择内容))
                 return@setOnClickListener
             }
             pop.dismiss()
@@ -214,7 +214,7 @@
         }
         pop.contentView.find<View>(R.id.tv_ok_server_mode).setOnClickListener {
             if (adapter.getSelectId().isEmpty()){
-                ToastUtils.showShortToast(context,"请选择内容")
+                ToastUtils.showShortToast(context,context.getString(R.string.请选择内容))
                 return@setOnClickListener
             }
             pop.dismiss()
diff --git a/app/src/main/java/com/driver/igotrip/ui/main/MainActivity.kt b/app/src/main/java/com/driver/igotrip/ui/main/MainActivity.kt
index a3598db..3e24771 100644
--- a/app/src/main/java/com/driver/igotrip/ui/main/MainActivity.kt
+++ b/app/src/main/java/com/driver/igotrip/ui/main/MainActivity.kt
@@ -1,20 +1,23 @@
 package com.driver.igotrip.ui.main
 
 import android.Manifest
-import android.annotation.SuppressLint
 import android.content.ActivityNotFoundException
 import android.content.Intent
+import android.content.pm.PackageManager
+import android.os.Build
 import android.os.Bundle
 import android.os.Handler
 import android.os.Looper
 import android.os.Message
 import android.provider.Settings
-import android.util.Log
 import android.view.View
 import android.widget.ImageView
 import android.widget.LinearLayout
 import android.widget.TextView
 import android.widget.Toast
+import androidx.core.app.ActivityCompat
+import androidx.core.net.toUri
+import cn.sinata.rxnetty.LogHelper
 import cn.sinata.rxnetty.NettyClient
 import cn.sinata.xldutils.utils.SPUtils
 import cn.sinata.xldutils.utils.clickDelay
@@ -41,6 +44,7 @@
 import com.driver.igotrip.netUtls.Api
 import com.driver.igotrip.netUtls.callNet
 import com.driver.igotrip.netUtls.getMapByAny
+import com.driver.igotrip.service.LocationForegroundService
 import com.driver.igotrip.ui.DialogUtil
 import com.driver.igotrip.ui.DialogUtil.getDelAndSureDialog
 import com.driver.igotrip.ui.main.event.MineEventActivity
@@ -56,7 +60,6 @@
 import com.driver.mask_talk.utils.toTimeEnglish
 import com.driver.mask_talk.utils.toTimeFrench
 import com.google.android.gms.maps.GoogleMap
-import com.google.android.gms.maps.SupportMapFragment
 import com.google.gson.Gson
 import com.tbruyelle.rxpermissions2.RxPermissions
 import com.wang.avi.AVLoadingIndicatorView
@@ -85,7 +88,6 @@
     private val tv_today_time by lazy { find<TextView>(R.id.tv_today_time) }
     private val tv_week_time by lazy { find<TextView>(R.id.tv_week_time) }
     private val tv_month_time by lazy { find<TextView>(R.id.tv_month_time) }
-    private val map_view by lazy { supportFragmentManager.findFragmentById(R.id.map_view) }
     private val avv_anim by lazy { find<AVLoadingIndicatorView>(R.id.avv_anim) }
     private val tv_up_avv by lazy { find<TextView>(R.id.tv_up_avv) }
     private val tv_order_num by lazy { find<TextView>(R.id.tv_order_num) }
@@ -380,12 +382,10 @@
     lateinit var aMap: GoogleMap
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
-        if (CacheKey.getKeyStr(Const.REFUSE_LOCATION)
-                .isNotEmpty() && !RxPermissions(this).isGranted(
-                Manifest.permission.ACCESS_FINE_LOCATION
-            )
+        if (CacheKey.getKeyStr(Const.REFUSE_LOCATION).isNotEmpty() &&
+            !RxPermissions(this).isGranted(Manifest.permission.ACCESS_FINE_LOCATION)
         ) {
-            toast("Without positioning permission, you will not be able to receive new order push notifications")
+            toast(getString(R.string.没有定位权限提示))
         } else {
             if (!RxPermissions(this).isGranted(Manifest.permission.ACCESS_FINE_LOCATION)) {
                 DialogUtil.getDelAndSureDialog(
@@ -394,57 +394,72 @@
                     getString(R.string.拒绝权限),
                     getString(R.string.定位权限说明),
                     {
+                        LogHelper.logRecord("用户拒绝定位权限1")
                     }) {
                     val subscribe =
                         RxPermissions(this).request(Manifest.permission.ACCESS_FINE_LOCATION)
-                            .subscribe {
+                            .subscribe { it ->
                                 if (!it) {
-                                    toast("Without positioning permission, you will not be able to receive new order push notifications")
+                                    toast(getString(R.string.没有定位权限提示))
                                     CacheKey.putKeyStr(Const.REFUSE_LOCATION, "1")
-                                } else
-                                    initLocation()
+                                    LogHelper.logRecord("用户拒绝定位权限2")
+                                } else {
+                                    val subscribe = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+                                        RxPermissions(this).request(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
+                                            .subscribe {
+                                                if (!it) {
+                                                    toast(getString(R.string.没有定位权限提示))
+                                                    CacheKey.putKeyStr(Const.REFUSE_LOCATION, "1")
+                                                    LogHelper.logRecord("用户拒绝定位权限3")
+                                                } else {
+                                                    initLocation()
+                                                    initFloatingWindow()
+                                                }
+                                            }
+                                    } else {
+                                        initLocation()
+                                        initFloatingWindow()
+                                    }
+                                }
                             }
                 }
-            } else
+            } else {
                 initLocation()
-        }
-    }
-
-    @SuppressLint("MissingPermission", "CheckResult")
-    private fun initLocation() {
-        val fragment = map_view as SupportMapFragment
-        AMapKit.initMap(fragment) { it ->
-            // zmc-remark 测试代码 给个初始位置
-//            MyApplication.aMapLocation = LatLng(30.659221715540937,104.06676612263988)
-            aMap = it
-            aMap.isMyLocationEnabled = true
-            aMap.setOnMyLocationChangeListener {
-                it?.let {
-                    Log.e("定位==============》", "${it.latitude},${it.longitude}")
-                    MyApplication.setLocation(it.latitude, it.longitude)
-                }
+                initFloatingWindow()
             }
-
-//                    val fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
-//                    val locationRequest = LocationRequest.create().apply {
-//                        interval = 10000  // 10秒间隔
-//                        priority = LocationRequest.PRIORITY_HIGH_ACCURACY
-//                    }
-//
-//                    fusedLocationClient.requestLocationUpdates(locationRequest,
-//                        object : LocationCallback() {
-//                            override fun onLocationResult(it: LocationResult) {
-//                                // 处理位置更新
-//                                Log.e("定位 by fusedLocationClient ==============》","${it.lastLocation?.latitude},${it.lastLocation?.longitude}")
-//                            }
-//                        }, Looper.getMainLooper()
-//                    )
         }
     }
 
+    //初始化定位
+    private fun initLocation() {
+        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+            return
+        }
+        LocationForegroundService.start()
+    }
+
+    //初始化悬浮窗
+    private fun initFloatingWindow() {
+        if (!Settings.canDrawOverlays(this) && CacheKey.getKeyStr(Const.REFUSE_FLOATING_WINDOW) != "1") {
+            DialogUtil.getDelAndSureDialog(
+                this,
+                getString(R.string.确认),
+                getString(R.string.拒绝权限),
+                getString(R.string.悬浮窗说明),
+                {
+                    CacheKey.putKeyStr(Const.REFUSE_FLOATING_WINDOW, "1")
+                }) {
+                val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, "package:${packageName}".toUri()).apply {
+                    putExtra("package", packageName)
+                }
+                startActivity(intent)
+            }
+        }
+    }
 
     override fun onResume() {
         super.onResume()
+        MyApplication.couldShowFloatingWindow = Settings.canDrawOverlays(this) && CacheKey.getKeyStr(Const.REFUSE_FLOATING_WINDOW) != "1"
         mainFragment?.refresh()
         callNet(Api.needToSettle, getMapByAny()) {
             var bean = gson.fromJson(it, BooleanBean::class.java).data
@@ -480,6 +495,7 @@
             tv_lien_name.text = data.data.brand.toString()
             tv_car.text =
                 if (data.data.work == 1) getString(R.string.下班) else getString(R.string.出车)
+            MyApplication.isWorking = data.data.work == 1
             if (data.data.work == 1) {
                 /*try {
                     vehicleReporter?.setVehicleState(RidesharingVehicleReporter.VehicleState.ONLINE)
@@ -569,6 +585,7 @@
                 callNet(Api.work, getMapByAny()) {
                     homeDataBean?.data?.work = 2
                     tv_car.text = getString(R.string.出车)
+                    MyApplication.isWorking = false
                     beOnDuty(false)
                     val bean = Gson().fromJson<UpCarInfo>(it, UpCarInfo::class.java)
                     MyApplication.getTTsManager().setVideoText(bean.data?.audioUrl)
@@ -765,16 +782,6 @@
                 mainFragment?.refresh()
             }
 
-            BaseEvent.OFF_LINE -> {
-                Thread() {
-                    try {
-                        /*  vehicleReporter?.disableLocationTracking()
-                          RidesharingDriverApi.clearInstance()*/
-                    } catch (e: Exception) {
-                    }
-                }.start()
-            }
-
             BaseEvent.FORCED_OFFLINE -> {
                 initCall()
             }
@@ -800,6 +807,8 @@
 
      */
     override fun onDestroy() {
+        MyApplication.couldShowFloatingWindow = false
+        LocationForegroundService.stop()
         super.onDestroy()
         MyApplication.removeOrderView(qeeOrderView)
     }
diff --git a/app/src/main/java/com/driver/igotrip/ui/mine/MineActivity.kt b/app/src/main/java/com/driver/igotrip/ui/mine/MineActivity.kt
index 52d0e51..72d7059 100644
--- a/app/src/main/java/com/driver/igotrip/ui/mine/MineActivity.kt
+++ b/app/src/main/java/com/driver/igotrip/ui/mine/MineActivity.kt
@@ -16,6 +16,7 @@
 import cn.sinata.xldutils.utils.clickDelay
 import cn.sinata.xldutils.utils.getFormatOne
 import cn.sinata.xldutils.utils.getFormatTwo
+import com.driver.igotrip.service.LocationForegroundService
 import com.driver.igotrip.R
 import com.driver.igotrip.base.BaseEvent
 import com.driver.igotrip.base.MyApplication
@@ -190,10 +191,12 @@
         rl_settlement.setOnClickListener {
             startActivity<OfflinePayActivity>()
         }
-        //
+
         // 退出登录
         rl_login_out.setOnClickListener {
             DialogUtil.getDelAndSureDialog(this, getString(R.string.是否退出登录), {}, {
+                MyApplication.couldShowFloatingWindow = false
+                LocationForegroundService.stop()
                 CacheUtil.get().clear()
                 NettyClient.getInstance().stopService()
                 CacheKey.putKeyStr("isAgreen", "1")
diff --git a/app/src/main/java/com/driver/igotrip/ui/mine/setting/LanghActivity.kt b/app/src/main/java/com/driver/igotrip/ui/mine/setting/LanghActivity.kt
index ade9ab2..5ecab08 100644
--- a/app/src/main/java/com/driver/igotrip/ui/mine/setting/LanghActivity.kt
+++ b/app/src/main/java/com/driver/igotrip/ui/mine/setting/LanghActivity.kt
@@ -6,6 +6,7 @@
 import cn.sinata.xldutils.utils.setDrawableRight
 import com.driver.igotrip.R
 import com.driver.igotrip.base.Const
+import com.driver.igotrip.base.MyApplication
 import com.driver.igotrip.base.MyBaseActivity
 import com.driver.igotrip.netUtls.Api
 import com.driver.igotrip.netUtls.callNet
@@ -44,7 +45,7 @@
                 changeServerLanguage {
                     LanguageUtil.reApp(this)
                 }
-
+                MyApplication.refreshFloatingWindow()
             }
         }
 
@@ -54,6 +55,7 @@
                 changeServerLanguage {
                     LanguageUtil.reApp(this)
                 }
+                MyApplication.refreshFloatingWindow()
             }
         }
 
@@ -63,6 +65,7 @@
                 changeServerLanguage {
                     LanguageUtil.reApp(this)
                 }
+                MyApplication.refreshFloatingWindow()
             }
         }
     }
diff --git a/app/src/main/java/com/driver/igotrip/ui/mine/setting/SettingActivity.kt b/app/src/main/java/com/driver/igotrip/ui/mine/setting/SettingActivity.kt
index 3887203..ce15998 100644
--- a/app/src/main/java/com/driver/igotrip/ui/mine/setting/SettingActivity.kt
+++ b/app/src/main/java/com/driver/igotrip/ui/mine/setting/SettingActivity.kt
@@ -1,12 +1,16 @@
 package com.driver.igotrip.ui.mine.setting
 
+import android.content.Intent
+import android.provider.Settings
 import android.view.View
 import android.widget.TextView
+import androidx.core.net.toUri
 import cn.sinata.xldutils.utils.clickDelay
 import cn.sinata.xldutils.utils.getVersionName
 import com.driver.emanagercar.ui.base.BaseWebActivity
 import com.driver.igotrip.R
 import com.driver.igotrip.base.BaseEvent
+import com.driver.igotrip.base.Const
 import com.driver.igotrip.base.MyApplication
 import com.driver.igotrip.base.MyBaseActivity
 import com.driver.igotrip.bean.AgreeBean
@@ -15,7 +19,9 @@
 import com.driver.igotrip.netUtls.callNet
 import com.driver.igotrip.netUtls.getMapByAny
 import com.driver.igotrip.ui.DialogUtil
+import com.driver.igotrip.utils.Cache.CacheKey
 import com.driver.igotrip.utils.glide.GlideCacheUtil
+import com.google.android.material.switchmaterial.SwitchMaterial
 import com.tencent.mm.opensdk.modelbase.BaseReq
 import com.tencent.mm.opensdk.modelbase.BaseResp
 import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler
@@ -41,6 +47,8 @@
     private val ll_clear by lazy { find<View>(R.id.ll_clear) }
     private val ll_version by lazy { find<View>(R.id.ll_version) }
     private val tv_qa by lazy { find<View>(R.id.tv_qa) }
+    private val ll_floating_window by lazy { find<View>(R.id.ll_floating_window) }
+    private val sm_floating_window by lazy { find<SwitchMaterial>(R.id.sm_floating_window) }
 
     override fun initView() {
         setTitleText(getString(R.string.设置))
@@ -119,6 +127,36 @@
         ll_version.setOnClickListener {
             callVersion()
         }
+        sm_floating_window.setOnCheckedChangeListener { _, isChecked ->
+            MyApplication.couldShowFloatingWindow = isChecked
+        }
+        ll_floating_window.setOnClickListener {
+            if (!sm_floating_window.isChecked) {
+                if (CacheKey.getKeyStr(Const.REFUSE_FLOATING_WINDOW) != "1") {
+                    //用户没有拒绝过,但是没有授予权限
+                    val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, "package:${packageName}".toUri()).apply {
+                        putExtra("package", packageName)
+                    }
+                    startActivity(intent)
+                } else {
+                    //用户拒绝过
+                    CacheKey.putKeyStr(Const.REFUSE_FLOATING_WINDOW, "")
+                    if (!Settings.canDrawOverlays(this)) {
+                        //没有权限
+                        val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, "package:${packageName}".toUri()).apply {
+                            putExtra("package", packageName)
+                        }
+                        startActivity(intent)
+                    } else {
+                        //有权限
+                        sm_floating_window.isChecked = true
+                    }
+                }
+            } else {
+                sm_floating_window.isChecked = false
+                CacheKey.putKeyStr(Const.REFUSE_FLOATING_WINDOW, "1")
+            }
+        }
     }
 
 
@@ -163,4 +201,8 @@
         }
     }
 
+    override fun onResume() {
+        super.onResume()
+        sm_floating_window.isChecked = Settings.canDrawOverlays(this) && CacheKey.getKeyStr(Const.REFUSE_FLOATING_WINDOW) != "1"
+    }
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/driver/igotrip/utils/MyUtils.java b/app/src/main/java/com/driver/igotrip/utils/MyUtils.java
index 0e6bdef..484f0c0 100644
--- a/app/src/main/java/com/driver/igotrip/utils/MyUtils.java
+++ b/app/src/main/java/com/driver/igotrip/utils/MyUtils.java
@@ -25,6 +25,7 @@
 import android.view.inputmethod.InputMethodManager;
 
 import com.driver.igotrip.BuildConfig;
+import com.driver.igotrip.R;
 import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
 import com.lljjcoder.style.citylist.Toast.ToastUtils;
@@ -318,7 +319,7 @@
      */
     public void CallPhone(Activity context, String phone) {
         if (phone == null || phone.trim().isEmpty()) {
-            ToastUtils.showShortToast(context, "手机号为空");
+            ToastUtils.showShortToast(context, context.getString(R.string.手机号为空));
             return;
         }
         try {
diff --git a/app/src/main/java/com/driver/igotrip/utils/glide/GlideUtil.java b/app/src/main/java/com/driver/igotrip/utils/glide/GlideUtil.java
index 0d41dbe..6121c63 100644
--- a/app/src/main/java/com/driver/igotrip/utils/glide/GlideUtil.java
+++ b/app/src/main/java/com/driver/igotrip/utils/glide/GlideUtil.java
@@ -12,6 +12,7 @@
 import androidx.annotation.Nullable;
 
 import com.bumptech.glide.Glide;
+import com.bumptech.glide.RequestBuilder;
 import com.bumptech.glide.load.DataSource;
 import com.bumptech.glide.load.engine.DiskCacheStrategy;
 import com.bumptech.glide.load.engine.GlideException;
@@ -73,13 +74,25 @@
 
     /***
      * 加载图片
+     */
+    @SuppressLint("CheckResult")
+    public static void loadResource(ImageView imageView, int res, boolean isCircle) {
+        RequestBuilder<Drawable> load = Glide.with(imageView).load(res);
+        if (isCircle) {
+            load.apply(new RequestOptions().circleCrop());
+        }
+        load.into(imageView);
+    }
+
+    /***
+     * 加载图片
      * @param context
      * @param url
      * @param imageView
      */
     @SuppressLint("CheckResult")
     public static void load(Context context, String url, ImageView imageView, int num) {
-        if (url == null || url.isEmpty()){
+        if (url == null || url.isEmpty()) {
             return;
         }
         if (url.endsWith("mp4") || url.endsWith("AVI") || url.endsWith("MP4") || url.endsWith("avi")) {
@@ -87,7 +100,7 @@
                 try {
                     Bitmap myBitmap = Glide.with(context).asBitmap().load(url).submit(100, 100).get();
                     new Handler(Looper.getMainLooper()).post(() -> {
-                        loadBM(context,myBitmap,imageView,num);
+                        loadBM(context, myBitmap, imageView, num);
                     });
                 } catch (ExecutionException e) {
                     e.printStackTrace();
@@ -111,7 +124,7 @@
                 try {
                     Bitmap myBitmap = Glide.with(context).asBitmap().load(url).submit(100, 100).get();
                     new Handler(Looper.getMainLooper()).post(() -> {
-                        loadBM(context,myBitmap,imageView,num);
+                        loadBM(context, myBitmap, imageView, num);
                     });
                 } catch (ExecutionException e) {
                     e.printStackTrace();
@@ -138,11 +151,11 @@
 
 
     public static void loadBitMap(Context context, String url, ImageView imageView) {
-        loadBitMap(context, url, imageView, 4,false);
+        loadBitMap(context, url, imageView, 4, false);
     }
 
     public static void loadBitMapFit(Context context, String url, ImageView imageView) {
-        loadBitMap(context, url, imageView, 4,true);
+        loadBitMap(context, url, imageView, 4, true);
     }
 
 
@@ -152,9 +165,9 @@
         if (url.endsWith("mp4") || url.endsWith("AVI") || url.endsWith("MP4") || url.endsWith("avi")) {
             new Thread(() -> {
                 try {
-                    Bitmap myBitmap = Glide.with(context).asBitmap().load(url).submit(imageView.getWidth()/3, imageView.getHeight()/3).get();
+                    Bitmap myBitmap = Glide.with(context).asBitmap().load(url).submit(imageView.getWidth() / 3, imageView.getHeight() / 3).get();
                     new Handler(Looper.getMainLooper()).post(() -> {
-                        loadBMFit(context,myBitmap,imageView,num);
+                        loadBMFit(context, myBitmap, imageView, num);
                     });
                 } catch (ExecutionException e) {
                     e.printStackTrace();
@@ -172,15 +185,15 @@
     }
 
 
-    public static void loadFit(Context context, String url, ImageView imageView, int num, int placeHolder,OverImgView view) {
+    public static void loadFit(Context context, String url, ImageView imageView, int num, int placeHolder, OverImgView view) {
         if (TextUtils.isEmpty(url))
             return;
         if (url.endsWith("mp4") || url.endsWith("AVI") || url.endsWith("MP4") || url.endsWith("avi")) {
             new Thread(() -> {
                 try {
-                    Bitmap myBitmap = Glide.with(context).asBitmap().load(url).submit(imageView.getWidth()/3, imageView.getHeight()/3).get();
+                    Bitmap myBitmap = Glide.with(context).asBitmap().load(url).submit(imageView.getWidth() / 3, imageView.getHeight() / 3).get();
                     new Handler(Looper.getMainLooper()).post(() -> {
-                        loadBMFit(context,myBitmap,imageView,num);
+                        loadBMFit(context, myBitmap, imageView, num);
                     });
                 } catch (ExecutionException e) {
                     e.printStackTrace();
@@ -210,31 +223,31 @@
     }
 
 
-    public interface OverImgView{
+    public interface OverImgView {
         void over();
+
         void fail();
     }
 
 
-
-    private static void loadBM(Context context, Bitmap bitmap, ImageView imageView, int num){
+    private static void loadBM(Context context, Bitmap bitmap, ImageView imageView, int num) {
         try {
             Glide.with(context)
                     .load(bitmap)
                     .apply(getRequestOption(num))
                     .into(imageView);
-        }catch (Exception e){
+        } catch (Exception e) {
 
         }
     }
 
-    private static void loadBMFit(Context context, Bitmap bitmap, ImageView imageView, int num){
+    private static void loadBMFit(Context context, Bitmap bitmap, ImageView imageView, int num) {
         try {
             Glide.with(context)
                     .load(bitmap)
                     .apply(getRequestOptionFit(num))
                     .into(imageView);
-        }catch (Exception e){
+        } catch (Exception e) {
 
         }
     }
@@ -300,29 +313,24 @@
     }
 
 
-
-
-
-
-
-    public static void loadBitMap(Context context, String url, ImageView imageView, Integer i,boolean isfit) {
+    public static void loadBitMap(Context context, String url, ImageView imageView, Integer i, boolean isfit) {
         new Thread(() -> {
             try {
                 Bitmap myBitmap = Glide.with(context).asBitmap().load(url).submit(100, 100).get();
                 new Handler(Looper.getMainLooper()).post(() -> {
                     if (url.endsWith("mp4") || url.endsWith("avi")) {
                         Bitmap map = doBlur(myBitmap, 15, false);
-                        if (!isfit){
-                            loadBM(context,map,imageView,i);
-                        }else {
-                            loadBMFit(context,map,imageView,i);
+                        if (!isfit) {
+                            loadBM(context, map, imageView, i);
+                        } else {
+                            loadBMFit(context, map, imageView, i);
                         }
                     } else {
                         Bitmap map = doBlur(myBitmap, 15, false);
-                        if (!isfit){
-                            loadBM(context,map,imageView,i);
-                        }else {
-                            loadBMFit(context,map,imageView,i);
+                        if (!isfit) {
+                            loadBM(context, map, imageView, i);
+                        } else {
+                            loadBMFit(context, map, imageView, i);
                         }
                     }
                 });
diff --git a/app/src/main/res/color/selector_switch_thumb_tint.xml b/app/src/main/res/color/selector_switch_thumb_tint.xml
new file mode 100644
index 0000000..0205466
--- /dev/null
+++ b/app/src/main/res/color/selector_switch_thumb_tint.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+<item android:state_checked="false" android:color="@color/btn_color"/>
+<item android:state_checked="true" android:color="@color/blue_1"/>
+</selector>
\ No newline at end of file
diff --git a/app/src/main/res/color/selector_switch_track_tint.xml b/app/src/main/res/color/selector_switch_track_tint.xml
new file mode 100644
index 0000000..daacec7
--- /dev/null
+++ b/app/src/main/res/color/selector_switch_track_tint.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+<item android:state_checked="false" android:color="@color/main_gray"/>
+<item android:state_checked="true" android:color="@color/blue_3"/>
+</selector>
\ 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 b6591f2..fae5108 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -373,24 +373,6 @@
     <RelativeLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent">
-        <fragment
-            android:id="@+id/map_view"
-            xmlns:map="http://schemas.android.com/apk/res-auto"
-            android:name="com.google.android.gms.maps.SupportMapFragment"
-            android:layout_width="100dp"
-            map:uiZoomControls="false"
-            map:uiRotateGestures="true"
-            map:cameraBearing="112.5"
-            map:cameraTargetLat="-33.796923"
-            map:cameraTargetLng="150.922433"
-            map:cameraTilt="30"
-            map:cameraZoom="13"
-            map:mapType="normal"
-            map:uiCompass="false"
-            map:uiScrollGestures="true"
-            map:uiTiltGestures="true"
-            map:uiZoomGestures="true"
-            android:layout_height="100dp" />
 
         <RelativeLayout
             android:id="@+id/rl_container"
diff --git a/app/src/main/res/layout/activity_setting.xml b/app/src/main/res/layout/activity_setting.xml
index b095a0d..c980a67 100644
--- a/app/src/main/res/layout/activity_setting.xml
+++ b/app/src/main/res/layout/activity_setting.xml
@@ -1,227 +1,248 @@
 <?xml version="1.0" encoding="utf-8"?>
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
-    android:orientation="vertical"
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
     android:background="@color/bg_main"
-    android:layout_height="match_parent">
-
-    <TextView
-        android:id="@+id/tv_more_langh"
-        android:layout_width="match_parent"
-        android:layout_height="50dp"
-        android:gravity="center_vertical"
-        android:paddingStart="14dp"
-        android:background="@color/white"
-        android:paddingEnd="14dp"
-        android:drawableEnd="@mipmap/more_black"
-        android:text="@string/多语言"
-        android:textColor="#ff333333"
-        android:textSize="14sp"
-        />
-
-    <View
-        android:layout_width="match_parent"
-        android:layout_height="14dp"
-        android:background="#F3F4F5"
-        android:id="@+id/view_line_14"
-        android:alpha="0.3"
-        />
-    <TextView
-        android:id="@+id/tv_user_to"
-        android:layout_width="match_parent"
-        android:layout_height="50dp"
-        android:gravity="center_vertical"
-        android:paddingStart="14dp"
-        android:background="@color/white"
-        android:paddingEnd="14dp"
-        android:drawableEnd="@mipmap/more_black"
-        android:text="@string/用户指南"
-        android:textColor="#ff333333"
-        android:textSize="14sp"
-        />
-
-    <include layout="@layout/include_line_14"/>
-    <TextView
-        android:id="@+id/tv_qa"
-        android:layout_width="match_parent"
-        android:layout_height="50dp"
-        android:gravity="center_vertical"
-        android:paddingStart="14dp"
-        android:background="@color/white"
-        android:paddingEnd="14dp"
-        android:drawableEnd="@mipmap/more_black"
-        android:text="@string/常见问题"
-        android:textColor="#ff333333"
-        android:textSize="14sp"
-        />
-
-    <include layout="@layout/include_line_14"/>
-
-    <TextView
-        android:id="@+id/tv_rule"
-        android:layout_width="match_parent"
-        android:layout_height="50dp"
-        android:gravity="center_vertical"
-        android:paddingStart="14dp"
-        android:background="@color/white"
-        android:paddingEnd="14dp"
-        android:drawableEnd="@mipmap/more_black"
-        android:text="@string/法律条款和平台规则"
-        android:textColor="#ff333333"
-        android:textSize="14sp"
-        />
-
-    <include layout="@layout/include_line_14"/>
-
-    <TextView
-        android:id="@+id/tv_yh"
-        android:layout_width="match_parent"
-        android:layout_height="50dp"
-        android:gravity="center_vertical"
-        android:paddingStart="14dp"
-        android:background="@color/white"
-        android:paddingEnd="14dp"
-        android:drawableEnd="@mipmap/more_black"
-        android:text="@string/用户协议"
-        android:textColor="#ff333333"
-        android:textSize="14sp"
-        />
-
-    <include layout="@layout/include_line_14"/>
-
-
-    <TextView
-        android:id="@+id/tv_about_ys"
-        android:layout_width="match_parent"
-        android:layout_height="50dp"
-        android:gravity="center_vertical"
-        android:paddingStart="14dp"
-        android:background="@color/white"
-        android:paddingEnd="14dp"
-        android:drawableEnd="@mipmap/more_black"
-        android:text="@string/隐私协议"
-        android:textColor="#ff333333"
-        android:textSize="14sp"
-        />
-    <include layout="@layout/include_line_14"/>
-
-
-    <TextView
-        android:id="@+id/tv_about_me"
-        android:layout_width="match_parent"
-        android:layout_height="50dp"
-        android:gravity="center_vertical"
-        android:paddingStart="14dp"
-        android:background="@color/white"
-        android:paddingEnd="14dp"
-        android:drawableEnd="@mipmap/more_black"
-        android:text="@string/关于我们"
-        android:textColor="#ff333333"
-        android:textSize="14sp"
-        />
-
-    <include layout="@layout/include_line_14"/>
-
-
-    <LinearLayout
-        android:id="@+id/ll_clear"
-        android:layout_width="match_parent"
-        android:background="@color/white"
-        android:layout_height="50dp"
-        android:orientation="horizontal">
-
-        <TextView
-            android:layout_width="wrap_content"
-            android:layout_height="50dp"
-            android:gravity="center_vertical"
-            android:paddingStart="14dp"
-            android:background="@color/white"
-            android:paddingEnd="14dp"
-            android:text="@string/清除缓存"
-            android:textColor="#ff333333"
-            android:textSize="14sp"
-            />
-
-        <include layout="@layout/include_weight_width"/>
-
-        <TextView
-            android:id="@+id/tv_cache"
-            android:layout_width="wrap_content"
-            android:layout_height="50dp"
-            android:gravity="center_vertical"
-            android:paddingStart="14dp"
-            android:background="@color/white"
-            android:drawablePadding="@dimen/dp_10"
-            android:paddingEnd="14dp"
-            android:alpha="0.4"
-            android:text="61.7M"
-            android:textColor="#ff333333"
-            android:textSize="14sp"
-            />
-
-
-    </LinearLayout>
-
-    <include layout="@layout/include_line_14"/>
-
-
+    android:orientation="vertical">
 
     <LinearLayout
         android:layout_width="match_parent"
-        android:background="@color/white"
-        android:layout_height="50dp"
-        android:orientation="horizontal">
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
 
         <TextView
-            android:layout_width="wrap_content"
+            android:id="@+id/tv_more_langh"
+            android:layout_width="match_parent"
             android:layout_height="50dp"
+            android:background="@color/white"
+            android:drawableEnd="@mipmap/more_black"
             android:gravity="center_vertical"
             android:paddingStart="14dp"
-            android:background="@color/white"
             android:paddingEnd="14dp"
-            android:text="@string/当前版本"
+            android:text="@string/多语言"
             android:textColor="#ff333333"
-            android:textSize="14sp"
-            />
+            android:textSize="14sp" />
 
-        <include layout="@layout/include_weight_width"/>
+        <View
+            android:id="@+id/view_line_14"
+            android:layout_width="match_parent"
+            android:layout_height="14dp"
+            android:alpha="0.3"
+            android:background="#F3F4F5" />
 
         <TextView
-            android:id="@+id/tv_version_code"
-            android:layout_width="wrap_content"
+            android:id="@+id/tv_user_to"
+            android:layout_width="match_parent"
             android:layout_height="50dp"
+            android:background="@color/white"
+            android:drawableEnd="@mipmap/more_black"
             android:gravity="center_vertical"
             android:paddingStart="14dp"
-            android:background="@color/white"
-            android:drawablePadding="@dimen/dp_10"
             android:paddingEnd="14dp"
-            android:alpha="0.4"
-            android:text="V1.0"
+            android:text="@string/用户指南"
             android:textColor="#ff333333"
-            android:textSize="14sp"
-            />
+            android:textSize="14sp" />
 
+        <include layout="@layout/include_line_14" />
+
+        <TextView
+            android:id="@+id/tv_qa"
+            android:layout_width="match_parent"
+            android:layout_height="50dp"
+            android:background="@color/white"
+            android:drawableEnd="@mipmap/more_black"
+            android:gravity="center_vertical"
+            android:paddingStart="14dp"
+            android:paddingEnd="14dp"
+            android:text="@string/常见问题"
+            android:textColor="#ff333333"
+            android:textSize="14sp" />
+
+        <include layout="@layout/include_line_14" />
+
+        <TextView
+            android:id="@+id/tv_rule"
+            android:layout_width="match_parent"
+            android:layout_height="50dp"
+            android:background="@color/white"
+            android:drawableEnd="@mipmap/more_black"
+            android:gravity="center_vertical"
+            android:paddingStart="14dp"
+            android:paddingEnd="14dp"
+            android:text="@string/法律条款和平台规则"
+            android:textColor="#ff333333"
+            android:textSize="14sp" />
+
+        <include layout="@layout/include_line_14" />
+
+        <TextView
+            android:id="@+id/tv_yh"
+            android:layout_width="match_parent"
+            android:layout_height="50dp"
+            android:background="@color/white"
+            android:drawableEnd="@mipmap/more_black"
+            android:gravity="center_vertical"
+            android:paddingStart="14dp"
+            android:paddingEnd="14dp"
+            android:text="@string/用户协议"
+            android:textColor="#ff333333"
+            android:textSize="14sp" />
+
+        <include layout="@layout/include_line_14" />
+
+        <TextView
+            android:id="@+id/tv_about_ys"
+            android:layout_width="match_parent"
+            android:layout_height="50dp"
+            android:background="@color/white"
+            android:drawableEnd="@mipmap/more_black"
+            android:gravity="center_vertical"
+            android:paddingStart="14dp"
+            android:paddingEnd="14dp"
+            android:text="@string/隐私协议"
+            android:textColor="#ff333333"
+            android:textSize="14sp" />
+
+        <include layout="@layout/include_line_14" />
+
+        <TextView
+            android:id="@+id/tv_about_me"
+            android:layout_width="match_parent"
+            android:layout_height="50dp"
+            android:background="@color/white"
+            android:drawableEnd="@mipmap/more_black"
+            android:gravity="center_vertical"
+            android:paddingStart="14dp"
+            android:paddingEnd="14dp"
+            android:text="@string/关于我们"
+            android:textColor="#ff333333"
+            android:textSize="14sp" />
+
+        <include layout="@layout/include_line_14" />
+
+        <LinearLayout
+            android:id="@+id/ll_floating_window"
+            android:layout_width="match_parent"
+            android:layout_height="50dp"
+            android:background="@color/white"
+            android:orientation="horizontal"
+            android:paddingHorizontal="14dp">
+
+            <TextView
+                android:layout_width="0dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:gravity="center_vertical"
+                android:text="@string/开启悬浮窗"
+                android:textColor="#ff333333"
+                android:textSize="14sp" />
+
+            <com.google.android.material.switchmaterial.SwitchMaterial
+                android:id="@+id/sm_floating_window"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:checked="false"
+                android:clickable="false"
+                android:enabled="false"
+                android:focusable="false"
+                android:focusableInTouchMode="false"
+                app:thumbTint="@color/selector_switch_thumb_tint"
+                app:trackTint="@color/selector_switch_track_tint"
+                app:useMaterialThemeColors="false" />
+        </LinearLayout>
+
+        <include layout="@layout/include_line_14" />
+
+        <LinearLayout
+            android:id="@+id/ll_clear"
+            android:layout_width="match_parent"
+            android:layout_height="50dp"
+            android:background="@color/white"
+            android:orientation="horizontal">
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="50dp"
+                android:background="@color/white"
+                android:gravity="center_vertical"
+                android:paddingStart="14dp"
+                android:paddingEnd="14dp"
+                android:text="@string/清除缓存"
+                android:textColor="#ff333333"
+                android:textSize="14sp" />
+
+            <include layout="@layout/include_weight_width" />
+
+            <TextView
+                android:id="@+id/tv_cache"
+                android:layout_width="wrap_content"
+                android:layout_height="50dp"
+                android:alpha="0.4"
+                android:background="@color/white"
+                android:drawablePadding="@dimen/dp_10"
+                android:gravity="center_vertical"
+                android:paddingStart="14dp"
+                android:paddingEnd="14dp"
+                android:text="61.7M"
+                android:textColor="#ff333333"
+                android:textSize="14sp" />
+
+
+        </LinearLayout>
+
+        <include layout="@layout/include_line_14" />
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="50dp"
+            android:background="@color/white"
+            android:orientation="horizontal">
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="50dp"
+                android:background="@color/white"
+                android:gravity="center_vertical"
+                android:paddingStart="14dp"
+                android:paddingEnd="14dp"
+                android:text="@string/当前版本"
+                android:textColor="#ff333333"
+                android:textSize="14sp" />
+
+            <include layout="@layout/include_weight_width" />
+
+            <TextView
+                android:id="@+id/tv_version_code"
+                android:layout_width="wrap_content"
+                android:layout_height="50dp"
+                android:alpha="0.4"
+                android:background="@color/white"
+                android:drawablePadding="@dimen/dp_10"
+                android:gravity="center_vertical"
+                android:paddingStart="14dp"
+                android:paddingEnd="14dp"
+                android:text="V1.0"
+                android:textColor="#ff333333"
+                android:textSize="14sp" />
+
+
+        </LinearLayout>
+
+        <include layout="@layout/include_line_14" />
+
+        <TextView
+            android:id="@+id/ll_version"
+            android:layout_width="match_parent"
+            android:layout_height="50dp"
+            android:background="@color/white"
+            android:drawableEnd="@mipmap/more_black"
+            android:gravity="center_vertical"
+            android:paddingStart="14dp"
+            android:paddingEnd="14dp"
+            android:text="@string/版本更新"
+            android:textColor="#ff333333"
+            android:textSize="14sp" />
 
     </LinearLayout>
-
-    <include layout="@layout/include_line_14"/>
-
-
-
-    <TextView
-        android:id="@+id/ll_version"
-        android:layout_width="match_parent"
-        android:layout_height="50dp"
-        android:gravity="center_vertical"
-        android:paddingStart="14dp"
-        android:background="@color/white"
-        android:paddingEnd="14dp"
-        android:drawableEnd="@mipmap/more_black"
-        android:text="@string/版本更新"
-        android:textColor="#ff333333"
-        android:textSize="14sp"
-        />
-
-
-
-</LinearLayout>
\ No newline at end of file
+</ScrollView>
diff --git a/app/src/main/res/layout/fx_card.xml b/app/src/main/res/layout/fx_card.xml
new file mode 100644
index 0000000..3bcea7d
--- /dev/null
+++ b/app/src/main/res/layout/fx_card.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/fxCard"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    app:cardCornerRadius="10dp"
+    app:cardElevation="4dp">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="140dp"
+        android:layout_height="74dp"
+        android:background="@drawable/bg_login">
+
+        <ImageView
+            android:id="@+id/iv_logo"
+            android:layout_width="56dp"
+            android:layout_height="56dp"
+            android:layout_marginEnd="6dp"
+            android:src="@mipmap/ic_launcher"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <TextView
+            android:id="@+id/tv1"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="12dp"
+            android:layout_marginTop="14dp"
+            android:gravity="center"
+            android:text="@string/listen_order"
+            android:textColor="@color/white"
+            android:textSize="15sp"
+            android:textStyle="bold"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="4dp"
+            android:gravity="center"
+            android:text="@string/IGO打车"
+            android:textColor="@color/white"
+            android:textSize="12sp"
+            app:layout_constraintStart_toStartOf="@id/tv1"
+            app:layout_constraintTop_toBottomOf="@id/tv1" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</com.google.android.material.card.MaterialCardView>
diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml
index cc08a6d..a8efb62 100644
--- a/app/src/main/res/values-en/strings.xml
+++ b/app/src/main/res/values-en/strings.xml
@@ -631,6 +631,7 @@
     <string name="立即支付">PAY NOW</string>
     <string name="交货">Delivery</string>
     <string name="定位中">Positioning…</string>
+    <string name="正在后台持续获取位置">continuously obtaining location in the background</string>
     <string name="选择照片">Choose a photo</string>
     <string name="年">Year</string>
     <string name="月">Month</string>
@@ -672,8 +673,8 @@
     <string name="当前可更换车辆">Currently Replaceable Vehicles</string>
     <string name="等待用户支付差价">Waiting for the user to pay the difference</string>
     <string name="请输入4位号码">Please enter a 4-digit number</string>
-    <string name="分享错误" >Share error</string>
-    <string name="分享成功" >Share success</string>
+    <string name="分享错误">Share error</string>
+    <string name="分享成功">Share success</string>
     <string name="朋友圈">Moments</string>
     <string name="微信">WeChat</string>
     <string name="机动车行驶证号码">Roadworthiness sticker number</string>
@@ -725,7 +726,7 @@
     <string name="pay_often">Settlement cycle</string>
     <string name="请填写居住地址">Please enter your residential address</string>
     <string name="请选择保险到期日期">Please select an insurance expiration date</string>
-    <string name="too_far" >Far destination</string>
+    <string name="too_far">Far destination</string>
     <string name="too_busy">Traffic jam</string>
     <string name="no_rider">Rider did not show up</string>
     <string name="car_problom">"Vehicle problem "</string>
@@ -786,8 +787,8 @@
     <string name="争议订单协商价格">( Note: Disputed order, after tripartite negotiation, the final pricing of the platform is FCFA %s )</string>
     <string name="被冻结">The order has been blocked by GOPOST,  and GOPOST customer service will contact you</string>
     <string name="取消订单费用">Cancellation fee</string>
-    <string name="请求出错" >Request error</string>
-    <string name="定位权限说明" > GOPOST Driver requires location permission to:\n1. Check if service is available in your current district,\n2. Match and push nearby orders to you,\n3. Transmit your real-time location during trips to show passengers your current position.\n\nWe will upload your location data to our backend in real-time, both when the app is in the foreground and during active trips (even if briefly in the background), solely for the above core service purposes.\nIf you deny location authorization, you will not be able to receive orders or provide trip services normally.\nDo you confirm the authorization?</string>
+    <string name="请求出错">Request error</string>
+    <string name="定位权限说明">The GOPOST driver app requires location permission for the following purposes: \nchecking if service is available in your current area, \nmatching and pushing nearby orders to you, \nand transmitting your location in real-time during the trip so that passengers can view your current position. \nWe will upload your location data in real-time to the backend during the application trip (even in the background), solely for the aforementioned core service purposes. \nIf you refuse to authorize, you will not be able to receive orders or provide trip services normally. \nAre you sure you want to authorize?</string>
     <string name="拒绝权限">Deny</string>
     <string name="充值">Recharge</string>
     <string name="余额充值">Balance recharge</string>
@@ -831,5 +832,11 @@
     <string name="收款金额">Payment Amount</string>
     <string name="订单收款金额">Order payment amount</string>
     <string name="已经是最新版">当前已经是最新版本了</string>
+    <string name="悬浮窗说明">The GOPOST driver app requires permission to access the floating window feature, which allows you to quickly return to the app to receive orders or provide ride services</string>
+    <string name="开启悬浮窗">open the floating window</string>
+    <string name="请选择内容">please select content</string>
+    <string name="没有定位权限提示">Without positioning permission, you will not be able to receive new order push notifications</string>
+    <string name="手机号为空">the phone number is empty</string>
+    <string name="休息中">On break</string>
 
 </resources>
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 981aa2c..6c91463 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -637,6 +637,7 @@
     <string name="立即支付">Payez maintenant</string>
     <string name="交货">Livré</string>
     <string name="定位中">Penentuan posisi…</string>
+    <string name="正在后台持续获取位置">La localisation est en cours de récupération en arrière-plan</string>
     <string name="选择照片">CHOISISSEZ UNE PHOTO</string>
     <string name="年">L’an</string>
     <string name="月">Mois</string>
@@ -791,7 +792,7 @@
     <string name="被冻结">La commande a été bloquée par GOPOST,  et le service client d’GOPOST vous contactera</string>
     <string name="取消订单费用">Frais d\'annulation</string>
     <string name="请求出错" >Erreur de demande</string>
-    <string name="定位权限说明" >GOPOST Driver a besoin de l\'autorisation de localisation pour :\n1. Vérifier si le service est disponible dans votre quartier actuel,\n2. Vous correspondre et vous proposer des commandes à proximité,\n3. Transmettre votre position en temps réel pendant les trajets afin que les passagers puissent voir votre emplacement actuel.\n\nNous téléchargerons vos données de localisation sur notre serveur en temps réel, tant lorsque l\'application est en premier plan que pendant les trajets actifs (même brièvement en arrière-plan), uniquement pour les besoins des services de base mentionnés ci-dessus.\nSi vous refusez l\'autorisation de localisation, vous ne pourrez pas recevoir de commandes ni fournir de services de trajet normalement.\nConfirmez-vous l\'autorisation ?</string>
+    <string name="定位权限说明" >L\'application GOPOST pour conducteurs nécessite l\'autorisation d\'accéder à la localisation, à des fins de : \nVérifier si votre zone actuelle est couverte par nos services, \nVous attribuer et envoyer des commandes à proximité, \nTransmettre en temps réel votre position pendant le trajet pour que les passagers puissent voir votre localisation actuelle. \nNous transmettrons vos données de localisation en temps réel au serveur, même en arrière-plan, uniquement pour les services essentiels mentionnés ci-dessus. \nSi vous refusez l\'autorisation, vous ne pourrez pas recevoir normalement les commandes ou fournir les services de trajet. \nConfirmez-vous l\'autorisation ?</string>
     <string name="拒绝权限" >Refuser</string>
     <string name="充值">Recharge</string>
     <string name="余额充值">Recharge du solde</string>
@@ -835,5 +836,11 @@
     <string name="收款金额">Montant de recette</string>
     <string name="订单收款金额">Montant perçu de la commande</string>
     <string name="已经是最新版">Vous utilisez déjà la dernière version.</string>
+    <string name="悬浮窗说明">L\'application conducteur de GOPOST nécessite l\'autorisation de fenêtre flottante pour vous permettre de revenir rapidement à l\'application afin de recevoir des commandes ou de fournir des services de trajet</string>
+    <string name="开启悬浮窗">Activer la fenêtre flottante</string>
+    <string name="请选择内容">Veuillez sélectionner le contenu</string>
+    <string name="没有定位权限提示">Sans autorisation de localisation, vous ne pourrez pas recevoir les notifications push de nouvelles commandes.</string>
+    <string name="手机号为空">Le numéro de téléphone est vide.</string>
+    <string name="休息中">En pause</string>
 
 </resources>
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index e4d9da9..3ca7ad9 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -103,6 +103,7 @@
     <color name="color_F3F4F5">#99000000</color>
     <color name="color_f07207">#fff07207</color>
     <color name="blue_1">#0E7151</color>
+    <color name="blue_3">#800E7151</color>
     <color name="blue_2">#89BB28</color>
     <color name="color_EE6307">#F07207</color>
     <color name="color_5DB03D">#5DB03D</color>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 5333fd8..ddf9f79 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -613,6 +613,7 @@
     <string name="立即支付">立即支付</string>
     <string name="交货">交货</string>
     <string name="定位中">定位中…</string>
+    <string name="正在后台持续获取位置">正在后台持续获取位置</string>
     <string name="选择照片">选择照片</string>
     <string name="年">年</string>
     <string name="月">月</string>
@@ -777,7 +778,7 @@
     <string name="被冻结">此订单已被平台冻结,平台客服将会联系您</string>
     <string name="取消订单费用">取消订单费用</string>
     <string name="请求出错">请求出错</string>
-    <string name="定位权限说明"> GOPOST 司机端 需要获取位置权限,用于:\n检查你当前区域是否可提供服务,\n为你匹配并推送附近订单,\n在行程中实时传输你的位置,以便乘客查看你的当前位置。\n我们会在应用前台及行程中(即使短暂处于后台)将你的位置数据实时上传至后端,仅用于上述核心服务目的。\n若你拒绝位置授权,将无法正常接收订单或提供行程服务。\n是否确认授权?</string>
+    <string name="定位权限说明">GOPOST 司机端 需要获取位置权限,用于:\n检查你当前区域是否可提供服务,\n为你匹配并推送附近订单,\n在行程中实时传输你的位置,以便乘客查看你的当前位置。\n我们会在应用行程中(即使处于后台)将你的位置数据实时上传至后端,仅用于上述核心服务目的。\n若你拒绝授权,将无法正常接收订单或提供行程服务。\n是否确认授权?</string>
     <string name="拒绝权限">拒绝</string>
 
 
@@ -823,5 +824,11 @@
     <string name="收款金额">收款金额</string>
     <string name="订单收款金额">订单收款金额</string>
     <string name="已经是最新版">当前已经是最新版本了</string>
+    <string name="悬浮窗说明">GOPOST 司机端 需要获取悬浮窗权限,方便您快速回到应用接收订单或提供行程服务</string>
+    <string name="开启悬浮窗">开启悬浮窗</string>
+    <string name="请选择内容">请选择内容</string>
+    <string name="没有定位权限提示">如果没有定位权限,您将无法接收新的订单推送通知</string>
+    <string name="手机号为空">手机号为空</string>
+    <string name="休息中">休息中</string>
 
 </resources>
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 5701650..668ebc4 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -51,4 +51,5 @@
         <item name="android:layout_height">1px</item>
         <item name="android:layout_width">match_parent</item>
     </style>
+    <style name="Theme.FloatingX" parent="Theme.Material3.DayNight.NoActionBar" />
 </resources>
diff --git a/build.gradle b/build.gradle
index 000455d..d2c4cd7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -23,7 +23,7 @@
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:8.6.0'
-        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0"
+        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:2.2.21"
         classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1"
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
diff --git a/xldUtils/src/main/java/cn/sinata/xldutils/activitys/BaseActivity.java b/xldUtils/src/main/java/cn/sinata/xldutils/activitys/BaseActivity.java
index aaaabeb..abfa1a5 100644
--- a/xldUtils/src/main/java/cn/sinata/xldutils/activitys/BaseActivity.java
+++ b/xldUtils/src/main/java/cn/sinata/xldutils/activitys/BaseActivity.java
@@ -194,7 +194,7 @@
      */
     protected void closeAll() {
         Intent intent = new Intent(ACTION_CLOSE_ALL);
-        sendBroadcast(intent);
+        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
     }
 
     /**

--
Gitblit v1.7.1