18034727885
2026-03-18 7804ce8edeba51418b5fde2d306e5f476dfb5993
合并最新代码
25个文件已添加
39个文件已修改
2832 ■■■■■ 已修改文件
app/src/main/AndroidManifest.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/assets/rce.html 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/base/BaseRvAdapter.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/base/MyApplication.kt 299 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/base/test/TestAdapter.kt 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/bean/AreaCode.kt 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/bean/CardListBean.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/bean/CloseRecordBean.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/bean/WaveBean.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/netUtls/Api.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/netUtls/LoggingInterceptor.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/ui/adapter/CardListAdapter.kt 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/ui/card/CardListActivity.kt 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/ui/card/CardListFragment.kt 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/ui/main/ChangPhoneActivity.kt 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/ui/main/MainActivity.kt 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/ui/main/TripActivity.kt 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/ui/main/major/MajorSureMoney2Activity.kt 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/ui/main/small_cargo/SmallCargoActivity.kt 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/ui/mine/AcountSafeActivity.kt 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/ui/mine/ChangeEmailActivity.kt 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/ui/mine/ChangePhoneOneActivity.kt 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/ui/mine/MineActivity.kt 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/ui/mine/SafeVerifyActivity.kt 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/ui/mine/money_bag/ApplyMoneyActivity.kt 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/ui/pub/AreaCodeActivity.kt 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/ui/pub/AreaCodeAdapter.kt 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/ui/pub/BecomeDriverActivity.kt 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/ui/pub/ForgetPwdActivity.kt 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/ui/pub/LoginActivity.kt 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/ui/wave/WaveAccountActivity.kt 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/ui/wave/WaveSetActivity.kt 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/utils/UtilKt.kt 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/utils/citypickerview/CityPickerView.java 414 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/utils/recaptcha/RecaptchaJavascriptChannel.kt 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/utils/recaptcha/RecaptchaListener.kt 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/utils/recaptcha/RecaptchaVisual.kt 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/utils/recaptcha/RecaptchaVisualException.kt 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/utils/recaptcha/RecaptchaVisualFragment.kt 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/driver/igotrip/utils/recaptcha/RecaptchaWebView.kt 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/shape_333_line_8.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/activity_apply_money.xml 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/activity_area_code.xml 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/activity_become_driver.xml 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/activity_changphone.xml 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/activity_order_cancel.xml 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/activity_wave_account.xml 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/activity_wave_set.xml 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/include_login_phone.xml 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/include_order_top_cargo.xml 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/item_area_code.xml 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/item_citylist.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/pop_citypicker.xml 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/recaptcha.xml 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/mipmap-xxhdpi/ic_search.png 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/values-en/strings.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/values-fr/strings.xml 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/values/strings.xml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rxnetty/build.gradle 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rxnetty/src/main/java/cn/sinata/rxnetty/CoreService.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rxnetty/src/main/java/cn/sinata/rxnetty/LogHelper.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rxnetty/src/main/java/cn/sinata/rxnetty/NJobService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rxnetty/src/main/java/cn/sinata/rxnetty/NettyClient.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rxnetty/src/main/java/cn/sinata/rxnetty/OnCheckListener.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/AndroidManifest.xml
@@ -104,6 +104,9 @@
        <activity
            android:name=".ui.pub.LoginActivity"
            android:launchMode="singleTask" />
        <activity
            android:name=".ui.pub.AreaCodeActivity"
            android:launchMode="singleTask" />
        <activity android:name=".ui.pub.ForgetPwdActivity" />
        <activity android:name=".ui.main.MainActivity" />
        <activity android:name=".ui.mine.MineActivity" />
@@ -126,6 +129,8 @@
        <activity android:name=".ui.mine.SettingLoginPwdActivity" />
        <activity android:name=".ui.mine.FeedbackRemarkActivity" />
        <activity android:name=".ui.card.CardListActivity" />
        <activity android:name=".ui.wave.WaveSetActivity" />
        <activity android:name=".ui.wave.WaveAccountActivity" />
        <activity android:name=".ui.mine.OrderSettingActivity" />
        <activity android:name=".ui.mine.ChangeCarActivity" />
        <activity
app/src/main/assets/rce.html
New file
@@ -0,0 +1,77 @@
<html>
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <head>
    <title>reCAPTCHA</title>
    <style>
      @keyframes lf-loading-spinner {
        0% {
          transform: rotate(0deg);
        }
        100% {
          transform: rotate(360deg);
        }
      }
      .lf-loading-spinner {
        animation: lf-loading-spinner 1250ms infinite linear;
        border: 4px solid #4285f4;
        border-radius: 32px;
        border-right-color: transparent;
        border-top-color: transparent;
        box-sizing: border-box;
        height: 64px;
        width: 64px;
      }
    </style>
    <style>
      html,
      body,
      .container {
        height: 100%;
        width: 100%;
        margin: 0;
        padding: 0;
        background-color: transparent;
      }
      .container {
        display: flex;
        justify-content: center;
        align-items: center;
      }
    </style>
    <script
      src="https://www.google.com/recaptcha/api.js?onload=onLoad&render=explicit__LANG__"
      async
      defer
    ></script>
    <script type="text/javascript">
      let isReadyTimer;
      const onVerify = (token) => {
        __JS_OBJECT_NAME__.onVerify(token);
      };
      const onError = (error) => {
        __JS_OBJECT_NAME__.onError(error);
      };
      const onExpire = () => {
        __JS_OBJECT_NAME__.onExpire();
      };
      var onLoad = () => {
        document.getElementById("spinner").style.display='none';
        const recaptchaParams = {
          "sitekey": "__SITE_KEY__",
          "action": "send_captcha",
          "callback": onVerify,
          "error-callback": onError,
          "expired-callback": onExpire,
        };
        window.grecaptcha.render("recaptcha-container", recaptchaParams);
        __JS_OBJECT_NAME__.onLoad();
      };
    </script>
  </head>
  <body>
    <div class="container">
      <div id="spinner" class="lf-loading-spinner"></div>
      <span id="recaptcha-container"></span>
    </div>
  </body>
</html>
app/src/main/java/com/driver/igotrip/base/BaseRvAdapter.java
@@ -1,5 +1,6 @@
package com.driver.igotrip.base;
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
@@ -39,6 +40,12 @@
        this(null, null);
    }
    @SuppressLint("NotifyDataSetChanged")
    public void setData(List<DataEntity> data) {
        this.data = data;
        this.notifyDataSetChanged();
    }
    public String getStr(int id){
        return context.getString(id);
    }
app/src/main/java/com/driver/igotrip/base/MyApplication.kt
@@ -1,6 +1,5 @@
package com.driver.igotrip.base
import android.R.id.message
import android.annotation.SuppressLint
import android.app.Activity
import android.app.Application
@@ -8,31 +7,29 @@
import android.content.Intent
import android.os.*
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import cn.jpush.android.api.JPushInterface
import cn.jpush.android.api.TagAliasCallback
import cn.sinata.rxnetty.LogHelper.initLogs
import cn.sinata.rxnetty.LogHelper.logRecord
import cn.sinata.rxnetty.NettyClient
import cn.sinata.xldutils.BaseApplication
import cn.sinata.xldutils.utils.SPUtils
import cn.sinata.xldutils.utils.sysErr
import com.driver.igotrip.BuildConfig
import com.driver.igotrip.R
import com.driver.igotrip.base.BaseEvent.REFREASH_ORDERLIST
import com.driver.igotrip.bean.OrderBean
import com.driver.igotrip.bean.OrderResData
import com.driver.igotrip.bean.OrderSimpleData
import com.driver.igotrip.bean.websocket.HeartBean
import com.driver.igotrip.netUtls.*
import com.driver.igotrip.netUtls.Api.getDriverOrderMessage
import com.driver.igotrip.ui.main.TripActivity
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.DES
import com.driver.igotrip.utils.LanguageManager
import com.driver.igotrip.utils.LanguageUtil
import com.driver.igotrip.utils.LogUtils
import com.google.android.gms.maps.model.LatLng
import com.google.cloud.texttospeech.v1.*
@@ -41,11 +38,7 @@
import com.tencent.bugly.crashreport.CrashReport
import com.umeng.commonsdk.UMConfigure
import com.umeng.socialize.PlatformConfig
import com.umeng.socialize.utils.DeviceConfigInternal.context
import com.xuexiang.xui.XUI
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import org.jetbrains.anko.startActivity
import org.jetbrains.anko.toast
@@ -74,7 +67,6 @@
        return "MyApplication"
    }
    @RequiresApi(api = Build.VERSION_CODES.DONUT)
    override fun onCreate() {
        super.onCreate()
        appContext = this
@@ -94,6 +86,7 @@
        PlatformConfig.setQQZone("1111276329", "JuAotVjQcUiesxgp") //qq互联
        CrashReport.initCrashReport(this, "163c95c374", true);
        LogUtils.OpenLog(true)
        initLogs()
        initSocket()
        JPushInterface.setDebugMode(true)
        JPushInterface.init(this)
@@ -103,7 +96,7 @@
    override fun attachBaseContext(base: Context?) {
        var language = SPUtils.getString("language")
       // super.attachBaseContext(LanguageUtil.changeAppLanguage(base, language, ""))
        // super.attachBaseContext(LanguageUtil.changeAppLanguage(base, language, ""))
        super.attachBaseContext(LanguageManager.wrapContext(base))
    }
@@ -212,53 +205,48 @@
        }
    private fun initSocket() {
        Log.e("sendLocation: ","开始链接" )
        Log.e("sendLocation: ", "开始链接")
        NettyClient.getInstance().init(this, Api.SOCKET_SERVER, Api.SOCKET_PORT, true)
        NettyClient.getInstance()
            .addOnMessageListener { message: String ->
                initnetdata(message)
            }
        NettyClient.getInstance()
            .setOnConnectListener {
                sendHeart()
            }
     if(frist){
        /* MainScope().launch {
             while (true){
                 delay(5000)
                 var map = getMapByAny()
                 if (getDriverOrderMessage.startsWith("api")) {
                     map["appid"] = getAppId()
                     var sign = DES.getSign(map)
                     map["sign"] = sign
                 }
                 HttpManager.getInstance().post(getDriverOrderMessage, map, object : MyNoMsgObserver(this@MyApplication) {
                     override fun success(responseString: String?) {
                         Log.e("长连接接口消息: ",responseString.toString() )
                         initnetdata(responseString.toString())
        NettyClient.getInstance().addOnMessageListener { message: String ->
            initnetdata(message)
        }
        NettyClient.getInstance().setOnConnectListener {
            sendHeart()
        }
        if (frist) {
            /* MainScope().launch {
                 while (true){
                     delay(5000)
                     var map = getMapByAny()
                     if (getDriverOrderMessage.startsWith("api")) {
                         map["appid"] = getAppId()
                         var sign = DES.getSign(map)
                         map["sign"] = sign
                     }
                 })
             }
         }*/
         frist=false
     }
                     HttpManager.getInstance().post(getDriverOrderMessage, map, object : MyNoMsgObserver(this@MyApplication) {
                         override fun success(responseString: String?) {
                             Log.e("长连接接口消息: ",responseString.toString() )
                             initnetdata(responseString.toString())
                         }
                     })
                 }
             }*/
            frist = false
        }
    }
    fun initnetdata(message:String,isnet: Boolean?=false){
    fun initnetdata(message: String, isnet: Boolean? = false) {
        try {
            Log.e("socket_message_by", message)
            Log.d("zmc-stock", message)
//                    sysErr("收到websocket消息")
            if (!isLogin&&isnet==false) {
            if (!isLogin && isnet == false) {
                return
            }
            currentTime = System.currentTimeMillis()
            val json = JSONObject(message)
            val method = json.optString("method")
            Handler(Looper.getMainLooper()).post {
                //                        ToastUtils.showShortToast(this, "收到websocket=$method")
            if (method != "OK") {
                Log.d("zmc-socket", message)
            }
            val data = json.optString("data")
            val code = json.optInt("code", -1)
@@ -279,7 +267,7 @@
                        CacheKey.putKeyStr("isAgreen", "1")
                        NettyClient.getInstance().stopService()
                        isLogin = false
                        var intent = Intent()
                        val intent = Intent()
                        intent.setClass(this, LoginActivity::class.java)
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                        startActivity(intent)
@@ -294,7 +282,10 @@
                            )
                        EventBus.getDefault().post(BaseEvent(BaseEvent.FORCED_OFFLINE))
                        val act = activities[activities.size - 1]
                        (act as PublicServiceActivity).forceOffline(simpleData.audioUrl, simpleData.msg)
                        (act as PublicServiceActivity).forceOffline(
                            simpleData.audioUrl,
                            simpleData.msg
                        )
                        if (act is PublicServiceDialogActivity) act.finish()
                    }
@@ -354,9 +345,14 @@
                                    )
                                    if (act is PublicServiceDialogActivity) act.finish()
                                }
                                4,5->{
                                    act?.startActivity<SmallCargoActivity>("orderId" to orderSimpleData.orderId.toString(), "orderType" to orderSimpleData.orderType.toString())
                                4, 5 -> {
                                    act?.startActivity<SmallCargoActivity>(
                                        "orderId" to orderSimpleData.orderId.toString(),
                                        "orderType" to orderSimpleData.orderType.toString()
                                    )
                                }
                                3 -> {
                                }
@@ -397,32 +393,43 @@
                    }
                    Const.SOCKET_METHOD.REASSIGN -> {
                        Log.e(
                            "zmc-socket",
                            "EventBus.getDefault().post(BaseEvent(BaseEvent.REFREASH_MAIN))"
                        )
                        EventBus.getDefault().post(BaseEvent(BaseEvent.REFREASH_MAIN))
                        val orderSimpleData =
                            Gson().fromJson(
                                data,
                                OrderResData::class.java
                            )
                        val act = activities[activities.size - 1]
                        when (orderSimpleData.orderType) {
//                                    1, 2, 4 -> {
//                                        (act as PublicServiceActivity).showOrder(
//                                            orderSimpleData.audioUrl,
//                                            orderSimpleData.orderId.toString(),
//                                            orderSimpleData.orderType.toString(),
//                                            30,
//                                            2
//                                        )
//                                        if (act is PublicServiceDialogActivity) act.finish()
//                                    }
                            4,5->{
                                act?.startActivity<SmallCargoActivity>("orderId" to orderSimpleData.orderId.toString(), "orderType" to orderSimpleData.orderType.toString())
                            }
                            else->{
                                act?.startActivity<TripActivity>("orderId" to orderSimpleData.orderId.toString(), "orderType" to orderSimpleData.orderType.toString())
                            }
                        }
//                        val orderSimpleData =
//                            Gson().fromJson(
//                                data,
//                                OrderResData::class.java
//                            )
//                        val act = activities[activities.size - 1]
//                        when (orderSimpleData.orderType) {
////                                    1, 2, 4 -> {
////                                        (act as PublicServiceActivity).showOrder(
////                                            orderSimpleData.audioUrl,
////                                            orderSimpleData.orderId.toString(),
////                                            orderSimpleData.orderType.toString(),
////                                            30,
////                                            2
////                                        )
////                                        if (act is PublicServiceDialogActivity) act.finish()
////                                    }
//                            4, 5 -> {
//                                act?.startActivity<SmallCargoActivity>(
//                                    "orderId" to orderSimpleData.orderId.toString(),
//                                    "orderType" to orderSimpleData.orderType.toString()
//                                )
//                            }
//
//                            else -> {
//                                act?.startActivity<TripActivity>(
//                                    "orderId" to orderSimpleData.orderId.toString(),
//                                    "orderType" to orderSimpleData.orderType.toString()
//                                )
//                            }
//                        }
                    }
@@ -509,62 +516,76 @@
        }
    }
    private fun getOrderWhenNoSocket(){
        Log.e("sendLocation: ", "定时获取司机订单数据" + (getUserId() != -1).toString())
        if (getUserId() != -1) {
            val map = getMapByAny()
            callNet1(this, Api.getDriverOrderMessage, map, clickAction = {
                logRecord(TAG, "getOrderWhenNoSocket 获取订单成功 $it")
                initnetdata(it ?: "")
            }, {
                logRecord(TAG, "getOrderWhenNoSocket 获取订单失败")
            }, false)
        }
    }
    private fun sendLocation() {
        Log.e("sendLocation: ","发送定位"+(getUserId() != -1).toString() )
        Log.e("sendLocation: ","发送定位"+(aMapLocation != null).toString() )
        Log.e("sendLocation: ", "发送定位 userId = ${getUserId()}, aMapLocation = ${Gson().toJson(aMapLocation)}")
        if (getUserId() != -1 && aMapLocation != null) {
//            val bean = CarLocationBean()
//            val dataBean = CarLocationBean.DataBean(
//                getUserId(),
//                currentOrderId,
//                currentOrderType,
//                aMapLocation!!.longitude,
//                aMapLocation!!.latitude,
//                0.0,
//                0.0
//            )
//            bean.data = dataBean
//            NettyClient.getInstance()
//                .sendMessage(Gson().toJson(bean))
//            sysErr(dataBean.toString())
            val map = getMapByAny()
            map["orderId"] = currentOrderId
            map["orderType"] = currentOrderType
            map["driverId"] = getUserId()
            map["lon"] = aMapLocation!!.longitude
            map["lat"] = aMapLocation!!.latitude
            Log.e("sendLocation: ","发送定位参数"+Gson().toJson(map) )
            callNet1(this, Api.saveOrderPosition, map,clickAction={
            },{
                Log.e("sendLocation: ","发送定位成功" )
            },false)
            logRecord(TAG, "sendLocation 发送定位参数" + Gson().toJson(map))
            callNet1(this, Api.saveOrderPosition, map, clickAction = {
                logRecord(TAG, "sendLocation 发送定位成功")
            }, {
                logRecord(TAG, "sendLocation 发送定位失败")
            }, false)
            val map1 = getMapByAny()
            map1["orderId"] = currentOrderId
            map1["orderType"] = currentOrderType
            map1["driverId"] = getUserId()
            map1["lon"] = aMapLocation!!.longitude
            map1["lat"] = aMapLocation!!.latitude
            map1["altitude"] = 0
            map1["directionAngle"] = 0
            callNet1(this, Api.positionSocket, map1, clickAction = {
                logRecord(TAG, "positionSocket 发送定位成功")
            }, {
                logRecord(TAG, "positionSocket 发送定位失败")
            }, false)
        }
    }
    val TAG = "MyApplication"
    private fun sendHeart() {
        Log.e("sendLocation: ","sendHeart" )
        if (getUserId() != -1) {
            Log.i(TAG, "sendHeart: userId === " + getUserId())
            logRecord(TAG, "sendHeart: userId = " + getUserId())
            val bean = HeartBean()
            bean.data = HeartBean.DataBean()
            NettyClient.getInstance()
                .sendMessage(Gson().toJson(bean))
            NettyClient.getInstance().sendMessage(Gson().toJson(bean))
            sendLocation()
            if (heartHandler == null) {
                heartHandler = Handler(mainLooper)
            }
            heartHandler!!.removeCallbacksAndMessages(null)
            testHeartNunm++
            if ((System.currentTimeMillis() - currentTime) / 1000 > 30) {
                sysErr("sendHeart_websocket 重新连接")
                currentTime = System.currentTimeMillis()
                NettyClient.getInstance().checkNettyState()
            } else {
                sysErr("sendHeart_websocket 发送心跳")
//            if ((System.currentTimeMillis() - currentTime) / 1000 > 3) {
            // sysErr("sendHeart_websocket 重新连接")
            logRecord(TAG, "sendHeart check socket status")
            currentTime = System.currentTimeMillis()
            val nettyState = NettyClient.getInstance().checkNettyState()
            if (!nettyState) {
                getOrderWhenNoSocket()
            }
//            } else {
//                sysErr("sendHeart_websocket 发送心跳")
//            }
        }
        heartHandler!!.postDelayed({ sendHeart() }, 5000)
    }
@@ -575,7 +596,7 @@
    companion object {
        var frist=true
        var frist = true
        private const val TAG = "MyApplication"
        public var appContext: MyApplication? = null
        var mTtsManager: AudioRecoderUtils? = null
@@ -687,7 +708,7 @@
        }
    }
     val activities = ArrayList<Activity?>()
    val activities = ArrayList<Activity?>()
    private var showNum = 0
    fun finishAll() {
@@ -705,36 +726,45 @@
        return act
    }
    override fun onActivityPaused(activity: Activity) {
        if (BuildConfig.DEBUG)
            Log.e("zmc-App", "onActivityPaused: " + activity?.javaClass?.name)
    }
    override fun onActivityResumed(activity: Activity) {
        if (BuildConfig.DEBUG)
            Log.i("zmc-App", "onActivityResumed: " + activity?.javaClass?.name)
    override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
        activities.add(activity)
        Log.i("zmc-pageA", "onActivityCreated: " + activity.javaClass.name)
        if (activity is MyBaseActivity) {
            activity.supportFragmentManager.registerFragmentLifecycleCallbacks(object :
                FragmentManager.FragmentLifecycleCallbacks() {
                override fun onFragmentCreated(
                    fm: FragmentManager,
                    f: Fragment,
                    savedInstanceState: Bundle?
                ) {
                    super.onFragmentCreated(fm, f, savedInstanceState)
                    Log.i("zmc-pageF", "onFragmentCreated: " + f.javaClass.name)
                }
                override fun onFragmentDestroyed(fm: FragmentManager, f: Fragment) {
                    super.onFragmentDestroyed(fm, f)
                    Log.e("zmc-pageF", "onFragmentDestroyed: " + f.javaClass.name)
                }
            }, true)
        }
    }
    override fun onActivityStarted(activity: Activity) {
        showNum++
        if (BuildConfig.DEBUG)
            Log.d("zmc-App", "onActivityStarted: " + activity?.javaClass?.name)
        Log.d("zmc-pageA", "onActivityStarted: " + activity.javaClass.name)
    }
    override fun onActivityDestroyed(activity: Activity) {
        if (BuildConfig.DEBUG)
            Log.d("zmc-App", "onActivityDestroyed: " + activity?.javaClass?.name)
        activities.remove(activity)
    override fun onActivityResumed(activity: Activity) {
//        Log.i("zmc-pageA", "onActivityResumed: " + activity.javaClass.name)
    }
    override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
        if (BuildConfig.DEBUG)
            Log.d("zmc-App", "onActivitySaveInstanceState: " + activity?.javaClass?.name)
    override fun onActivityPaused(activity: Activity) {
//        Log.e("zmc-pageA", "onActivityPaused: " + activity.javaClass.name)
    }
    override fun onActivityStopped(activity: Activity) {
        if (BuildConfig.DEBUG)
            Log.e("zmc-App", "onActivityStopped: " + activity?.javaClass?.name)
        Log.e("zmc-pageA", "onActivityStopped: " + activity.javaClass.name)
        showNum--
        Handler(Looper.getMainLooper()).postDelayed({
            if (showNum == 0 && isPlayVoice) {
@@ -745,14 +775,15 @@
            }
            isPlayVoice = true
        }, 600)
    }
    override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
        activities.add(activity)
        if (BuildConfig.DEBUG)
            Log.i("zmc-App", "onActivityCreated: " + activity?.javaClass?.name)
    override fun onActivityDestroyed(activity: Activity) {
        Log.d("zmc-pageA", "onActivityDestroyed: " + activity.javaClass.name)
        activities.remove(activity)
    }
    override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
//        Log.d("zmc-pageA", "onActivitySaveInstanceState: " + activity.javaClass.name)
    }
}
app/src/main/java/com/driver/igotrip/base/test/TestAdapter.kt
New file
@@ -0,0 +1,23 @@
package com.driver.igotrip.base.test
import android.view.View
import com.driver.igotrip.R
import com.driver.igotrip.base.BaseRvAdapter
import com.driver.igotrip.base.BaseViewHolder
import com.driver.igotrip.bean.UserInfoBean
class TestAdapter: BaseRvAdapter<UserInfoBean>() {
    override fun getLayoutResId(viewType: Int): Int {
        return R.layout.item_citylist
    }
    override fun onBindItem(holder: BaseViewHolder?, view: View?, item: UserInfoBean?) {
        holder?.let {
        }
    }
    override fun getDataItemCount(): Int {
        return 10
    }
}
app/src/main/java/com/driver/igotrip/bean/AreaCode.kt
New file
@@ -0,0 +1,7 @@
package com.driver.igotrip.bean
data class AreaCode(
    var abbreviation: String? = null,
    var name: String? = null,
    var code: String? = null
)
app/src/main/java/com/driver/igotrip/bean/CardListBean.java
@@ -3,8 +3,7 @@
import java.io.Serializable;
import java.util.List;
public class CardListBean
{
public class CardListBean {
    private int code;
    private String msg;
    private List<DataBean> data;
app/src/main/java/com/driver/igotrip/bean/CloseRecordBean.java
@@ -129,31 +129,27 @@
        }
        public String getStateStr(Context ctx) {
            int nas = 0;
            if (state == 1){
                nas = R.string.处理中;
                return ctx.getString(R.string.处理中);
            } else if (state == 2){
                return ctx.getString(R.string.已提现);
            } else if (state == 3){
                return ctx.getString(R.string.提现失败);
            } else {
                return "";
            }
            if (state == 2){
                nas = R.string.已提现;
            }
            if (state == 3){
                nas =  R.string.提现失败;
            }
            return ctx.getString(nas);
        }
        public int getCorlor(Context ctx) {
            int nas = 0;
            if (state == 1){
                nas = R.color.color_2378D2;
                return ctx.getResources().getColor(R.color.color_2378D2);
            } else if (state == 2){
                return ctx.getResources().getColor(R.color.color_5DB03D);
            } else if (state == 3){
                return ctx.getResources().getColor(R.color.color_F35646);
            } else {
                return ctx.getResources().getColor(R.color.black);
            }
            if (state == 2){
                nas = R.color.color_5DB03D;
            }
            if (state == 3){
                nas =  R.color.color_F35646;
            }
            return ctx.getResources().getColor(nas);
        }
    }
}
app/src/main/java/com/driver/igotrip/bean/WaveBean.java
New file
@@ -0,0 +1,58 @@
package com.driver.igotrip.bean;
import java.io.Serializable;
public class WaveBean {
    private int code;
    private DataBean data;
    private String msg;
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public DataBean getData() {
        return data;
    }
    public void setData(DataBean data) {
        this.data = data;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public static class DataBean implements Serializable {
        private String name;
        private String phone;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getPhone() {
            return phone;
        }
        public void setPhone(String phone) {
            this.phone = phone;
        }
    }
}
app/src/main/java/com/driver/igotrip/netUtls/Api.java
@@ -53,6 +53,8 @@
    public static String needToSettle = "api/settlementRecord/needToSettle"; //判断司机是否需要结算费用
    public static String textToSpeech = "api/driver/textToSpeech";
    public static String saveOrderPosition = "api/order/saveOrderPosition";
    public static String positionSocket = "api/netty/positionSocket"; // 司机端主动调用该接口上传位置信息
    public static String getDriverOrderMessage = "api/order/getDriverOrderMessage"; // 司机定时任务获取订单相关socket消息【1.0】
    /***
     * 订单中
@@ -101,6 +103,7 @@
    public static String updatePhone1 = "api/driver/updatePhone1"; //api/driver/updatePhone1 修改手机号码
    public static String updatePassword = "api/driver/updatePassword"; //api/driver/updatePassword 修改密码
    public static String withdrawal = "api/withdrawal/withdrawal"; //api/withdrawal/withdrawal 账户余额提现
    public static String withdrawal1 = "api/withdrawal/withdrawal1"; //账户余额提现【1.0】
    public static String queryActivityIncome = "api/driver/queryActivityIncome"; //api/driver/queryActivityIncome 获取收益明细 (我的奖励)
    public static String queryWithdrawal = "api/withdrawal/queryWithdrawal"; //api/withdrawal/queryWithdrawal 获取历史提现数据
    public static String queryBalanceUsageRecord = "api/driver/queryBalanceUsageRecord"; // 获取使用记录
@@ -126,6 +129,10 @@
    public static String queryBankCard = "api/bankCard/queryBankCard"; ///api/bankCard/queryBankCard 获取银行卡号列表
    public static String delBankCard = "api/bankCard/delBankCard"; ///api/bankCard/delBankCard删除银行卡信心
    public static String saveBankCard = "api/bankCard/saveBankCard"; //api/bankCard/saveBankCard 保存银行卡信息
    public static String getWave = "api/driver/getWave"; //获取WAVE账户【1.0】
    public static String saveWave = "api/driver/saveWave"; //保存WAVE账户【1.0】
    public static String updateBankCard = "api/bankCard/updateBankCard"; ///api/bankCard/updateBankCard 保存银行卡信息
    public static String verificationPassword = "api/driver/verificationPassword"; ///api/driver/verificationPassword 验证登录密码是否有效
@@ -155,7 +162,6 @@
    public static String rechargeBalance = "api/driver/rechargeBalance"; //余额充值【1.0】
    public static String getDriverOrderMessage = "api/order/getDriverOrderMessage"; //司机定时任务获取订单相关socket消息【1.0】
    public static String completeOrder ="api/order/completeOrder";//手动确认订单完成
    public static String companyList ="base/driver/companyList";//获取运营公司列表
app/src/main/java/com/driver/igotrip/netUtls/LoggingInterceptor.java
@@ -96,7 +96,7 @@
    boolean isFilePart(MediaType mediaType) {
        if (mediaType != null) {
            String type = mediaType.toString();
            return type.startsWith("audio/") || type.startsWith("text/plain");
            return type.startsWith("audio/") || type.startsWith("text/plain") || type.startsWith("multipart/form-data");
        }
        return false;
    }
app/src/main/java/com/driver/igotrip/ui/adapter/CardListAdapter.kt
@@ -13,7 +13,10 @@
import com.driver.igotrip.ui.DialogUtil
import org.jetbrains.anko.find
class CardListAdapter:BaseRvAdapter<CardListBean.DataBean>() {
class CardListAdapter : BaseRvAdapter<CardListBean.DataBean>() {
    var itemClick: ((CardListBean.DataBean) -> Unit)? = null
    override fun getLayoutResId(viewType: Int): Int {
        return R.layout.item_card_list
    }
@@ -23,17 +26,25 @@
            it.itemView.find<TextView>(R.id.tv_name).text = item!!.bank
            it.itemView.find<TextView>(R.id.tv_num).text = item.code.hideBankNum()
            it.itemView.find<View>(R.id.cl_root).setOnLongClickListener {
                DialogUtil.getDelAndSureDialog(context, context.getString(R.string.delete_this_card), {}, {
                    var map = getMapByAny()
                    map["id"] = item.id
                    callNet(context, Api.delBankCard,map){
                        data.remove(item)
                        notifyDataSetChanged()
                        toast(context.getString(R.string.successfully_delete))
                    }
                })
                DialogUtil.getDelAndSureDialog(
                    context,
                    context.getString(R.string.delete_this_card),
                    {},
                    {
                        var map = getMapByAny()
                        map["id"] = item.id
                        callNet(context, Api.delBankCard, map) {
                            data.remove(item)
                            notifyDataSetChanged()
                            toast(context.getString(R.string.successfully_delete))
                        }
                    })
                return@setOnLongClickListener false
            }
            it.itemView.find<View>(R.id.cl_root).setOnClickListener {
                itemClick?.invoke(item)
            }
        }
    }
}
app/src/main/java/com/driver/igotrip/ui/card/CardListActivity.kt
@@ -1,17 +1,23 @@
package com.driver.igotrip.ui.card
import android.content.Intent
import android.widget.TextView
import cn.sinata.xldutils.utils.clickDelay
import com.driver.igotrip.R
import com.driver.igotrip.base.MyBaseActivity
import com.driver.igotrip.ui.adapter.CardListAdapter
import org.jetbrains.anko.find
import org.jetbrains.anko.startActivity
class CardListActivity :MyBaseActivity(){
class CardListActivity : MyBaseActivity() {
    var needBack = false // 是否需要返回值
    val carListFragment by lazy {
        CardListFragment()
        CardListFragment(adapter)
    }
    val adapter by lazy { CardListAdapter() }
    override fun setContentView() {
        setContentView(R.layout.activity_list_card)
@@ -20,7 +26,16 @@
    override fun initView() {
        setTitleText(getString(R.string.银行卡))
        find<TextView>(R.id.tv_sure).text = "+${getString(R.string.添加银行卡)}"
        addFragment(carListFragment,R.id.fl_container)
        addFragment(carListFragment, R.id.fl_container)
        needBack = intent?.getBooleanExtra("needBack", false) ?: false
        if(needBack){
            adapter.itemClick = {
                val intent = Intent().apply { putExtra("data",it) }
                setResult(RESULT_OK, intent)
                finish()
            }
        }
    }
    override fun setOnclick() {
app/src/main/java/com/driver/igotrip/ui/card/CardListFragment.kt
@@ -8,7 +8,7 @@
import com.driver.igotrip.ui.adapter.CardListAdapter
import java.util.HashMap
class CardListFragment: BaseRecyclerFragment<CardListBean.DataBean>(CardListAdapter()) {
class CardListFragment(adapter: CardListAdapter): BaseRecyclerFragment<CardListBean.DataBean>(adapter) {
    override fun pathUrl(): String? {
        return Api.queryBankCard
    }
app/src/main/java/com/driver/igotrip/ui/main/ChangPhoneActivity.kt
@@ -2,6 +2,7 @@
import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Intent
import android.os.Bundle
@@ -18,11 +19,13 @@
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import androidx.lifecycle.lifecycleScope
import cn.sinata.rxnetty.NettyClient
import cn.sinata.xldutils.utils.SPUtils
import cn.sinata.xldutils.utils.Utils
import cn.sinata.xldutils.utils.clickDelay
import cn.sinata.xldutils.utils.doubleOne
import cn.sinata.xldutils.utils.getAreaCode
import cn.sinata.xldutils.utils.getContent
import cn.sinata.xldutils.utils.gone
import cn.sinata.xldutils.utils.setDrawableLeft
@@ -53,6 +56,9 @@
import com.driver.igotrip.ui.mine.MineActivity
import com.driver.igotrip.ui.mine.MsgActivity
import com.driver.igotrip.ui.mine.OfflinePayActivity
import com.driver.igotrip.ui.mine.SafeVerifyActivity.Companion.BASE_URL
import com.driver.igotrip.ui.mine.SafeVerifyActivity.Companion.WEB_SITE_KEY
import com.driver.igotrip.ui.pub.AreaCodeActivity
import com.driver.igotrip.ui.pub.LoginActivity
import com.driver.igotrip.utils.Cache.CacheKey
import com.driver.igotrip.utils.Cache.CacheUtil
@@ -65,6 +71,9 @@
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.google.gson.Gson
import com.google.recaptcha.sample.RecaptchaVisual
import com.google.recaptcha.sample.RecaptchaVisualException
import com.lljjcoder.style.citylist.Toast.ToastUtils
import com.lzf.easyfloat.EasyFloat
import com.lzf.easyfloat.enums.ShowPattern
import com.lzf.easyfloat.enums.SidePattern
@@ -76,89 +85,88 @@
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.jetbrains.anko.browse
import org.jetbrains.anko.dip
import org.jetbrains.anko.find
import org.jetbrains.anko.startActivity
import org.jetbrains.anko.startActivityForResult
import org.jetbrains.anko.toast
import java.util.concurrent.TimeUnit
class ChangPhoneActivity : MyBaseActivity(){
class ChangPhoneActivity : MyBaseActivity() {
    private lateinit var recaptcha: RecaptchaVisual
    private val areaCode by lazy { find<TextView>(R.id.areaCode) }
    val et_login_code_send by lazy { find<TextView>(R.id.et_login_code_send) }
    val et_login_code by lazy { find<EditText>(R.id.et_login_code) }
    val et_login_phone by lazy { find<EditText>(R.id.et_login_phone) }
    val tv_operator by lazy { find<TextView>(R.id.tv_operator) }
    val tv_sure_car_num by lazy { find<TextView>(R.id.tv_sure_car_num) }
    override fun setContentView() {
        setContentView(R.layout.activity_changphone)
    }
    override fun initView() {
        recaptcha = RecaptchaVisual(supportFragmentManager, WEB_SITE_KEY, BASE_URL)
        val lang = SPUtils.getString(Const.language)
        val et_login_code_send = find<TextView>(R.id.et_login_code_send)
        val et_login_code = find<EditText>(R.id.et_login_code)
        val et_login_phone = find<EditText>(R.id.et_login_phone)
        val tv_operator = find<TextView>(R.id.tv_operator)
        val tv_sure_car_num = find<TextView>(R.id.tv_sure_car_num)
        if (lang == "fr") {
            et_login_code_send.setTextSize(TypedValue.COMPLEX_UNIT_SP,11f)
            et_login_code.setTextSize(TypedValue.COMPLEX_UNIT_SP,11f)
            et_login_phone.setTextSize(TypedValue.COMPLEX_UNIT_SP,11f)
            et_login_code_send.setTextSize(TypedValue.COMPLEX_UNIT_SP, 11f)
            et_login_code.setTextSize(TypedValue.COMPLEX_UNIT_SP, 11f)
            et_login_phone.setTextSize(TypedValue.COMPLEX_UNIT_SP, 11f)
        }
        et_login_code_send.clickDelay {
            if (et_login_phone.getContent().isEmpty()){
            if (et_login_phone.getContent().isEmpty()) {
                toast(getString(R.string.请输入手机号))
                return@clickDelay
            }
            var maps = getMapByAny()
            maps["phone"] = et_login_phone.getContent().trim()
            maps["type"] = 1
            callNet(Api.queryCaptcha, maps){
                toast(getString(R.string.发送成功))
            }
            refreshTime(et_login_code_send)
            sendSms()
        }
      /*  tv_operator.clickDelay {
            val operator = tv_operator.text.toString()
            DialogUtil.getColorListDialog(
                arrayListOf("MTN", "TIGO", "TELECEL", "AIRTEL"),
                tv_operator,
                this,
                if (operator.isEmpty()) "MTN" else operator
            ){
                tv_operator.text = it
            }
        }*/
        /*  tv_operator.clickDelay {
              val operator = tv_operator.text.toString()
              DialogUtil.getColorListDialog(
                  arrayListOf("MTN", "TIGO", "TELECEL", "AIRTEL"),
                  tv_operator,
                  this,
                  if (operator.isEmpty()) "MTN" else operator
              ){
                  tv_operator.text = it
              }
          }*/
        tv_sure_car_num.clickDelay {
            closeTime()
           /* if (tv_operator.text.toString().isEmpty()) {
                toast(getString(R.string.请选择运营商))
                return@clickDelay
            }*/
            if (et_login_code.getContent().isEmpty()){
            /* if (tv_operator.text.toString().isEmpty()) {
                 toast(getString(R.string.请选择运营商))
                 return@clickDelay
             }*/
            if (et_login_code.getContent().isEmpty()) {
                toast(getString(R.string.请输入验证码))
                return@clickDelay
            }
            if (et_login_phone.getContent().isEmpty()){
            if (et_login_phone.getContent().isEmpty()) {
                toast(getString(R.string.请输入手机号))
                return@clickDelay
            }
            if (!PhoneCheckUtil.phoneCheck(et_login_phone.getContent())){
            if (!PhoneCheckUtil.phoneCheck(et_login_phone.getContent())) {
                toast(getString(R.string.手机号格式错误))
                return@clickDelay
            }
            var map = getMapByAny()
            map["code"] = et_login_code.getContent()
            map["phone"] = et_login_phone.getContent()
           // map["phoneOperator"] = tv_operator.text.toString()
            callNet(Api.checkCaptcha, map){
                callNet(Api.updatePhone, map){
            map["phone"] = areaCode.getAreaCode() + et_login_phone.getContent()
            // map["phoneOperator"] = tv_operator.text.toString()
            callNet(Api.checkCaptcha, map) {
                callNet(Api.updatePhone, map) {
                    toast(getString(R.string.修改成功))
                    var user = CacheKey.getUserInfo()
                    user.phone = et_login_phone.getContent()
                    user.phone = areaCode.getAreaCode() + et_login_phone.getContent()
                    CacheKey.saveUserInfo(user)
                   // showPhone()
                    // showPhone()
                    CacheUtil.get().clear()
                    startActivity<LoginActivity>()
                    EventBus.getDefault().post(BaseEvent(BaseEvent.OFF_LINE))
@@ -169,22 +177,26 @@
            }
        }
    }
   /* fun showPhone(){
        var phone = CacheKey.getUserInfo().phone
        tv_phone.text = getString(R.string.您当前的手机号为, phone.substring(0, 3), phone.substring(7))
    }*/
    /* fun showPhone(){
         var phone = CacheKey.getUserInfo().phone
         tv_phone.text = getString(R.string.您当前的手机号为, phone.substring(0, 3), phone.substring(7))
     }*/
    override fun setOnclick() {
        areaCode.setOnClickListener {
            startActivityForResult<AreaCodeActivity>(10086)
        }
    }
    fun closeTime() {
        if (null != timeDisposable && !timeDisposable!!.isDisposed) {
            timeDisposable!!.dispose()
        }
    }
    var maxTime = 60 //配置倒计时时间
    private var timeDisposable: Disposable? = null
    @SuppressLint("SetTextI18n")
    public fun refreshTime(textView: TextView) {
        if (null != timeDisposable && !timeDisposable!!.isDisposed) {
@@ -202,9 +214,37 @@
                    textView.text = getString(R.string.获取验证码)
                } else {
                    textView.isEnabled = false
                    textView.text = (maxTime - 1 - aLong).toString() + getString(R.string.s后重新获取)
                    textView.text =
                        (maxTime - 1 - aLong).toString() + getString(R.string.s后重新获取)
                }
            }
    }
    private fun sendSms() {
        lifecycleScope.launch {
            try {
                val token = recaptcha.runCaptcha().await()
                val map = getMapByAny()
                map["phone"] = areaCode.getAreaCode() + et_login_phone.getContent().trim()
                map["kaptcha"] = "kaptcha"
                map["type"] = 1
                map["token"] = token
                callNet(Api.queryCaptcha, map) {
                    refreshTime(et_login_code_send)
                }
            } catch (error: RecaptchaVisualException) {
                ToastUtils.showShortToast(this@ChangPhoneActivity, error.message)
            }
        }
    }
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == Activity.RESULT_OK && requestCode == 10086) {
            data?.getStringExtra("code")?.let {
                areaCode.text = it
            }
        }
    }
}
app/src/main/java/com/driver/igotrip/ui/main/MainActivity.kt
@@ -41,8 +41,6 @@
import com.driver.igotrip.bean.UpCarInfo
import com.driver.igotrip.bean.VersionBean
import com.driver.igotrip.netUtls.Api
import com.driver.igotrip.netUtls.Api.completeOrder
import com.driver.igotrip.netUtls.Api.getDriverOrderMessage
import com.driver.igotrip.netUtls.callNet
import com.driver.igotrip.netUtls.getMapByAny
import com.driver.igotrip.ui.DialogUtil
@@ -417,6 +415,9 @@
    private fun initLocation() {
        val fragment = map_view as SupportMapFragment
        AMapKit.initMap(fragment) {
            // zmc-remark 测试代码 给个初始位置
//            MyApplication.aMapLocation = LatLng(30.659221715540937,104.06676612263988)
            aMap = it
            RxPermissions(this).request(Manifest.permission.ACCESS_FINE_LOCATION).subscribe {
                if (it) {
app/src/main/java/com/driver/igotrip/ui/main/TripActivity.kt
@@ -251,50 +251,54 @@
        }
        slide_btn.onSwipeListener = {
            orderBean?.let {
                when (it.data.orderState) {
                    2, 3, 4 -> {
                        var timeByLo = (DateUtil.dateToStamp(
                            DateUtil.TYPE0,
                            it.data.travelTime
                        ) - System.currentTimeMillis()) / 1000L
                        if (it.data.orderState == 2 && it.data.reservation == 2 && timeByLo > 1800L) {//判断预约单时间滑动是否有效
                            toast(getString(R.string.只能在预约时间的半小时内出行))
                            return@let
                        }
                        if (it.data.orderState == 4) {
            if (MyApplication.getLocation() == null) {
                toast(getString(R.string.定位中))
            } else {
                orderBean?.let {
                    when (it.data.orderState) {
                        2, 3, 4 -> {
                            var timeByLo = (DateUtil.dateToStamp(
                                DateUtil.TYPE0,
                                it.data.travelTime
                            ) - System.currentTimeMillis()) / 1000L
                            if (it.data.orderState == 2 && it.data.reservation == 2 && timeByLo > 1800L) {//判断预约单时间滑动是否有效
                                toast(getString(R.string.只能在预约时间的半小时内出行))
                                return@let
                            }
                            if (it.data.orderState == 4) {
//                            showNumDialog { num ->
                            it.data.orderState++
                            callStatue("", it.data.orderState, {
                                showStatueMapUI(it)
                                iv_to_gd.callOnClick()
                            }) {
                                it.data.orderState--
                            }
//                            }
                        } else {
                            it.data.orderState++
                            callStatue(it.data.orderState) {
                                if (it.data.orderState == 3){
                                it.data.orderState++
                                callStatue("", it.data.orderState, {
                                    showStatueMapUI(it)
                                    iv_to_gd.callOnClick()
                                }) {
                                    it.data.orderState--
                                }
//                            }
                            } else {
                                it.data.orderState++
                                callStatue(it.data.orderState) {
                                    if (it.data.orderState == 3){
                                        iv_to_gd.callOnClick()
                                    }
                                }
                                showStatueMapUI(it)
                            }
                            showStatueMapUI(it)
                        }
                    }
                    5, 6 -> {
                        it.data.orderState = 6
                        when (orderType) {
                            "2" -> {
                                showMoneyTypeDialog()
                            }
                            "1" -> {
                                callStatue(6) {
                                    startActivity<MajorSureMoneyActivity>(
                                        "orderId" to orderId,
                                        "orderType" to orderType
                                    )
                                    finish()
                        5, 6 -> {
                            it.data.orderState = 6
                            when (orderType) {
                                "2" -> {
                                    showMoneyTypeDialog()
                                }
                                "1" -> {
                                    callStatue(6) {
                                        startActivity<MajorSureMoneyActivity>(
                                            "orderId" to orderId,
                                            "orderType" to orderType
                                        )
                                        finish()
                                    }
                                }
                            }
                        }
app/src/main/java/com/driver/igotrip/ui/main/major/MajorSureMoney2Activity.kt
@@ -1,11 +1,8 @@
package com.driver.igotrip.ui.main.major
import android.util.Log
import android.view.View
import android.widget.EditText
import android.widget.TextView
import cn.sinata.xldutils.utils.clickDelay
import cn.sinata.xldutils.utils.getContent
import com.driver.igotrip.R
import com.driver.igotrip.base.BaseEvent
import com.driver.igotrip.base.MyBaseActivity
@@ -13,17 +10,13 @@
import com.driver.igotrip.bean.OrderBean
import com.driver.igotrip.netUtls.Api
import com.driver.igotrip.netUtls.Api.completeOrder
import com.driver.igotrip.netUtls.Api.rechargeBalance
import com.driver.igotrip.netUtls.callNet
import com.driver.igotrip.netUtls.getMapByAny
import com.driver.igotrip.ui.main.OrderOverActivity
import com.driver.igotrip.ui.main.major.MajorSureMoneyActivity.Companion.setbean
import com.driver.igotrip.ui.main.small_cargo.SmallOverActivity
import com.google.gson.Gson
import org.greenrobot.eventbus.EventBus
import org.jetbrains.anko.find
import org.jetbrains.anko.startActivity
import org.jetbrains.anko.toast
class MajorSureMoney2Activity : MyBaseActivity() {
@@ -57,29 +50,13 @@
    override fun setOnclick() {
        tv_sure1.clickDelay {
            sureMoneyCall()
            sureMoneyCallOnLine()
        }
        tv_sure2.clickDelay {
            var map = getMapByAny()
            map["orderId"] = orderId
            map["orderType"] = orderType
            map["type"] = 1
            callNet(true, Api.confirmFees, map) {
                var map = getMapByAny()
                map["orderId"] = orderId
                map["orderType"] = orderType
                callNet(completeOrder, map) {
                    EventBus.getDefault().post(BaseEvent(BaseEvent.BACK_CAR_OVER))
                    EventBus.getDefault().post(BaseEvent(BaseEvent.REFREASH_ORDERLIST))
                    finish()
                }
            }
            sureMoneyCallOffLine()
        }
        var map = getMapByAny()
        map["orderId"] = orderId
        map["orderType"] = orderType
@@ -92,7 +69,7 @@
    }
    private fun sureMoneyCall() {
    private fun sureMoneyCallOnLine() {
        var map = getMapByAny()
        map["orderId"] = orderId
        map["orderType"] = orderType
@@ -107,6 +84,24 @@
        }
    }
    private fun sureMoneyCallOffLine(){
        var map = getMapByAny()
        map["orderId"] = orderId
        map["orderType"] = orderType
        map["type"] = 2
        callNet(true, Api.confirmFees, map) {
            var map = getMapByAny()
            map["orderId"] = orderId
            map["orderType"] = orderType
            callNet(completeOrder, map) {
                EventBus.getDefault().post(BaseEvent(BaseEvent.BACK_CAR_OVER))
                EventBus.getDefault().post(BaseEvent(BaseEvent.REFREASH_ORDERLIST))
                EventBus.getDefault().post(BaseEvent(BaseEvent.REFREASH_MAIN))
                finish()
            }
        }
    }
    private fun callSmallOrder() {
        showDialog()
app/src/main/java/com/driver/igotrip/ui/main/small_cargo/SmallCargoActivity.kt
@@ -94,6 +94,7 @@
    private val btn_gap_money by lazy { find<TextView>(R.id.btn_gap_money) }
    private val iv_move by lazy { find<View>(R.id.iv_move) }
    private val iv_phone by lazy { find<View>(R.id.iv_phone) }
    private val iv_phone1 by lazy { find<View>(R.id.iv_phone1) }
    private val iv_police by lazy { find<View>(R.id.iv_police) }
    private val iv_to_gd by lazy { find<View>(R.id.iv_to_gd) }
    private val slide_btn by lazy { find<SlidingButton>(R.id.slide_btn) }
@@ -407,6 +408,12 @@
                MyUtils.getInstans().CallPhone(this, it.data.userPhone)
            }
        }
        iv_phone1.clickDelay {
            orderBean?.let {
                MyUtils.getInstans().CallPhone(this, it.data.phone)
            }
        }
    }
    fun startNavi(startLat: Double, startLon: Double, endLat: Double, endLon: Double) {
app/src/main/java/com/driver/igotrip/ui/mine/AcountSafeActivity.kt
@@ -7,6 +7,7 @@
import com.driver.igotrip.base.MyBaseActivity
import com.driver.igotrip.ui.card.CardListActivity
import com.driver.igotrip.ui.card.CommitPwdActivity
import com.driver.igotrip.ui.wave.WaveAccountActivity
import com.driver.igotrip.utils.Cache.CacheKey
import org.jetbrains.anko.find
import org.jetbrains.anko.startActivity
@@ -41,7 +42,8 @@
    fun showPhone(){
        var phone = CacheKey.getUserInfo().phone
        tv_phone.text = phone.substring(0,3)+"****"+phone.substring(7)
        tv_email.text = CacheKey.getUserInfo().email
//        tv_email.text = CacheKey.getUserInfo().email
        tv_email.text = " "
        tv_first_name.text = CacheKey.getUserInfo().firstName
        tv_last_name.text = CacheKey.getUserInfo().lastName
    }
@@ -64,7 +66,8 @@
        }
        ll_change_email.clickDelay {
            startActivity<ChangeEmailActivity>()
//            startActivity<ChangeEmailActivity>()
            startActivity<WaveAccountActivity>()
        }
        ll_change_name.clickDelay {
app/src/main/java/com/driver/igotrip/ui/mine/ChangeEmailActivity.kt
@@ -21,7 +21,7 @@
    private val et_email by lazy { find<EditText>(R.id.et_email) }
    override fun initView() {
        setTitle(R.string.WAVE账号设置)
        setTitleText(getString(R.string.WAVE账号设置))
        et_email.setText(CacheKey.getUserInfo().email)
        tv_Right.text = getString(R.string.保存)
    }
app/src/main/java/com/driver/igotrip/ui/mine/ChangePhoneOneActivity.kt
@@ -1,12 +1,15 @@
package com.driver.igotrip.ui.mine
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.util.TypedValue
import android.view.View
import android.widget.EditText
import android.widget.TextView
import cn.sinata.xldutils.utils.SPUtils
import cn.sinata.xldutils.utils.clickDelay
import cn.sinata.xldutils.utils.getAreaCode
import cn.sinata.xldutils.utils.getContent
import cn.sinata.xldutils.utils.textColor
import com.driver.igotrip.R
@@ -18,6 +21,7 @@
import com.driver.igotrip.netUtls.getMapByAny
import com.driver.igotrip.ui.DialogUtil
import com.driver.igotrip.ui.main.ChangPhoneActivity
import com.driver.igotrip.ui.pub.AreaCodeActivity
import com.driver.igotrip.ui.pub.LoginActivity
import com.driver.igotrip.utils.Cache.CacheKey
import com.driver.igotrip.utils.Cache.CacheUtil
@@ -30,6 +34,7 @@
import org.greenrobot.eventbus.EventBus
import org.jetbrains.anko.find
import org.jetbrains.anko.startActivity
import org.jetbrains.anko.startActivityForResult
import org.jetbrains.anko.toast
import java.util.concurrent.TimeUnit
@@ -40,7 +45,7 @@
    private val tv_phone by lazy { find<TextView>(R.id.tv_phone) }
    private val tv_change_phone by lazy { find<TextView>(R.id.tv_change_phone) }
    private var areaCode: TextView? = null
    override fun initView() {
        setTitleText(getString(R.string.修改手机号))
@@ -70,6 +75,7 @@
            )
            var view = DialogUtil.getView(dialog)
            val lang = SPUtils.getString(Const.language)
            areaCode = view.find<TextView>(R.id.areaCode)
            val et_login_code_send = view.find<TextView>(R.id.et_login_code_send)
            val et_login_code = view.find<EditText>(R.id.et_login_code)
            val et_login_phone = view.find<EditText>(R.id.et_login_phone)
@@ -83,13 +89,16 @@
                et_login_phone.setTextSize(TypedValue.COMPLEX_UNIT_SP,11f)
            }
            et_login_code_send.textColor(this,R.color.color_F02807)
            areaCode!!.setOnClickListener {
                startActivityForResult<AreaCodeActivity>(10086)
            }
            et_login_code_send.clickDelay {
                if (et_login_phone.getContent().isEmpty()){
                    toast(getString(R.string.请输入手机号))
                    return@clickDelay
                }
                var maps = getMapByAny()
                maps["phone"] = et_login_phone.getContent().trim()
                maps["phone"] = areaCode!!.getAreaCode() + et_login_phone.getContent().trim()
                maps["type"] = 1
                callNet(Api.queryCaptcha, maps){
                    toast(getString(R.string.发送成功))
@@ -135,13 +144,13 @@
                }
                var map = getMapByAny()
                map["code"] = et_login_code.getContent()
                map["phone"] = et_login_phone.getContent()
                map["phone"] = areaCode!!.getAreaCode() + et_login_phone.getContent()
                map["phoneOperator"] = tv_operator.text.toString()
                callNet(Api.checkCaptcha, map){
                    callNet(Api.updatePhone1, map){
                        toast(getString(R.string.修改成功))
                        var user = CacheKey.getUserInfo()
                        user.phone = et_login_phone.getContent()
                        user.phone = areaCode!!.getAreaCode() + et_login_phone.getContent()
                        CacheKey.saveUserInfo(user)
                        showPhone()
                        dialog.dismiss()
@@ -185,4 +194,13 @@
                }
            }
    }
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == Activity.RESULT_OK && requestCode == 10086) {
            data?.getStringExtra("code")?.let {
                areaCode?.text = it
            }
        }
    }
}
app/src/main/java/com/driver/igotrip/ui/mine/MineActivity.kt
@@ -17,6 +17,7 @@
import cn.sinata.xldutils.utils.getFormatTwo
import com.driver.igotrip.R
import com.driver.igotrip.base.BaseEvent
import com.driver.igotrip.base.BaseEvent.REFREASH_ORDERLIST
import com.driver.igotrip.base.MyApplication
import com.driver.igotrip.base.MyBaseActivity
import com.driver.igotrip.bean.UserBean
@@ -50,6 +51,7 @@
import org.greenrobot.eventbus.EventBus
import org.jetbrains.anko.find
import org.jetbrains.anko.startActivity
import org.jetbrains.anko.toast
import java.net.URL
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
app/src/main/java/com/driver/igotrip/ui/mine/SafeVerifyActivity.kt
@@ -3,6 +3,7 @@
import android.util.TypedValue
import android.widget.EditText
import android.widget.TextView
import androidx.lifecycle.lifecycleScope
import cn.sinata.xldutils.utils.SPUtils
import cn.sinata.xldutils.utils.clickDelay
import cn.sinata.xldutils.utils.getContent
@@ -14,15 +15,28 @@
import com.driver.igotrip.netUtls.callNet
import com.driver.igotrip.netUtls.getMapByAny
import com.driver.igotrip.utils.Cache.CacheKey
import com.google.recaptcha.sample.RecaptchaVisual
import com.google.recaptcha.sample.RecaptchaVisualException
import com.lljjcoder.style.citylist.Toast.ToastUtils
import kotlinx.coroutines.launch
import org.jetbrains.anko.find
import org.jetbrains.anko.startActivity
import org.jetbrains.anko.toast
class SafeVerifyActivity: BaseLoginActivity() {
    companion object {
        const val WEB_SITE_KEY = "6LdZdPErAAAAAM5YvB_2ElX5VR4bG2hcNhAOO5cU"
        const val BASE_URL = "https://gopost.ci"
    }
    private val et_login_code_send by lazy { find<TextView>(R.id.et_login_code_send) }
    private val et_login_pwd by lazy { find<EditText>(R.id.et_login_pwd) }
    private val tv_phone by lazy { find<TextView>(R.id.tv_phone) }
    private val tv_next by lazy { find<TextView>(R.id.tv_next) }
    private lateinit var recaptcha: RecaptchaVisual
    override fun tvInit(tv_code: TextView) {
        et_login_code_send.text = getString(R.string.获取验证码)
@@ -43,6 +57,7 @@
            et_login_pwd.setTextSize(TypedValue.COMPLEX_UNIT_SP,12f)
            et_login_code_send.setTextSize(TypedValue.COMPLEX_UNIT_SP,12f)
        }
        recaptcha = RecaptchaVisual(supportFragmentManager, WEB_SITE_KEY, BASE_URL)
    }
    override fun onResume() {
@@ -57,12 +72,7 @@
    override fun setOnclick() {
        et_login_code_send.setOnClickListener {
            var map = getMapByAny()
            map["phone"] = CacheKey.getUserInfo().phone
            map["type"] = 4
            callNet(Api.queryCaptcha, map) {
                refreshTime(et_login_code_send)
            }
            sendSms()
        }
        tv_next.clickDelay {
@@ -80,6 +90,27 @@
        }
    }
    private fun sendSms() {
        lifecycleScope.launch {
            try {
                val token = recaptcha.runCaptcha().await()
                var map = getMapByAny()
                map["phone"] = CacheKey.getUserInfo().phone
                map["kaptcha"] = "kaptcha"
                map["type"] = 4
                map["token"] = token
                callNet(Api.queryCaptcha, map) {
                    refreshTime(et_login_code_send)
                }
            } catch (error: RecaptchaVisualException) {
                ToastUtils.showShortToast(this@SafeVerifyActivity,error.message)
            }
        }
    }
    override fun onEventMainThread(event: BaseEvent?) {
        super.onEventMainThread(event)
        when(event?.code){
app/src/main/java/com/driver/igotrip/ui/mine/money_bag/ApplyMoneyActivity.kt
@@ -1,26 +1,41 @@
package com.driver.igotrip.ui.mine.money_bag
import android.annotation.SuppressLint
import android.content.Intent
import android.text.InputFilter
import android.text.Spanned
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.RadioGroup
import android.widget.TextView
import androidx.core.view.isVisible
import cn.sinata.xldutils.utils.doubleTwo
import cn.sinata.xldutils.utils.getContent
import com.driver.igotrip.R
import com.driver.igotrip.base.MyBaseActivity
import com.driver.igotrip.bean.CardListBean
import com.driver.igotrip.bean.UserBean
import com.driver.igotrip.bean.WaveBean
import com.driver.igotrip.netUtls.Api
import com.driver.igotrip.netUtls.callNet
import com.driver.igotrip.netUtls.getMapByAny
import com.driver.igotrip.ui.DialogUtil
import com.driver.igotrip.ui.card.CardListActivity
import com.driver.igotrip.ui.wave.WaveAccountActivity
import com.driver.igotrip.utils.Cache.CacheKey
import com.driver.igotrip.utils.view.NumberInputFilter
import org.jetbrains.anko.find
import org.jetbrains.anko.startActivityForResult
import org.jetbrains.anko.toast
import kotlin.getValue
class ApplyMoneyActivity : MyBaseActivity() {
    var maxMoney = 0.0
    var card: CardListBean.DataBean? = null
    var wave: WaveBean.DataBean? = null
    var withdrawCashType: Int? = null // 提现方式(1=银行卡,2=WAVE)
    val type by lazy {
        intent.getStringExtra("type")
@@ -36,11 +51,17 @@
    private val tv_type by lazy { find<TextView>(R.id.tv_type) }
    private val tv_action by lazy { find<TextView>(R.id.tv_action) }
    private val rgPay by lazy { find<RadioGroup>(R.id.rg_pay) }
    private val ll_card by lazy { find<LinearLayout>(R.id.ll_card) }
    private val tv_card by lazy { find<TextView>(R.id.tv_card) }
    private val ll_wave by lazy { find<LinearLayout>(R.id.ll_wave) }
    private val tv_wave by lazy { find<TextView>(R.id.tv_wave) }
    override fun initView() {
        setTitleText(getString(R.string.申请提现))
        maxMoney = if (type == "2"){
        maxMoney = if (type == "2") {
            CacheKey.getUserInfo().laveBusinessMoney
        }else{
        } else {
            CacheKey.getUserInfo().balance
        }
        et_money.hint = getString(R.string.填写提现金额最多可提).replace("%s", doubleTwo(maxMoney))
@@ -73,42 +94,95 @@
    override fun setOnclick() {
        tv_action.setOnClickListener {
            if (maxMoney <= 0){
            if (maxMoney <= 0) {
                toast(getString(R.string.没有余额))
                return@setOnClickListener
            }
            if (et_money.getContent().isEmpty()){
            if (et_money.getContent().isEmpty()) {
                toast(getString(R.string.请输入提现金额))
                return@setOnClickListener
            }
            if (et_money.getContent().toDouble() == 0.0){
            if (et_money.getContent().toDouble() == 0.0) {
                toast(getString(R.string.请输入提现金额))
                return@setOnClickListener
            }
            if (withdrawCashType == null) {
                toast(getString(R.string.请选择提现方式))
                return@setOnClickListener
            }
            if (wave == null && card == null) {
                toast(getString(R.string.请选择提现账号))
                return@setOnClickListener
            }
            tv_action.isEnabled = false
            var map = getMapByAny()
            val map = getMapByAny()
            if(withdrawCashType == 1){
                map["bankId"] = card!!.id
            }
            map["money"] = et_money.getContent().toDouble()
            map["type"] = type
            map["type"] = withdrawCashType
            map["remark"] = et_remark.getContent()
            callNet(Api.withdrawal,map,{
            callNet(Api.withdrawal1, map, {
                tv_action.isEnabled = true
                DialogUtil.getOnlySureDialog(this, getString(R.string.我们将尽快为您处理)) {
                    onBackPressed()
                }
                callNet(Api.queryInfo, getMapByAny()){
                callNet(Api.queryInfo, getMapByAny()) {
                    var user = gson.fromJson<UserBean>(it, UserBean::class.java)
                    CacheKey.saveUserInfo(user.data)
                    maxMoney = if (type == "2"){
                    maxMoney = if (type == "2") {
                        CacheKey.getUserInfo().laveBusinessMoney
                    }else{
                    } else {
                        CacheKey.getUserInfo().balance
                    }
                    et_money.hint = getString(R.string.填写提现金额最多可提).replace("%s", doubleTwo(maxMoney))
                    et_money.hint =
                        getString(R.string.填写提现金额最多可提).replace("%s", doubleTwo(maxMoney))
                }
            },{
            }, {
                tv_action.isEnabled = true
            })
        }
        rgPay.setOnCheckedChangeListener { _, checkedId ->
            when (checkedId) {
                R.id.rbpaytype1 -> {
                    // 选中“银行卡”
                    ll_card.isVisible = true
                    ll_wave.isVisible = false
                    withdrawCashType = 1
                }
                R.id.rbpaytype2 -> {
                    // 选中“WAVE”
                    ll_card.isVisible = false
                    ll_wave.isVisible = true
                    withdrawCashType = 2
                }
            }
        }
        ll_card.setOnClickListener {
            startActivityForResult<CardListActivity>(110, Pair("needBack", true))
        }
        ll_wave.setOnClickListener {
            startActivityForResult<WaveAccountActivity>(119, Pair("needBack", true))
        }
    }
    @SuppressLint("SetTextI18n")
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == RESULT_OK) {
            when (requestCode) {
                110 -> {
                    card = data?.getSerializableExtra("data") as? CardListBean.DataBean
                    tv_card.text = card?.bank
                }
                119 -> {
                    wave = data?.getSerializableExtra("data") as? WaveBean.DataBean
                    tv_wave.text = "${wave?.name}(${wave?.phone})"
                }
            }
        }
    }
}
app/src/main/java/com/driver/igotrip/ui/pub/AreaCodeActivity.kt
New file
@@ -0,0 +1,52 @@
package com.driver.igotrip.ui.pub
import android.content.Intent
import android.widget.EditText
import androidx.core.widget.addTextChangedListener
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.driver.igotrip.R
import com.driver.igotrip.base.MyBaseActivity
import com.driver.igotrip.bean.AreaCode
import org.jetbrains.anko.find
class AreaCodeActivity : MyBaseActivity() {
    private val search by lazy { find<EditText>(R.id.search) }
    private val rv by lazy { find<RecyclerView>(R.id.rv) }
    val dataList = mutableListOf<AreaCode>()
    private val adapter by lazy { AreaCodeAdapter() }
    override fun setContentView() {
        setContentView(R.layout.activity_area_code)
    }
    override fun initView() {
        setTitleText(getString(R.string.选择区号))
        dataList.add(AreaCode("CIV", getString(R.string.科特迪瓦), "+225"))
        dataList.add(AreaCode("CHN", getString(R.string.中国), "+86"))
        rv.adapter = adapter
        rv.layoutManager = LinearLayoutManager(this)
        adapter.data = dataList
        adapter.block = {
            it?.let {
                val intent = Intent().apply { putExtra("code", it.code) }
                setResult(RESULT_OK, intent)
                finish()
            }
        }
    }
    override fun setOnclick() {
        search.addTextChangedListener { text ->
            val filter = dataList.filter {
                (it.name ?: "").contains(text.toString())
                        || (it.abbreviation ?: "").contains(text.toString())
            }
            adapter.data = filter
        }
    }
}
app/src/main/java/com/driver/igotrip/ui/pub/AreaCodeAdapter.kt
New file
@@ -0,0 +1,29 @@
package com.driver.igotrip.ui.pub
import android.view.View
import android.widget.TextView
import com.driver.igotrip.R
import com.driver.igotrip.base.BaseRvAdapter
import com.driver.igotrip.base.BaseViewHolder
import com.driver.igotrip.bean.AreaCode
import org.jetbrains.anko.find
class AreaCodeAdapter : BaseRvAdapter<AreaCode>() {
    var block: ((AreaCode?) -> Unit)? = null
    override fun getLayoutResId(viewType: Int): Int {
        return R.layout.item_area_code
    }
    override fun onBindItem(holder: BaseViewHolder?, view: View?, item: AreaCode?) {
        holder?.let {
            it.itemView.find<TextView>(R.id.abbreviation).text = item?.abbreviation ?: ""
            it.itemView.find<TextView>(R.id.name).text = item?.name ?: ""
            it.itemView.find<TextView>(R.id.code).text = item?.code ?: ""
            it.itemView.setOnClickListener {
                block?.invoke(item)
            }
        }
    }
}
app/src/main/java/com/driver/igotrip/ui/pub/BecomeDriverActivity.kt
@@ -1,5 +1,7 @@
package com.driver.igotrip.ui.pub
import android.app.Activity
import android.content.Intent
import android.os.Handler
import android.util.Log
import android.view.View
@@ -8,8 +10,10 @@
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import cn.sinata.rxnetty.LogHelper.logRecord
import cn.sinata.xldutils.utils.*
import com.driver.igotrip.R
import com.driver.igotrip.base.BaseEvent
@@ -17,23 +21,29 @@
import com.driver.igotrip.bean.*
import com.driver.igotrip.netUtls.*
import com.driver.igotrip.netUtls.Api.companyList
import com.driver.igotrip.netUtls.Api.completeOrder
import com.driver.igotrip.ui.DialogUtil
import com.driver.igotrip.ui.adapter.SearchSitedapter
import com.driver.igotrip.ui.adapter.SiteListAdapter
import com.driver.igotrip.ui.mine.AddCarRegisterActivity
import com.driver.igotrip.ui.mine.SafeVerifyActivity.Companion.BASE_URL
import com.driver.igotrip.ui.mine.SafeVerifyActivity.Companion.WEB_SITE_KEY
import com.driver.igotrip.utils.*
import com.driver.igotrip.utils.Cache.CacheKey
import com.driver.igotrip.utils.citypickerview.picker.widget.builder.TimePickerBuilder
import com.driver.igotrip.utils.glide.GlideUtil
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.google.recaptcha.sample.RecaptchaVisual
import com.google.recaptcha.sample.RecaptchaVisualException
import com.lljjcoder.Interface.OnCityItemClickListener
import com.lljjcoder.bean.CityBean
import com.lljjcoder.bean.DistrictBean
import com.lljjcoder.bean.ProvinceBean
import com.lljjcoder.style.citylist.Toast.ToastUtils
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import org.jetbrains.anko.find
import org.jetbrains.anko.startActivity
import org.jetbrains.anko.startActivityForResult
import org.jetbrains.anko.toast
import java.util.*
import java.util.regex.Pattern
@@ -47,7 +57,9 @@
    var selectPhone = 0 //1 身份证 2:头像 3:驾驶证 4:网约车资格证  5 身份证背面
    var array = arrayListOf<String>()
    private lateinit var recaptcha: RecaptchaVisual
    private val areaCode by lazy { find<TextView>(R.id.areaCode) }
    private val et_collection_code by lazy { find<TextView>(R.id.et_collection_code) }
    private val et_yunyinggongsi_code by lazy { find<TextView>(R.id.et_yunyinggongsi_code) }
    private val et_login_code_send by lazy { find<TextView>(R.id.et_login_code_send) }
@@ -106,14 +118,22 @@
        array.add(getString(R.string.包裹_简单))
        tv_Right.text = ""
        tv_Right.gone()
        recaptcha = RecaptchaVisual(supportFragmentManager, WEB_SITE_KEY, BASE_URL)
    }
    private var chooseid = -1
    override fun setOnclick() {
        areaCode.setOnClickListener {
            startActivityForResult<AreaCodeActivity>(10086)
        }
        et_yunyinggongsi_code.setOnClickListener {
            var map = getMapByAny()
            if(upBean.placeOfPracticeId.isNullOrEmpty()){
                toast(getString(R.string.请选择从业地))
                return@setOnClickListener
            }
            val map = getMapByAny()
            map["cityId"] = upBean.placeOfPracticeId
            callNet(companyList, map) {
                Log.e("列表消息: ", it.toString())
                val datas = Gson().fromJson(it, OutBean::class.java)
@@ -170,14 +190,8 @@
//            if (!PhoneCheckUtil.phoneCheck(et_login_phone.getString())) {
//                toast(getString(R.string.手机号格式错误))
//                return@clickDelay
//            }
            var map = getMapByAny()
            map["phone"] = et_login_phone.getString()
            map["type"] = 3
            callNet(Api.queryCaptcha, map) {
                toast(getString(R.string.发送成功))
            }
            refreshTime(et_login_code_send)
//            }()
            sendSms()
        }
        iv_eye.setOnClickListener {
@@ -262,6 +276,9 @@
                    tv_city.text = city.getName()
                    upBean.placeOfPracticeId = city.id.toString()
                    upBean.placeOfPractice = city.getName()
                    et_yunyinggongsi_code.text = ""
                    chooseid = -1
                }
            }
@@ -439,9 +456,9 @@
            var map = getMapByAny()
            map["code"] = et_login_code.getString()
            map["phone"] = et_login_phone.getString()
            map["phone"] = areaCode.getAreaCode() + et_login_phone.getString()
            callNet(Api.checkCaptcha, map, {
                upBean.phone = et_login_phone.getString()
                upBean.phone = areaCode.getAreaCode() + et_login_phone.getString()
                upBean.password = et_login_pwd.getString()
                ll_driver_one.gone()
                ll_driver_two.visible()
@@ -512,7 +529,7 @@
    private fun callPersionInfo() {
        var map = getMapByAny()
        map["code"] = et_login_code.getString()
        map["phone"] = et_login_phone.getString()
        map["phone"] = areaCode.getAreaCode() + et_login_phone.getString()
        map["password"] = et_login_pwd.getString()
        // map["phoneOperator"] = tv_operator.text.toString()
        map["type"] = 2
@@ -553,7 +570,7 @@
            upBean.idCardImgUrl2 = it.idCardImgUrl2
            upBean.driveCardImgUrl2 = it.getdriveCardImgUrl2()
            upBean.password = et_login_pwd.getString()
            upBean.phone = et_login_phone.getString()
            upBean.phone = areaCode.getAreaCode() + et_login_phone.getString()
            upBean.placeOfPracticeId = it.placeOfPracticeId
            upBean.sex = it.sex
            upBean.taxiAptitudeCard = it.taxiAptitudeCard
@@ -840,4 +857,35 @@
        }
        return false
    }
    private fun sendSms() {
        lifecycleScope.launch {
            try {
                val token = recaptcha.runCaptcha().await()
                logRecord("okhttp","token = $token")
                var map = getMapByAny()
                map["kaptcha"] = "kaptcha"
                map["token"] = token
                map["phone"] = areaCode.getAreaCode() + et_login_phone.getString()
                map["type"] = 3
                callNet(Api.queryCaptcha, map) {
                    refreshTime(et_login_code_send)
                }
            } catch (error: RecaptchaVisualException) {
                ToastUtils.showShortToast(this@BecomeDriverActivity, error.message)
            }
        }
    }
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == Activity.RESULT_OK && requestCode == 10086) {
            data?.getStringExtra("code")?.let {
                areaCode.text = it
            }
        }
    }
}
app/src/main/java/com/driver/igotrip/ui/pub/ForgetPwdActivity.kt
@@ -1,9 +1,12 @@
package com.driver.igotrip.ui.pub
import android.app.Activity
import android.content.Intent
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import cn.sinata.xldutils.utils.clickDelay
import cn.sinata.xldutils.utils.getAreaCode
import cn.sinata.xldutils.utils.getString
import com.driver.emanagercar.ui.base.Local.BaseLoginActivity
import com.driver.igotrip.R
@@ -15,11 +18,13 @@
import com.driver.igotrip.netUtls.getMapByAny
import com.driver.igotrip.utils.PhoneCheckUtil
import org.jetbrains.anko.find
import org.jetbrains.anko.startActivityForResult
import org.jetbrains.anko.toast
class ForgetPwdActivity: BaseLoginActivity() {
    var first = false
    private val areaCode by lazy { find<TextView>(R.id.areaCode) }
    private val et_login_code_send by lazy { find<TextView>(R.id.et_login_code_send) }
    private val tv_hint_phone by lazy { find<TextView>(R.id.tv_hint_phone) }
    private val et_login_pwd by lazy { find<EditText>(R.id.et_login_pwd) }
@@ -73,6 +78,9 @@
    }
    override fun setOnclick() {
        areaCode.setOnClickListener {
            startActivityForResult<AreaCodeActivity>(10086)
        }
        et_login_code_send.clickDelay {
            if (et_login_phone.getString().isEmpty()){
                toast(getString(R.string.请输入手机号))
@@ -83,7 +91,7 @@
                return@clickDelay
            }
            var map = getMapByAny()
            map["phone"] = et_login_phone.getString()
            map["phone"] = areaCode.getAreaCode() + et_login_phone.getString()
            map["type"] =4
            callNet(Api.queryCaptcha,map){
                toast(getString(R.string.发送成功))
@@ -119,7 +127,7 @@
            var map = getMapByAny()
            map["code"] = et_login_code.getString()
            map["phone"] = et_login_phone.getString()
            map["phone"] = areaCode.getAreaCode() + et_login_phone.getString()
            callNet(Api.checkCaptcha,map){
                map["password"] = et_login_pwd.getString()
                callNet(Api.resetPassword,map){
@@ -129,4 +137,13 @@
            }
        }
    }
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == Activity.RESULT_OK && requestCode == 10086) {
            data?.getStringExtra("code")?.let {
                areaCode.text = it
            }
        }
    }
}
app/src/main/java/com/driver/igotrip/ui/pub/LoginActivity.kt
@@ -1,5 +1,8 @@
package com.driver.igotrip.ui.pub
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.util.Log
import android.view.Gravity
import android.view.View
@@ -9,6 +12,7 @@
import android.widget.Toast
import cn.sinata.xldutils.utils.SPUtils
import cn.sinata.xldutils.utils.clickDelay
import cn.sinata.xldutils.utils.getAreaCode
import cn.sinata.xldutils.utils.getString
import com.driver.emanagercar.ui.base.Local.BaseLoginActivity
import com.driver.igotrip.R
@@ -31,14 +35,16 @@
import org.jetbrains.anko.dip
import org.jetbrains.anko.find
import org.jetbrains.anko.startActivity
import org.jetbrains.anko.startActivityForResult
import org.jetbrains.anko.toast
import java.util.*
class LoginActivity: BaseLoginActivity() {
class LoginActivity : BaseLoginActivity() {
    override fun setContentView() {
        setContentView(R.layout.activity_login)
    }
    private val areaCode by lazy { find<TextView>(R.id.areaCode) }
    private val et_login_phone by lazy { find<EditText>(R.id.et_login_phone) }
    private val iv_logo by lazy { find<View>(R.id.iv_logo) }
    private val tv_driver by lazy { find<View>(R.id.tv_driver) }
@@ -78,8 +84,9 @@
    override fun setOnclick() {
        areaCode.setOnClickListener {
            startActivityForResult<AreaCodeActivity>(10086)
        }
        tv_driver.setOnClickListener {
            startActivity<BecomeDriverActivity>()
        }
@@ -92,36 +99,36 @@
            callHtml {
            }
            showEye(iv_eye,et_login_pwd)
            showEye(iv_eye, et_login_pwd)
        }
        tv_login.setOnClickListener {
            if (et_login_phone.getString().isEmpty()){
            if (et_login_phone.getString().isEmpty()) {
                toast(getString(R.string.请输入手机号))
                return@setOnClickListener
            }
            if (!PhoneCheckUtil.phoneCheck(et_login_phone.getString())){
            if (!PhoneCheckUtil.phoneCheck(et_login_phone.getString())) {
                toast(getString(R.string.手机号格式错误))
                return@setOnClickListener
            }
            if (et_login_pwd.getString().isEmpty()){
            if (et_login_pwd.getString().isEmpty()) {
                toast(getString(R.string.请输入密码))
                return@setOnClickListener
            }
            if (et_login_pwd.getString().length < 6){
            if (et_login_pwd.getString().length < 6) {
                toast(getString(R.string.密码不能小于6位))
                return@setOnClickListener
            }
            var map = getMapByAny()
            map["password"] = et_login_pwd.getString()
            map["phone"] = et_login_phone.getString()
            callNet(Api.loginPhone,map) {
                var bean = gson.fromJson<LoginBean>(it,LoginBean::class.java)
                CacheKey.putKeyStr("appid",bean.data.appid)
                CacheKey.putKeyStr("token",bean.data.token)
                CacheKey.putKeyStr("vehicleId",bean.data.vehicleId)
                CacheKey.putKeyStr("userId",bean.data.id.toString())
                CacheKey.putKeyStr("serverId",bean.data.serverId.toString())
                CacheKey.putKeyStr("terminalName",bean.data.terminalId.toString())
            map["phone"] = areaCode.getAreaCode() + et_login_phone.getString()
            callNet(Api.loginPhone, map) {
                var bean = gson.fromJson<LoginBean>(it, LoginBean::class.java)
                CacheKey.putKeyStr("appid", bean.data.appid)
                CacheKey.putKeyStr("token", bean.data.token)
                CacheKey.putKeyStr("vehicleId", bean.data.vehicleId)
                CacheKey.putKeyStr("userId", bean.data.id.toString())
                CacheKey.putKeyStr("serverId", bean.data.serverId.toString())
                CacheKey.putKeyStr("terminalName", bean.data.terminalId.toString())
//                CacheKey.putKeyStr("jumpCode",bean.data.jumpCode.toString())
                toast(getString(R.string.登录成功))
                MyApplication.getInstance()!!.setAlisa()
@@ -138,6 +145,8 @@
    }
    private var mBackAppTime: Long = 0
    @SuppressLint("MissingSuperCall")
    override fun onBackPressed() {
        if (System.currentTimeMillis() - mBackAppTime > 2000) {
            Toast.makeText(this, getString(R.string.再按一次退出程序), Toast.LENGTH_SHORT)
@@ -150,7 +159,7 @@
    override fun onStop() {
        super.onStop()
       // showFloater()
        // showFloater()
        //EasyFloat.show("EasyFloatTag")
    }
@@ -177,4 +186,14 @@
            floater?.show()
        }
    }
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == Activity.RESULT_OK && requestCode == 10086) {
            data?.getStringExtra("code")?.let {
                areaCode.text = it
            }
        }
    }
}
app/src/main/java/com/driver/igotrip/ui/wave/WaveAccountActivity.kt
New file
@@ -0,0 +1,66 @@
package com.driver.igotrip.ui.wave
import android.content.Intent
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isVisible
import cn.sinata.xldutils.utils.clickDelay
import com.driver.igotrip.R
import com.driver.igotrip.base.MyBaseActivity
import com.driver.igotrip.bean.WaveBean
import com.driver.igotrip.netUtls.Api
import com.driver.igotrip.netUtls.callNet
import com.driver.igotrip.netUtls.getMapByAny
import org.jetbrains.anko.find
import org.jetbrains.anko.startActivity
class WaveAccountActivity : MyBaseActivity() {
    var needBack = false // 是否需要返回值
    var wave: WaveBean.DataBean? = null
    private val cl_root by lazy { find<ConstraintLayout>(R.id.cl_root) }
    private val tv_name by lazy { find<TextView>(R.id.tv_name) }
    private val tv_phone by lazy { find<TextView>(R.id.tv_phone) }
    private val tv_sure by lazy { find<TextView>(R.id.tv_sure) }
    override fun setContentView() {
        setContentView(R.layout.activity_wave_account)
    }
    override fun initView() {
        setTitleText(getString(R.string.WAVE账号设置))
        needBack = intent?.getBooleanExtra("needBack", false) ?: false
    }
    override fun setOnclick() {
        tv_sure.clickDelay {
            startActivity<WaveSetActivity>()
        }
        cl_root.clickDelay {
            if (needBack) {
                val intent = Intent().apply { putExtra("data", wave!!) }
                setResult(RESULT_OK, intent)
                finish()
            }
        }
    }
    override fun onResume() {
        super.onResume()
        getWaveData()
    }
    private fun getWaveData() {
        callNet(Api.getWave, getMapByAny()) {
            val data = gson.fromJson<WaveBean>(it, WaveBean::class.java)
            if (data.data.phone.isNullOrEmpty() || data.data.name.isNullOrEmpty()) {
                cl_root.isVisible = false
            } else {
                wave = data.data
                cl_root.isVisible = true
                tv_name.text = data.data.name
                tv_phone.text = data.data.phone
            }
        }
    }
}
app/src/main/java/com/driver/igotrip/ui/wave/WaveSetActivity.kt
New file
@@ -0,0 +1,51 @@
package com.driver.igotrip.ui.wave
import android.widget.EditText
import android.widget.TextView
import cn.sinata.xldutils.utils.clickDelay
import com.driver.igotrip.R
import com.driver.igotrip.base.MyBaseActivity
import com.driver.igotrip.netUtls.Api
import com.driver.igotrip.netUtls.callNet
import com.driver.igotrip.netUtls.getMapByAny
import org.jetbrains.anko.find
import org.jetbrains.anko.toast
class WaveSetActivity : MyBaseActivity() {
    private val et_name by lazy { find<EditText>(R.id.et_name) }
    private val et_phone by lazy { find<EditText>(R.id.et_phone) }
    private val tv_action by lazy { find<TextView>(R.id.tv_action) }
    override fun setContentView() {
        setContentView(R.layout.activity_wave_set)
    }
    override fun initView() {
        setTitleText(getString(R.string.设置账号))
    }
    override fun setOnclick() {
        tv_action.clickDelay {
            val name = et_name.text.toString()
            if (name.isEmpty()) {
                toast(getString(R.string.请输入您的名字))
                return@clickDelay
            }
            val phone = et_phone.text.toString()
            if (phone.isEmpty()) {
                toast(getString(R.string.请输入WAVE手机号))
                return@clickDelay
            }
            val map = getMapByAny()
            map["phone"] = phone
            map["name"] = name
            callNet(Api.saveWave, map) {
                onBackPressed()
                toast(getString(R.string.success))
            }
        }
    }
}
app/src/main/java/com/driver/igotrip/utils/UtilKt.kt
@@ -276,6 +276,10 @@
    return this.text.toString().trim()
}
fun TextView.getAreaCode(): String{
    return this.text.toString().replace("+","")
}
fun EditText.setTextChange(onClick: (text: String) -> Unit) {
    this.addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(s: Editable?) {
app/src/main/java/com/driver/igotrip/utils/citypickerview/CityPickerView.java
New file
@@ -0,0 +1,414 @@
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.driver.igotrip.utils.citypickerview;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.PopupWindow.OnDismissListener;
import com.driver.igotrip.R;
import com.lljjcoder.Interface.OnCityItemClickListener;
import com.lljjcoder.bean.CityBean;
import com.lljjcoder.bean.DistrictBean;
import com.lljjcoder.bean.ProvinceBean;
import com.lljjcoder.citywheel.CityConfig;
import com.lljjcoder.citywheel.CityParseHelper;
import com.lljjcoder.citywheel.CityConfig.WheelType;
import com.lljjcoder.style.citylist.Toast.ToastUtils;
import com.lljjcoder.style.citypickerview.R.id;
import com.lljjcoder.style.citypickerview.R.layout;
import com.lljjcoder.style.citypickerview.R.style;
import com.lljjcoder.style.citypickerview.widget.CanShow;
import com.lljjcoder.style.citypickerview.widget.wheel.OnWheelChangedListener;
import com.lljjcoder.style.citypickerview.widget.wheel.WheelView;
import com.lljjcoder.style.citypickerview.widget.wheel.adapters.ArrayWheelAdapter;
import com.lljjcoder.utils.utils;
import java.util.ArrayList;
import java.util.List;
public class CityPickerView implements CanShow, OnWheelChangedListener {
    private String TAG = "citypicker_log";
    private PopupWindow popwindow;
    private View popview;
    private WheelView mViewProvince;
    private WheelView mViewCity;
    private WheelView mViewDistrict;
    private RelativeLayout mRelativeTitleBg;
    private TextView mTvOK;
    private TextView mTvTitle;
    private TextView mTvCancel;
    private OnCityItemClickListener mBaseListener;
    private CityParseHelper parseHelper;
    private CityConfig config;
    private Context context;
    private List<ProvinceBean> proArra;
    public void setOnCityItemClickListener(OnCityItemClickListener listener) {
        this.mBaseListener = listener;
    }
    public CityPickerView() {
    }
    public void setConfig(CityConfig config) {
        this.config = config;
    }
    public void init(Context context) {
        this.context = context;
        this.parseHelper = new CityParseHelper();
        if (this.parseHelper.getProvinceBeanArrayList().isEmpty()) {
            this.parseHelper.initData(context);
        }
    }
    @SuppressLint("WrongConstant")
    private void initCityPickerPopwindow() {
        if (this.config == null) {
            throw new IllegalArgumentException("please set config first...");
        } else {
            if (this.parseHelper == null) {
                this.parseHelper = new CityParseHelper();
            }
            if (this.parseHelper.getProvinceBeanArrayList().isEmpty()) {
                ToastUtils.showLongToast(this.context, "请在Activity中增加init操作");
            } else {
                LayoutInflater layoutInflater = LayoutInflater.from(this.context);
                this.popview = layoutInflater.inflate(R.layout.pop_citypicker, (ViewGroup)null);
                this.mViewProvince = (WheelView)this.popview.findViewById(id.id_province);
                this.mViewCity = (WheelView)this.popview.findViewById(id.id_city);
                this.mViewDistrict = (WheelView)this.popview.findViewById(id.id_district);
                this.mRelativeTitleBg = (RelativeLayout)this.popview.findViewById(id.rl_title);
                this.mTvOK = (TextView)this.popview.findViewById(id.tv_confirm);
                this.mTvTitle = (TextView)this.popview.findViewById(id.tv_title);
                this.mTvCancel = (TextView)this.popview.findViewById(id.tv_cancel);
                this.popwindow = new PopupWindow(this.popview, -1, -2);
                this.popwindow.setAnimationStyle(style.AnimBottom);
                this.popwindow.setBackgroundDrawable(new ColorDrawable());
                this.popwindow.setTouchable(true);
                this.popwindow.setOutsideTouchable(false);
                this.popwindow.setFocusable(true);
                this.popwindow.setOnDismissListener(new OnDismissListener() {
                    public void onDismiss() {
                        if (CityPickerView.this.config.isShowBackground()) {
                            utils.setBackgroundAlpha(CityPickerView.this.context, 1.0F);
                        }
                    }
                });
                if (!TextUtils.isEmpty(this.config.getTitleBackgroundColorStr())) {
                    if (this.config.getTitleBackgroundColorStr().startsWith("#")) {
                        this.mRelativeTitleBg.setBackgroundColor(Color.parseColor(this.config.getTitleBackgroundColorStr()));
                    } else {
                        this.mRelativeTitleBg.setBackgroundColor(Color.parseColor("#" + this.config.getTitleBackgroundColorStr()));
                    }
                }
                if (!TextUtils.isEmpty(this.config.getTitle())) {
                    this.mTvTitle.setText(this.config.getTitle());
                }
                if (this.config.getTitleTextSize() > 0) {
                    this.mTvTitle.setTextSize((float)this.config.getTitleTextSize());
                }
                if (!TextUtils.isEmpty(this.config.getTitleTextColorStr())) {
                    if (this.config.getTitleTextColorStr().startsWith("#")) {
                        this.mTvTitle.setTextColor(Color.parseColor(this.config.getTitleTextColorStr()));
                    } else {
                        this.mTvTitle.setTextColor(Color.parseColor("#" + this.config.getTitleTextColorStr()));
                    }
                }
                if (!TextUtils.isEmpty(this.config.getConfirmTextColorStr())) {
                    if (this.config.getConfirmTextColorStr().startsWith("#")) {
                        this.mTvOK.setTextColor(Color.parseColor(this.config.getConfirmTextColorStr()));
                    } else {
                        this.mTvOK.setTextColor(Color.parseColor("#" + this.config.getConfirmTextColorStr()));
                    }
                }
                if (!TextUtils.isEmpty(this.config.getConfirmText())) {
                    this.mTvOK.setText(this.config.getConfirmText());
                }
                if (this.config.getConfirmTextSize() > 0) {
                    this.mTvOK.setTextSize((float)this.config.getConfirmTextSize());
                }
                if (!TextUtils.isEmpty(this.config.getCancelTextColorStr())) {
                    if (this.config.getCancelTextColorStr().startsWith("#")) {
                        this.mTvCancel.setTextColor(Color.parseColor(this.config.getCancelTextColorStr()));
                    } else {
                        this.mTvCancel.setTextColor(Color.parseColor("#" + this.config.getCancelTextColorStr()));
                    }
                }
                if (!TextUtils.isEmpty(this.config.getCancelText())) {
                    this.mTvCancel.setText(this.config.getCancelText());
                }
                if (this.config.getCancelTextSize() > 0) {
                    this.mTvCancel.setTextSize((float)this.config.getCancelTextSize());
                }
                if (this.config.getWheelType() == WheelType.PRO) {
                    this.mViewCity.setVisibility(8);
                    this.mViewDistrict.setVisibility(8);
                } else if (this.config.getWheelType() == WheelType.PRO_CITY) {
                    this.mViewDistrict.setVisibility(8);
                } else {
                    this.mViewProvince.setVisibility(0);
                    this.mViewCity.setVisibility(0);
                    this.mViewDistrict.setVisibility(0);
                }
                this.mViewProvince.addChangingListener(this);
                this.mViewCity.addChangingListener(this);
                this.mViewDistrict.addChangingListener(this);
                this.mTvCancel.setOnClickListener(new OnClickListener() {
                    public void onClick(View v) {
                        CityPickerView.this.mBaseListener.onCancel();
                        CityPickerView.this.hide();
                    }
                });
                this.mTvOK.setOnClickListener(new OnClickListener() {
                    public void onClick(View v) {
                        if (CityPickerView.this.parseHelper != null) {
                            if (CityPickerView.this.config.getWheelType() == WheelType.PRO) {
                                CityPickerView.this.mBaseListener.onSelected(CityPickerView.this.parseHelper.getProvinceBean(), new CityBean(), new DistrictBean());
                            } else if (CityPickerView.this.config.getWheelType() == WheelType.PRO_CITY) {
                                CityPickerView.this.mBaseListener.onSelected(CityPickerView.this.parseHelper.getProvinceBean(), CityPickerView.this.parseHelper.getCityBean(), new DistrictBean());
                            } else {
                                CityPickerView.this.mBaseListener.onSelected(CityPickerView.this.parseHelper.getProvinceBean(), CityPickerView.this.parseHelper.getCityBean(), CityPickerView.this.parseHelper.getDistrictBean());
                            }
                        } else {
                            CityPickerView.this.mBaseListener.onSelected(new ProvinceBean(), new CityBean(), new DistrictBean());
                        }
                        CityPickerView.this.hide();
                    }
                });
                this.setUpData();
                if (this.config != null && this.config.isShowBackground()) {
                    utils.setBackgroundAlpha(this.context, 0.5F);
                }
            }
        }
    }
    private List<ProvinceBean> getProArrData(List<ProvinceBean> array) {
        List<ProvinceBean> provinceBeanList = new ArrayList();
        int i;
        for(i = 0; i < array.size(); ++i) {
            provinceBeanList.add(array.get(i));
        }
        if (!this.config.isShowGAT()) {
            provinceBeanList.remove(provinceBeanList.size() - 1);
            provinceBeanList.remove(provinceBeanList.size() - 1);
            provinceBeanList.remove(provinceBeanList.size() - 1);
        }
        this.proArra = new ArrayList();
        for(i = 0; i < provinceBeanList.size(); ++i) {
            this.proArra.add(provinceBeanList.get(i));
        }
        return this.proArra;
    }
    private void setUpData() {
        if (this.parseHelper != null && this.config != null) {
            this.getProArrData(this.parseHelper.getProvinceBeenArray());
            int provinceDefault = -1;
            if (!TextUtils.isEmpty(this.config.getDefaultProvinceName()) && this.proArra.size() > 0) {
                for(int i = 0; i < this.proArra.size(); ++i) {
                    if (((ProvinceBean)this.proArra.get(i)).getName().contains(this.config.getDefaultProvinceName())) {
                        provinceDefault = i;
                        break;
                    }
                }
            }
            ArrayWheelAdapter arrayWheelAdapter = new ArrayWheelAdapter(this.context, this.proArra);
            this.mViewProvince.setViewAdapter(arrayWheelAdapter);
            if (this.config.getCustomItemLayout() != CityConfig.NONE && this.config.getCustomItemTextViewId() != CityConfig.NONE) {
                arrayWheelAdapter.setItemResource(this.config.getCustomItemLayout());
                arrayWheelAdapter.setItemTextResource(this.config.getCustomItemTextViewId());
            } else {
                arrayWheelAdapter.setItemResource(layout.default_item_city);
                arrayWheelAdapter.setItemTextResource(id.default_item_city_name_tv);
            }
            if (-1 != provinceDefault) {
                this.mViewProvince.setCurrentItem(provinceDefault);
            }
            this.mViewProvince.setVisibleItems(this.config.getVisibleItems());
            this.mViewCity.setVisibleItems(this.config.getVisibleItems());
            this.mViewDistrict.setVisibleItems(this.config.getVisibleItems());
            this.mViewProvince.setCyclic(this.config.isProvinceCyclic());
            this.mViewCity.setCyclic(this.config.isCityCyclic());
            this.mViewDistrict.setCyclic(this.config.isDistrictCyclic());
            this.mViewProvince.setDrawShadows(this.config.isDrawShadows());
            this.mViewCity.setDrawShadows(this.config.isDrawShadows());
            this.mViewDistrict.setDrawShadows(this.config.isDrawShadows());
            this.mViewProvince.setLineColorStr(this.config.getLineColor());
            this.mViewProvince.setLineWidth(this.config.getLineHeigh());
            this.mViewCity.setLineColorStr(this.config.getLineColor());
            this.mViewCity.setLineWidth(this.config.getLineHeigh());
            this.mViewDistrict.setLineColorStr(this.config.getLineColor());
            this.mViewDistrict.setLineWidth(this.config.getLineHeigh());
            this.updateCities();
            this.updateAreas();
        }
    }
    private void updateCities() {
        if (this.parseHelper != null && this.config != null) {
            int pCurrent = this.mViewProvince.getCurrentItem();
            ProvinceBean mProvinceBean = (ProvinceBean)this.proArra.get(pCurrent);
            this.parseHelper.setProvinceBean(mProvinceBean);
            if (this.parseHelper.getPro_CityMap() != null) {
                List<CityBean> cities = (List)this.parseHelper.getPro_CityMap().get(mProvinceBean.getName());
                if (cities != null) {
                    int cityDefault = -1;
                    if (!TextUtils.isEmpty(this.config.getDefaultCityName()) && cities.size() > 0) {
                        for(int i = 0; i < cities.size(); ++i) {
                            if (this.config.getDefaultCityName().contains(((CityBean)cities.get(i)).getName())) {
                                cityDefault = i;
                                break;
                            }
                        }
                    }
                    ArrayWheelAdapter cityWheel = new ArrayWheelAdapter(this.context, cities);
                    if (this.config.getCustomItemLayout() != CityConfig.NONE && this.config.getCustomItemTextViewId() != CityConfig.NONE) {
                        cityWheel.setItemResource(this.config.getCustomItemLayout());
                        cityWheel.setItemTextResource(this.config.getCustomItemTextViewId());
                    } else {
                        cityWheel.setItemResource(layout.default_item_city);
                        cityWheel.setItemTextResource(id.default_item_city_name_tv);
                    }
                    this.mViewCity.setViewAdapter(cityWheel);
                    if (-1 != cityDefault) {
                        this.mViewCity.setCurrentItem(cityDefault);
                    } else {
                        this.mViewCity.setCurrentItem(0);
                    }
                    this.updateAreas();
                }
            }
        }
    }
    private void updateAreas() {
        int pCurrent = this.mViewCity.getCurrentItem();
        if (this.parseHelper.getPro_CityMap() != null && this.parseHelper.getCity_DisMap() != null) {
            if (this.config.getWheelType() == WheelType.PRO_CITY || this.config.getWheelType() == WheelType.PRO_CITY_DIS) {
                CityBean mCityBean = (CityBean)((List)this.parseHelper.getPro_CityMap().get(this.parseHelper.getProvinceBean().getName())).get(pCurrent);
                this.parseHelper.setCityBean(mCityBean);
                if (this.config.getWheelType() == WheelType.PRO_CITY_DIS) {
                    List<DistrictBean> areas = (List)this.parseHelper.getCity_DisMap().get(this.parseHelper.getProvinceBean().getName() + mCityBean.getName());
                    if (areas == null) {
                        return;
                    }
                    int districtDefault = -1;
                    if (!TextUtils.isEmpty(this.config.getDefaultDistrict()) && areas.size() > 0) {
                        for(int i = 0; i < areas.size(); ++i) {
                            if (this.config.getDefaultDistrict().contains(((DistrictBean)areas.get(i)).getName())) {
                                districtDefault = i;
                                break;
                            }
                        }
                    }
                    ArrayWheelAdapter districtWheel = new ArrayWheelAdapter(this.context, areas);
                    if (this.config.getCustomItemLayout() != CityConfig.NONE && this.config.getCustomItemTextViewId() != CityConfig.NONE) {
                        districtWheel.setItemResource(this.config.getCustomItemLayout());
                        districtWheel.setItemTextResource(this.config.getCustomItemTextViewId());
                    } else {
                        districtWheel.setItemResource(layout.default_item_city);
                        districtWheel.setItemTextResource(id.default_item_city_name_tv);
                    }
                    this.mViewDistrict.setViewAdapter(districtWheel);
                    DistrictBean mDistrictBean = null;
                    if (this.parseHelper.getDisMap() == null) {
                        return;
                    }
                    if (-1 != districtDefault) {
                        this.mViewDistrict.setCurrentItem(districtDefault);
                        mDistrictBean = (DistrictBean)this.parseHelper.getDisMap().get(this.parseHelper.getProvinceBean().getName() + mCityBean.getName() + this.config.getDefaultDistrict());
                    } else {
                        this.mViewDistrict.setCurrentItem(0);
                        if (areas.size() > 0) {
                            mDistrictBean = (DistrictBean)areas.get(0);
                        }
                    }
                    this.parseHelper.setDistrictBean(mDistrictBean);
                }
            }
        }
    }
    public void showCityPicker() {
        this.initCityPickerPopwindow();
        popview.findViewById(R.id.id_district).setVisibility(View.GONE);
        popview.findViewById(R.id.ll_title_background).setBackgroundResource(cn.sinata.xldutils.R.drawable.bg_white_10_top);
        popview.findViewById(R.id.rl_title).setBackgroundResource(cn.sinata.xldutils.R.drawable.bg_white_10_top);
        mViewProvince.setBackgroundResource(cn.sinata.xldutils.R.color.white);
        if (!this.isShow()) {
            this.popwindow.showAtLocation(this.popview, 80, 0, 0);
        }
    }
    public void hide() {
        if (this.isShow()) {
            this.popwindow.dismiss();
        }
    }
    public boolean isShow() {
        return this.popwindow.isShowing();
    }
    public void onChanged(WheelView wheel, int oldValue, int newValue) {
        if (wheel == this.mViewProvince) {
            this.updateCities();
        } else if (wheel == this.mViewCity) {
            this.updateAreas();
        } else if (wheel == this.mViewDistrict && this.parseHelper != null && this.parseHelper.getCity_DisMap() != null) {
            DistrictBean mDistrictBean = (DistrictBean)((List)this.parseHelper.getCity_DisMap().get(this.parseHelper.getProvinceBean().getName() + this.parseHelper.getCityBean().getName())).get(newValue);
            this.parseHelper.setDistrictBean(mDistrictBean);
        }
    }
}
app/src/main/java/com/driver/igotrip/utils/recaptcha/RecaptchaJavascriptChannel.kt
New file
@@ -0,0 +1,25 @@
package com.google.recaptcha.sample
import android.webkit.JavascriptInterface
class RecaptchaJavascriptChannel(private val listener: RecaptchaListener) {
    @JavascriptInterface
    fun onLoad() {
        listener.onLoad()
    }
    @JavascriptInterface
    fun onVerify(token: String) {
        listener.onVerify(token)
    }
    @JavascriptInterface
    fun onError(error: String) {
        listener.onError(RecaptchaVisualException(error))
    }
    @JavascriptInterface
    fun onExpire() {
        listener.onExpire()
    }
}
app/src/main/java/com/driver/igotrip/utils/recaptcha/RecaptchaListener.kt
New file
@@ -0,0 +1,11 @@
package com.google.recaptcha.sample
interface RecaptchaListener {
    fun onLoad()
    fun onVerify(token: String)
    fun onError(error: RecaptchaVisualException)
    fun onExpire()
}
app/src/main/java/com/driver/igotrip/utils/recaptcha/RecaptchaVisual.kt
New file
@@ -0,0 +1,39 @@
package com.google.recaptcha.sample
import androidx.fragment.app.FragmentManager
import java.util.Locale
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Deferred
class RecaptchaVisual(
    private val fragmentManager: FragmentManager,
    private val siteKey: String,
    private val baseUrl: String,
    private val lang: String = Locale.getDefault().getLanguage()
) : RecaptchaListener {
    private var onDone: CompletableDeferred<String> = CompletableDeferred()
    fun runCaptcha(): Deferred<String> {
        onDone = CompletableDeferred()
        val fragment = RecaptchaVisualFragment.newInstance(siteKey, baseUrl, lang)
        fragment.configure(this)
        fragment.show(fragmentManager, "RecaptchaVisual")
        return onDone
    }
    override fun onLoad() {
        // Do nothing
    }
    override fun onVerify(token: String) {
        onDone.complete(token)
    }
    override fun onError(error: RecaptchaVisualException) {
        onDone.completeExceptionally(error)
    }
    override fun onExpire() {
        onDone.completeExceptionally(RecaptchaVisualException("reCAPTCHA Expired"))
    }
}
app/src/main/java/com/driver/igotrip/utils/recaptcha/RecaptchaVisualException.kt
New file
@@ -0,0 +1,7 @@
package com.google.recaptcha.sample
class RecaptchaVisualException : Exception {
    constructor() : super()
    constructor(message: String) : super(message)
}
app/src/main/java/com/driver/igotrip/utils/recaptcha/RecaptchaVisualFragment.kt
New file
@@ -0,0 +1,82 @@
package com.google.recaptcha.sample
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.webkit.WebView
import androidx.fragment.app.DialogFragment
import com.driver.igotrip.R
class RecaptchaVisualFragment : DialogFragment(), RecaptchaListener {
    private lateinit var recaptchaWebView: RecaptchaWebView
    private lateinit var listener: RecaptchaListener
    companion object {
        fun newInstance(siteKey: String, baseUrl: String, lang: String?): RecaptchaVisualFragment {
            val f = RecaptchaVisualFragment()
            val args = Bundle()
            args.putString(RecaptchaWebView.SITE_KEY, siteKey)
            args.putString(RecaptchaWebView.BASE_URL, baseUrl)
            args.putString(RecaptchaWebView.LANG, lang)
            f.arguments = args
            return f
        }
    }
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.recaptcha, container, false)
        val webView = view.findViewById<WebView>(R.id.recaptchaWebview)
        recaptchaWebView = RecaptchaWebView(webView, requireArguments())
        recaptchaWebView.start(this, requireContext())
        view.findViewById<View>(R.id.cancelButton).setOnClickListener {
            onError(RecaptchaVisualException("User pressed cancel"))
        }
        return view
    }
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        dialog
            ?.window
            ?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
    }
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        return object : Dialog(requireActivity(), theme) {
            override fun onBackPressed() {
                dialog?.dismiss()
                listener.onError(RecaptchaVisualException("User pressed back"))
            }
        }
    }
    override fun onLoad() {
        listener.onLoad()
    }
    override fun onVerify(token: String) {
        dialog?.dismiss()
        listener.onVerify(token)
    }
    override fun onError(error: RecaptchaVisualException) {
        dialog?.dismiss()
        listener.onError(error)
    }
    override fun onExpire() {
        dialog?.dismiss()
        listener.onExpire()
    }
    fun configure(listener: RecaptchaListener) {
        this.listener = listener
    }
}
app/src/main/java/com/driver/igotrip/utils/recaptcha/RecaptchaWebView.kt
New file
@@ -0,0 +1,49 @@
package com.google.recaptcha.sample
import android.content.Context
import android.os.Bundle
import android.webkit.WebSettings
import android.webkit.WebView
import android.webkit.WebViewClient
const val JS_OBJECT_NAME: String = "RecaptchaJavascriptChannel"
class RecaptchaWebView(private val webView: WebView, private val arguments: Bundle) {
    companion object {
        const val SITE_KEY = "SITE_KEY"
        const val BASE_URL = "BASE_URL"
        const val LANG = "LANG"
    }
    init {
        configWebView(webView)
        webView.webViewClient = WebViewClient()
    }
    private fun configWebView(view: WebView) {
        WebView.setWebContentsDebuggingEnabled(true)
        val webSettings = view.getSettings()
        webSettings.javaScriptEnabled = true
        webSettings.useWideViewPort = true
        webSettings.setSupportZoom(false)
        webSettings.displayZoomControls = false
        webSettings.cacheMode = WebSettings.LOAD_NO_CACHE
    }
    fun start(listener: RecaptchaListener, context: Context) {
        webView.addJavascriptInterface(RecaptchaJavascriptChannel(listener), JS_OBJECT_NAME)
        val siteKey = arguments.getString(SITE_KEY)
        val baseUrl = arguments.getString(BASE_URL)
        val lang = arguments.getString(LANG)
        val htmlTemplate = context.assets.open("rce.html").bufferedReader().use { it.readText() }
        val html =
            htmlTemplate
                .replace("__SITE_KEY__", siteKey ?: "NO_SITEKEY")
                .replace("__LANG__", "&hl=$lang")
                .replace("__JS_OBJECT_NAME__", JS_OBJECT_NAME)
        webView.loadDataWithBaseURL(baseUrl, html, "text/html", "UTF-8", null)
    }
}
app/src/main/res/drawable/shape_333_line_8.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="8dp"/>
    <stroke android:color="#333333" android:width="1dp"/>
</shape>
app/src/main/res/layout/activity_apply_money.xml
@@ -71,9 +71,139 @@
    <View
        style="@style/style_form_divider_line"
        android:layout_marginStart="14dp"
        android:visibility="gone"
        android:layout_marginEnd="14dp"
        android:visibility="gone"
        app:layout_constraintTop_toBottomOf="@id/tv_type" />
    <TextView
        android:id="@+id/tv_pay_type"
        style="@style/style_form_text_wallet"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="14dp"
        android:text="@string/提现方式"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/tv_phone" />
    <RadioGroup
        android:id="@+id/rg_pay"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="20dp"
        android:orientation="horizontal"
        app:layout_constraintBottom_toBottomOf="@+id/tv_pay_type"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="@+id/tv_pay_type">
        <RadioButton
            android:id="@+id/rbpaytype1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/银行卡" />
        <RadioButton
            android:id="@+id/rbpaytype2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="50dp"
            android:text="WAVE" />
    </RadioGroup>
    <View
        style="@style/style_form_divider_line"
        android:layout_marginStart="14dp"
        android:layout_marginEnd="14dp"
        app:layout_constraintTop_toBottomOf="@id/tv_pay_type" />
    <LinearLayout
        android:id="@+id/type_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintTop_toBottomOf="@id/tv_pay_type">
        <LinearLayout
            android:id="@+id/ll_card"
            android:visibility="gone"
            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/debit_card_received"
                android:textColor="#ff333333"
                android:textSize="14sp" />
            <include layout="@layout/include_weight_width" />
            <TextView
                android:id="@+id/tv_card"
                android:layout_width="wrap_content"
                android:layout_height="50dp"
                android:background="@color/white"
                android:drawableEnd="@mipmap/more_black"
                android:drawablePadding="@dimen/dp_10"
                android:gravity="center_vertical"
                android:hint="@string/请选择"
                android:paddingStart="14dp"
                android:paddingEnd="14dp"
                android:text=""
                android:textColor="#ff333333"
                android:textSize="14sp"
                android:textStyle="bold" />
        </LinearLayout>
        <LinearLayout
            android:id="@+id/ll_wave"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:visibility="gone"
            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/到账WAVE"
                android:textColor="#ff333333"
                android:textSize="14sp" />
            <include layout="@layout/include_weight_width" />
            <TextView
                android:id="@+id/tv_wave"
                android:layout_width="wrap_content"
                android:layout_height="50dp"
                android:background="@color/white"
                android:drawableEnd="@mipmap/more_black"
                android:drawablePadding="@dimen/dp_10"
                android:gravity="center_vertical"
                android:hint="@string/请选择"
                android:paddingStart="14dp"
                android:paddingEnd="14dp"
                android:text=""
                android:textColor="#ff333333"
                android:textSize="14sp"
                android:textStyle="bold" />
        </LinearLayout>
        <include layout="@layout/include_line_14" />
    </LinearLayout>
    <EditText
        android:id="@+id/et_money"
@@ -83,9 +213,9 @@
        android:layout_marginEnd="14dp"
        android:background="@null"
        android:gravity="end|center_vertical"
        android:textSize="14sp"
        android:textColor="@color/textColor"
        app:layout_constraintTop_toBottomOf="@id/tv_type" />
        android:textSize="14sp"
        app:layout_constraintTop_toBottomOf="@id/type_layout" />
    <TextView
        android:id="@+id/tv_title"
@@ -132,34 +262,5 @@
        android:layout_marginStart="14dp"
        android:layout_marginEnd="14dp"
        app:layout_constraintTop_toBottomOf="@id/et_remark" />
    <TextView
        android:id="@+id/tvpaytype"
        style="@style/style_form_text_wallet"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="14dp"
        android:paddingBottom="0dp"
        android:text="@string/提现方式"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/et_remark" />
    <RadioButton
        android:id="@+id/rbpaytype1"
        app:layout_constraintStart_toEndOf="@+id/tvpaytype"
        android:text="@string/银行卡"
        android:layout_marginStart="50dp"
        app:layout_constraintBaseline_toBaselineOf="@+id/tvpaytype"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <RadioButton
        android:id="@+id/rbpaytype2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/rbpaytype1"
        android:text="WAVE"
        app:layout_constraintBaseline_toBaselineOf="@+id/tvpaytype"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>
app/src/main/res/layout/activity_area_code.xml
New file
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    android:orientation="vertical">
    <EditText
        android:id="@+id/search"
        style="@style/style_common_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="30dp"
        android:layout_marginTop="20dp"
        android:background="@drawable/shape_333_line_8"
        android:drawableStart="@mipmap/ic_search"
        android:drawablePadding="10dp"
        android:singleLine="true"
        android:hint="@string/搜索国家或简写"
        android:paddingHorizontal="20dp"
        android:paddingVertical="10dp" />
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp" />
</LinearLayout>
app/src/main/res/layout/activity_become_driver.xml
@@ -14,7 +14,7 @@
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="76dp"
            android:layout_height="wrap_content"
            android:elevation="2dp"
            android:orientation="horizontal">
@@ -45,7 +45,7 @@
            <TextView
                android:id="@+id/tv_two"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_height="match_parent"
                android:layout_marginStart="13dp"
                android:layout_marginTop="16dp"
                android:layout_weight="1"
app/src/main/res/layout/activity_changphone.xml
@@ -59,17 +59,34 @@
                    android:textSize="14sp" />
            </LinearLayout>
            <EditText
                android:id="@+id/et_login_phone"
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="36dp"
                android:layout_marginTop="4dp"
                android:background="@null"
                android:hint="@string/输入未注册手机号"
                android:inputType="number"
                android:textColor="#333333"
                android:textSize="14sp" />
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:orientation="horizontal">
                <TextView
                    android:id="@+id/areaCode"
                    style="@style/style_common_text"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/shape_333_line_8"
                    android:gravity="center"
                    android:paddingHorizontal="15dp"
                    android:paddingVertical="10dp"
                    android:text="+86" />
                <EditText
                    android:id="@+id/et_login_phone"
                    android:layout_width="match_parent"
                    android:layout_height="36dp"
                    android:layout_marginStart="10dp"
                    android:background="@null"
                    android:hint="@string/输入未注册手机号"
                    android:inputType="number"
                    android:textColor="#333333"
                    android:textSize="14sp" />
            </LinearLayout>
            <include layout="@layout/include_line" />
app/src/main/res/layout/activity_order_cancel.xml
@@ -47,6 +47,7 @@
        android:layout_width="wrap_content"
        android:layout_height="30dp"
        android:gravity="center_vertical"
        android:visibility="gone"
        android:orientation="horizontal">
        <TextView
app/src/main/res/layout/activity_wave_account.xml
New file
@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/cl_root"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:background="@drawable/bg_green_6dp"
        android:visibility="gone"
        app:layout_constraintTop_toTopOf="parent"
        tools:visibility="visible">
        <TextView
            android:id="@+id/tv_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="18dp"
            android:layout_marginTop="16dp"
            android:text="VISA"
            android:textColor="@color/white"
            android:textSize="14sp"
            android:textStyle="bold"
            app:layout_constraintTop_toTopOf="parent" />
        <TextView
            android:id="@+id/tv_phone"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="18dp"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="16dp"
            android:text="XXXX XXXX XXXX 3910"
            android:textColor="@color/white"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_name" />
    </androidx.constraintlayout.widget.ConstraintLayout>
    <TextView
        android:id="@+id/tv_sure"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_marginHorizontal="26dp"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        android:background="@drawable/bg_grey_line"
        android:gravity="center"
        android:text="@string/设置"
        android:textColor="@color/textColor"
        android:textSize="15sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
app/src/main/res/layout/activity_wave_set.xml
New file
@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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/page_bg">
    <View
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="@color/white"
        app:layout_constraintBottom_toBottomOf="@id/et_phone"
        app:layout_constraintTop_toTopOf="parent" />
    <TextView
        android:id="@+id/tv_1"
        style="@style/style_common_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="14dp"
        android:layout_marginTop="14dp"
        android:gravity="center_vertical"
        android:text="@string/姓名"
        android:textStyle="bold"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <EditText
        android:id="@+id/et_name"
        style="@style/style_common_text"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginHorizontal="14dp"
        android:background="@null"
        android:gravity="center_vertical"
        app:layout_constraintTop_toBottomOf="@id/tv_1" />
    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:layout_marginHorizontal="14dp"
        android:background="@color/dividing_line_color"
        app:layout_constraintTop_toBottomOf="@id/et_name" />
    <TextView
        android:id="@+id/tv_2"
        style="@style/style_common_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="14dp"
        android:layout_marginTop="14dp"
        android:gravity="center_vertical"
        android:text="@string/WAVE手机号"
        android:textStyle="bold"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/et_name" />
    <EditText
        android:id="@+id/et_phone"
        style="@style/style_common_text"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginHorizontal="14dp"
        android:background="@null"
        android:gravity="center_vertical"
        app:layout_constraintTop_toBottomOf="@id/tv_2" />
    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:layout_marginHorizontal="14dp"
        android:background="@color/dividing_line_color"
        app:layout_constraintTop_toBottomOf="@id/et_phone" />
    <TextView
        android:id="@+id/tv_action"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="26dp"
        android:layout_marginBottom="20dp"
        android:background="@drawable/bg_grey_line"
        android:gravity="center"
        android:paddingVertical="9dp"
        android:text="@string/设置"
        android:textColor="@color/textColor"
        android:textSize="15sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
app/src/main/res/layout/include_login_phone.xml
@@ -1,10 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_main_login_phone"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android">
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
@@ -28,16 +27,34 @@
    </LinearLayout>
    <EditText
        android:id="@+id/et_login_phone"
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="36dp"
        android:inputType="number"
        android:background="@null"
        android:layout_marginTop="4dp"
        android:hint="@string/请输入有效手机号"
        android:textColor="#333333"
        android:textSize="14sp" />
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:orientation="horizontal">
        <TextView
            android:id="@+id/areaCode"
            style="@style/style_common_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/shape_333_line_8"
            android:gravity="center"
            android:paddingHorizontal="15dp"
            android:paddingVertical="10dp"
            android:text="+86" />
        <EditText
            android:id="@+id/et_login_phone"
            android:layout_width="match_parent"
            android:layout_height="36dp"
            android:layout_marginStart="10dp"
            android:background="@null"
            android:hint="@string/请输入有效手机号"
            android:inputType="number"
            android:textColor="#333333"
            android:textSize="14sp" />
    </LinearLayout>
    <include layout="@layout/include_line" />
app/src/main/res/layout/include_order_top_cargo.xml
@@ -96,18 +96,32 @@
    <include layout="@layout/include_line" />
    <TextView
        android:id="@+id/tv_people_cargo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="11dp"
        android:layout_marginBottom="11dp"
        android:drawableStart="@mipmap/icon_people_gray"
        android:drawablePadding="5dp"
        tools:text="柳州客运中心"
        android:textColor="#ff27282d"
        android:textSize="14sp"
        android:textStyle="bold" />
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/tv_people_cargo"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="11dp"
            android:layout_marginBottom="11dp"
            android:drawableStart="@mipmap/icon_people_gray"
            android:drawablePadding="5dp"
            android:textColor="#ff27282d"
            android:textSize="14sp"
            android:textStyle="bold"
            tools:text="柳州客运中心" />
        <ImageView
            android:id="@+id/iv_phone1"
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:layout_alignParentEnd="true"
            android:layout_centerVertical="true"
            android:layout_marginEnd="14dp"
            android:background="@mipmap/icon_dial" />
    </RelativeLayout>
    <include layout="@layout/include_line" />
app/src/main/res/layout/item_area_code.xml
New file
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/white"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:id="@+id/abbreviation"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:paddingHorizontal="20dp"
            android:paddingVertical="14dp"
            android:text="崇州"
            android:textColor="@color/textColor"
            android:textSize="14sp" />
        <TextView
            android:id="@+id/name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="start"
            android:paddingVertical="14dp"
            android:paddingStart="30dp"
            android:text="崇州"
            android:textColor="@color/textColor"
            android:textSize="14sp" />
        <TextView
            android:id="@+id/code"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:paddingHorizontal="20dp"
            android:paddingVertical="14dp"
            android:text="崇州"
            android:textColor="@color/textColor"
            android:textSize="14sp" />
    </LinearLayout>
    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:background="@color/dividing_line_color" />
</LinearLayout>
app/src/main/res/layout/item_citylist.xml
New file
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <TextView
        android:id="@+id/default_item_city_name_tv"
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:background="@color/white"
        android:gravity="center"
        android:textSize="14sp"
        />
</LinearLayout>
app/src/main/res/layout/pop_citypicker.xml
New file
@@ -0,0 +1,83 @@
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_title_background"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:background="#E9E9E9"
    android:orientation="vertical">
    <RelativeLayout
        android:id="@+id/rl_title"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="@color/province_line_border">
        <TextView
            android:id="@+id/tv_confirm"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_alignParentRight="true"
            android:layout_marginRight="15dp"
            android:gravity="center_vertical"
            android:text="确定"
            android:textColor="@color/colorPrimary"
            android:textSize="16sp"/>
        <TextView
            android:id="@+id/tv_title"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_centerHorizontal="true"
            android:gravity="center_vertical"
            android:text="选择地区"
            android:textColor="#000000"
            android:textSize="16sp"/>
        <TextView
            android:id="@+id/tv_cancel"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_alignParentLeft="true"
            android:layout_marginLeft="15dp"
            android:gravity="center_vertical"
            android:text="取消"
            android:textColor="@color/colorPrimary"
            android:textSize="16sp"/>
    </RelativeLayout>
    <LinearLayout
        android:id="@+id/ll_title"
        android:layout_width="fill_parent"
        android:background="@color/white"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <com.lljjcoder.style.citypickerview.widget.wheel.WheelView
            android:id="@+id/id_province"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1">
        </com.lljjcoder.style.citypickerview.widget.wheel.WheelView>
        <com.lljjcoder.style.citypickerview.widget.wheel.WheelView
            android:id="@+id/id_city"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1">
        </com.lljjcoder.style.citypickerview.widget.wheel.WheelView>
        <com.lljjcoder.style.citypickerview.widget.wheel.WheelView
            android:id="@+id/id_district"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1">
        </com.lljjcoder.style.citypickerview.widget.wheel.WheelView>
    </LinearLayout>
</LinearLayout>
app/src/main/res/layout/recaptcha.xml
New file
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <android.webkit.WebView
        android:id="@+id/recaptchaWebview"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toTopOf="@+id/cancelButton"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />
    <Button
        app:layout_constraintTop_toBottomOf="@+id/recaptchaWebview"
        app:layout_constraintBottom_toBottomOf="parent"
        android:id="@+id/cancelButton"
        android:textSize="16sp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/关闭"
        style="@style/Widget.MaterialComponents.Button.TextButton"
        />
</androidx.constraintlayout.widget.ConstraintLayout>
app/src/main/res/mipmap-xxhdpi/ic_search.png
app/src/main/res/values-en/strings.xml
@@ -789,4 +789,9 @@
    <string name="定位权限说明" > GOPOST Driver needs an authorization to obtain your current location to check if services are available in the current district. We’ll upload your location to the backend in real-time to match and push nearby orders. If you deny location authorization, you won’t be able to receive orders normally. Confirm the authorization?</string>
    <string name="拒绝权限">Deny</string>
    <string name="搜索国家或简写">Search Country/Abbreviation</string>
    <string name="选择区号">Select Area Code</string>
    <string name="科特迪瓦">Côte d\'Ivoire</string>
    <string name="中国">China</string>
</resources>
app/src/main/res/values-fr/strings.xml
@@ -793,4 +793,8 @@
    <string name="定位权限说明" >Chauffeur GOPOST a besoin d’une autorisation pour obtenir votre emplacement actuel afin de vérifier si des services sont disponibles dans la zone actuelle. Nous téléchargerons votre position sur le backend en temps réel pour faire correspondre et pousser les commandes à proximité. Si vous refusez l’autorisation de localisation, vous ne pourrez pas recevoir les commandes normalement. Confirmer l’autorisation?</string>
    <string name="拒绝权限" >Refuser</string>
    <string name="搜索国家或简写">Rechercher le pays ou son abréviation</string>
    <string name="选择区号">Choisir le code régional</string>
    <string name="科特迪瓦">Côte d\'Ivoire</string>
    <string name="中国">Chine</string>
</resources>
app/src/main/res/values/strings.xml
@@ -800,11 +800,22 @@
    <string name="请上传手持身份证照片">请上传手持身份证照片</string>
    <string name="拍摄身份证背面照">拍摄身份证背面照</string>
    <string name="请选择提现方式">请选择提现方式</string>
    <string name="请选择提现账号">请选择提现账号</string>
    <string name="WAVE账号设置">WAVE账号设置</string>
    <string name="WAVE手机号">WAVE手机号</string>
    <string name="到账WAVE">到账WAVE</string>
    <string name="请输入WAVE手机号">请输入WAVE手机号</string>
    <string name="设置账号">设置账号</string>
    <string name="原密码">原密码</string>
    <string name="输入原密码">输入原密码</string>
    <string name="确认原密码">确认原密码</string>
    <string name="填写新手机号">填写新手机号</string>
    <string name="搜索国家或简写">搜索国家/简写</string>
    <string name="选择区号">选择区号</string>
    <string name="科特迪瓦">科特迪瓦</string>
    <string name="中国">中国</string>
</resources>
rxnetty/build.gradle
@@ -30,4 +30,7 @@
    api 'androidx.appcompat:appcompat:1.1.0'
    api 'io.reactivex:rxandroid:1.2.1'
    api 'io.reactivex:rxjava:1.1.6'
    api 'com.blankj:utilcodex:1.31.1'
}
rxnetty/src/main/java/cn/sinata/rxnetty/CoreService.java
@@ -1,5 +1,7 @@
package cn.sinata.rxnetty;
import static cn.sinata.rxnetty.LogHelper.logRecord;
import android.app.*;
import android.content.Context;
import android.content.Intent;
@@ -7,7 +9,6 @@
import android.graphics.Color;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
@@ -15,6 +16,7 @@
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import cn.sinata.rxnetty.netStatus.NetChangeObserver;
import cn.sinata.rxnetty.netStatus.NetStateReceiver;
import cn.sinata.rxnetty.netStatus.NetUtils;
@@ -33,6 +35,8 @@
 */
public class CoreService extends Service {
    private String TAG = "CoreService";
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
@@ -42,6 +46,7 @@
    @Override
    public void onCreate() {
        super.onCreate();
        logRecord(TAG, "onCreate");
    }
    void init() {
@@ -52,7 +57,10 @@
            @Override
            public void onSend(String s) {
                //先检查通道状态,如果断开,则重连。
                checkState();
                boolean state = checkState();
                if (!state) {
                    reConnect();
                }
                Observable<Void> send = send(s + "\n");
//                Observable<Void> send = send(s);
                if (send != null) {
@@ -76,19 +84,27 @@
        initCheckOb();
    }
    public void checkState() {
    public boolean checkState() {
        if (mConnection == null || mConnection.getChannel() == null
                || !mConnection.getChannel().isActive()
                || !mConnection.getChannel().isWritable()) {
            reConnect();
            logRecord(TAG, "checkState need reConnect");
            return false;
        } else {
            logRecord(TAG, "checkState no need reConnect");
            return true;
        }
    }
    void initCheckOb() {
        NettyClient.getInstance().setOnCheckListener(new OnCheckListener() {
            @Override
            public void doCheck() {
                checkState();
            public boolean doCheck() {
                boolean state = checkState();
                if (!state) {
                    reConnect();
                }
                return state;
            }
        });
    }
@@ -105,21 +121,31 @@
            @Override
            public void onNetConnected(NetUtils.NetType type) {
                super.onNetConnected(type);
                checkState();
                logRecord(TAG, "onNetConnected start checkState");
                boolean state = checkState();
                if (!state) {
                    reConnect();
                }
            }
            @Override
            public void onNetDisConnect() {
                super.onNetDisConnect();
                logRecord(TAG, "onNetDisConnect");
            }
        };
        NetStateReceiver.registerObserver(mNetChangeObserver);
        if (Config.isStartForeground) {
            if (Build.VERSION.SDK_INT >= 34) {
                startForeground(Config.NOTIFICATION_ID,getNotification(), ServiceInfo.FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING);
                startForeground(Config.NOTIFICATION_ID, getNotification(), ServiceInfo.FOREGROUND_SERVICE_TYPE_REMOTE_MESSAGING);
            } else {
                startForeground(Config.NOTIFICATION_ID,getNotification());
                startForeground(Config.NOTIFICATION_ID, getNotification());
            }
        }
        return START_NOT_STICKY;
    }
    private Notification getNotification(){
    private Notification getNotification() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            //8.0以上创建channel
            NotificationManager notificationManager =
@@ -147,9 +173,9 @@
        intent.setClassName(getPackageName(), getPackageName() + ".broadcast.MBroadcastReceiver");
        PendingIntent contentIntent;
        if (Build.VERSION.SDK_INT >= 31) {
            contentIntent= PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE);
        }else {
            contentIntent= PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            contentIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE);
        } else {
            contentIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        }
        mBuilder.setContentIntent(contentIntent);
        return mBuilder.build();
@@ -161,6 +187,7 @@
    public void onDestroy() {
        super.onDestroy();
        isDestroy = true;
        logRecord(TAG, "onDestroy");
        NetStateReceiver.unRegisterNetworkStateReceiver(this);
        if (subscriber != null && !subscriber.isUnsubscribed()) {
            subscriber.unsubscribe();
@@ -174,8 +201,9 @@
    }
    private void connectServer() {
        if (NetUtils.isNetworkAvailable(this)) {
        boolean status = NetUtils.isNetworkAvailable(this);
        logRecord(TAG, "connectServer net status = " + status);
        if (status) {
            connectionSub();
            connect(Config.SOCKET_SERVER, Config.SOCKET_PORT)
                    .subscribeOn(Schedulers.io())
@@ -202,6 +230,7 @@
            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
                logRecord(TAG, "connectionSub onError " + e.getMessage());
                reConnect();
            }
@@ -232,6 +261,7 @@
            @Override
            public void onError(Throwable e) {
                logRecord(TAG, "initReceiveOb onError " + e.getMessage());
                reConnect();
            }
@@ -257,6 +287,7 @@
    private void reConnect() {
        logRecord(TAG, "reConnect isDestroy = " + isDestroy);
        if (isDestroy) {
            return;
        }
@@ -268,7 +299,7 @@
                    mConnection.close();
                    mConnection = null;
                }
                Log.i("CoreService", "sendHeart_websocket长连接断开,重新连接");
                logRecord(TAG, "reConnect sendHeart_websocket长连接断开,重新连接");
                connectServer();
            }
        });
rxnetty/src/main/java/cn/sinata/rxnetty/LogHelper.java
New file
@@ -0,0 +1,23 @@
package cn.sinata.rxnetty;
import com.blankj.utilcode.util.LogUtils;
public class LogHelper {
    public static void initLogs() {
        LogUtils.Config config = LogUtils.getConfig();
        config.setSaveDays(7);
        config.setFilePrefix("gopost");
        config.setConsoleSwitch(true);
        config.setLog2FileSwitch(true);
        config.setSingleTagSwitch(true);
        config.setLogHeadSwitch(false);
        logRecord("MyApplication", "initLogs");
    }
    public static void logRecord(String name, String info) {
        String tag = name + " [" + Thread.currentThread().getName() + "-" + Thread.currentThread().getId() + "]";
        LogUtils.iTag(tag, info);
    }
}
rxnetty/src/main/java/cn/sinata/rxnetty/NJobService.java
@@ -24,6 +24,8 @@
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class NJobService extends android.app.job.JobService {
    private String TAG = "NJobService";
    @Override
    public void onCreate() {
        super.onCreate();
rxnetty/src/main/java/cn/sinata/rxnetty/NettyClient.java
@@ -1,10 +1,11 @@
package cn.sinata.rxnetty;
import static cn.sinata.rxnetty.LogHelper.logRecord;
import android.app.job.JobScheduler;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.util.Log;
import java.util.ArrayList;
@@ -13,23 +14,23 @@
 */
public class NettyClient {
    private String TAG = "NettyClient";
    public boolean isStop = false;
    private Context mContext;
    private ArrayList<OnMessageListener> listeners ;
    private ArrayList<OnMessageListener> listeners;
    private OnSendListener sendListener;
    private OnConnectListener connectListener;
    private OnCheckListener onCheckListener;
        public void init(Context context,String server,int port) {
            init(context,server,port,false);
        }
    public void init(Context context, String server, int port) {
        init(context, server, port, false);
    }
    public void init(Context context,String server,int port,boolean isStartForeground) {
    public void init(Context context, String server, int port, boolean isStartForeground) {
        mContext = context.getApplicationContext();
        Config.SOCKET_SERVER = server;
        Config.SOCKET_PORT = port;
        Config.isStartForeground= isStartForeground;
        Config.isStartForeground = isStartForeground;
    }
    public OnConnectListener getConnectListener() {
@@ -49,9 +50,9 @@
    }
    /**
     * 添加消息监听
     *
     * @param listener
     */
    public void addOnMessageListener(OnMessageListener listener) {
@@ -65,6 +66,7 @@
    /**
     * 连接完成监听
     *
     * @param listener
     */
    public void setOnConnectListener(OnConnectListener listener) {
@@ -72,7 +74,8 @@
    }
    /**
     *  移除消息监听
     * 移除消息监听
     *
     * @param listener
     */
    public void removeOnMessageListener(OnMessageListener listener) {
@@ -94,10 +97,11 @@
    /**
     * 发送消息给服务器
     *
     * @param msg
     */
    public void sendMessage(String msg) {
        Log.e("sendLocation: ","发送消息" +msg);
        logRecord(TAG, "sendMessage sendListener is null " + (sendListener == null) + " msg = " + msg);
        if (sendListener != null) {
            sendListener.onSend(msg);
        }
@@ -106,9 +110,12 @@
    /**
     * 检测netty连接状况
     */
    public void checkNettyState() {
    public boolean checkNettyState() {
        logRecord(TAG, "checkNettyState onCheckListener is null " + (onCheckListener == null));
        if (onCheckListener != null) {
            onCheckListener.doCheck();
            return onCheckListener.doCheck();
        } else {
            return false;
        }
    }
@@ -117,7 +124,7 @@
            return;
        }
        if (!isStop) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)  {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                try {
                    Intent intent = new Intent(this.getContext(), NJobService.class);
                    this.mContext.stopService(intent);
@@ -129,7 +136,7 @@
            }
        }
        isStop = false;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)  {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            try {
                Intent intent = new Intent(this.getContext(), NJobService.class);
                this.mContext.startService(intent);
@@ -146,11 +153,10 @@
            return;
        }
        isStop = true;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)  {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            try {
                JobScheduler jobScheduler = (JobScheduler) this.mContext.getSystemService(Context.JOB_SCHEDULER_SERVICE);
                if(jobScheduler!=null)
                    jobScheduler.cancel(11);
                if (jobScheduler != null) jobScheduler.cancel(11);
                this.mContext.stopService(new Intent(this.mContext, NJobService.class));
                this.mContext.stopService(new Intent(this.mContext, CoreService.class));
            } catch (Exception e) {
rxnetty/src/main/java/cn/sinata/rxnetty/OnCheckListener.java
@@ -5,5 +5,5 @@
 */
interface OnCheckListener {
    void doCheck();
    boolean doCheck();
}