diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 99b6fef..cbcc9b2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -101,10 +101,7 @@ android:name=".act.RegisterActivity" android:process=":background" android:screenOrientation="portrait" /> - + - + - + ${profile.uuid}") if (isDelete) { Log.d("gogogogogo isDelete") - profileManager.delete(profile.uuid) +// profileManager.delete(profile.uuid) MMKV.defaultMMKV() .removeValueForKey(BZYConstants.NODE_All_ITEM_NAME_KEY) - setSub2(profileManager, nowSubUrl) + } else { Log.d("gogogogogo update") profileManager.setActive(profile) - delay(500) + Log.d("updateProfile pro.source==>${profile.source}, url==>${nowSubUrl}") if (!TextUtils.isEmpty(profile.source)) { + if (profile.source != nowSubUrl) { Log.d("updateProfile patch") profileManager.patch( @@ -273,6 +274,17 @@ class ChangeNodeActivity : BaseActivity(), View.OnClickListener { } Log.d("updateProfile patch 2") } + } else { + profileManager.patch( + profile.uuid, + profile.name, + nowSubUrl, + 1800000L + ) + Log.d("updateProfile patch new 1") + profileManager.commit(profile.uuid) { status -> + Log.d("updateProfile new updateStatus: " + Gson().toJson(status.args) + ", pro==>" + status.progress) + } } Log.d("updateProfile go update") profileManager.update(profile.uuid) @@ -375,7 +387,6 @@ class ChangeNodeActivity : BaseActivity(), View.OnClickListener { } } - private fun setNewData(nodes: MutableList?) { runOnUiThread { if (nodes != null) { diff --git a/app/src/main/java/com/yingmao/clash/act/ChangeNodeTzActivity.kt b/app/src/main/java/com/yingmao/clash/act/ChangeNodeTzActivity.kt index fcd72e3..0d6d4b4 100644 --- a/app/src/main/java/com/yingmao/clash/act/ChangeNodeTzActivity.kt +++ b/app/src/main/java/com/yingmao/clash/act/ChangeNodeTzActivity.kt @@ -31,13 +31,12 @@ import com.cncat.vpn.common.log.Log import com.yingmao.clash.conf.BZYConstants import com.yingmao.clash.conf.Conf import com.yingmao.clash.entity.ClashNodebBean -import com.yingmao.clash.fragment.NewAccFragment -import com.yingmao.clash.fragment.NewAccFragment.Companion.CHECK_NODE_RESULT_CODE import com.yingmao.clash.remote.Resource import com.cncat.vpn.service.model.Profile import com.cncat.vpn.service.remote.IProfileManager import com.cncat.vpn.service.remote.IRemoteService import com.yingmao.clash.app.MainApplication +import com.yingmao.clash.fragment.home.HomeFragment import com.yingmao.clash.util.Utils import com.yingmao.clash.view.RxToast import com.yingmao.clash.view.adapter.NodeListAdapter @@ -92,7 +91,7 @@ class ChangeNodeTzActivity : BaseActivity(), View.OnClickListener { override fun onBackPressed() { intent.putExtra(BZYConstants.EXTRA_KEY_IS_RUNING, is_runing) - setResult(CHECK_NODE_RESULT_CODE, intent) + setResult(HomeFragment.CHECK_NODE_RESULT_CODE, intent) super.onBackPressed() } @@ -337,7 +336,7 @@ class ChangeNodeTzActivity : BaseActivity(), View.OnClickListener { val reloadLock = Semaphore(10) private fun setPing() { - if (!NewAccFragment.clashRunning) { + if (!HomeFragment.clashRunning) { RxToast.info("请先开启加速后,再进行测试."); return } @@ -430,7 +429,7 @@ class ChangeNodeTzActivity : BaseActivity(), View.OnClickListener { val intent = Intent() intent.putExtra(BZYConstants.MMKV_KEY_SELECT_NODE_NAME, "自动选择") intent.putExtra(BZYConstants.EXTRA_KEY_IS_RUNING, is_runing) - setResult(CHECK_NODE_RESULT_CODE, intent) + setResult(HomeFragment.CHECK_NODE_RESULT_CODE, intent) finish() } } diff --git a/app/src/main/java/com/yingmao/clash/act/MyPointCardActivity.kt b/app/src/main/java/com/yingmao/clash/act/MyPointCardActivity.kt deleted file mode 100644 index 9bce177..0000000 --- a/app/src/main/java/com/yingmao/clash/act/MyPointCardActivity.kt +++ /dev/null @@ -1,147 +0,0 @@ -package com.yingmao.clash.act - -import android.os.Bundle -import android.text.Html -import android.widget.EditText -import android.widget.TextView -import androidx.lifecycle.ViewModelProvider -import com.yingmao.clash.view.dialog.RxDialogShapeLoading - -import com.orhanobut.logger.Logger -import com.yingmao.clash.R -import com.yingmao.clash.base.BaseActivity -import com.yingmao.clash.net.http.HttpReqType -import com.yingmao.clash.net.http.HttpStatus -import com.yingmao.clash.net.http.entity.NormalMessageRsp -import com.yingmao.clash.net.http.entity.NormalRsp -import com.yingmao.clash.view.RxToast - -class MyPointCardActivity : BaseActivity() { - private lateinit var pointCardIdEt:EditText - private lateinit var pointCardRechargeTv:TextView - private lateinit var pointCardBalanceTv:TextView - private lateinit var pointCardVM: MyPointCardVM - - private lateinit var rxDialogShapeLoading: RxDialogShapeLoading - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.layout_activity_pointcard) - showTitleBar("我的点卡") - pointCardVM = ViewModelProvider(this).get(MyPointCardVM::class.java) - observe(this, pointCardVM) - initView() - - pointCardVM.getPointCardSurplus() - } - - private fun initView() { - pointCardIdEt = findViewById(R.id.et_point_card_id) - pointCardRechargeTv = findViewById(R.id.tv_point_card_recharge) - pointCardBalanceTv = findViewById(R.id.tv_point_card_balance) - pointCardRechargeTv.setOnClickListener { - rechargePointCard() - } - - } - - //点卡充值 - private fun rechargePointCard() { - if(::pointCardIdEt.isInitialized) { - val pointCardId = pointCardIdEt.text.toString().trim() - if(pointCardId.isEmpty()){ - RxToast.warning("请输入点卡卡号") - return - } - - val regex = "^[a-z0-9A-Z]{16}$" - val matches = pointCardId.matches(Regex(regex)) - if(!matches){ - RxToast.warning("您输入点卡卡号有误,请查证后输入!") - return - } - pointCardVM.rechargePointCard(pointCardId) - } - - } - - override fun httpLoading(httpStatus: HttpStatus.Loading) { - if(httpStatus.reqType == HttpReqType.POINT_CARD_RECHARGE){ - if(!::rxDialogShapeLoading.isInitialized) { - rxDialogShapeLoading = RxDialogShapeLoading(this) - } - rxDialogShapeLoading.setMessage("正在充值,请稍后...") - if(!rxDialogShapeLoading.isShowing){ - rxDialogShapeLoading.show() - } - }else if(httpStatus.reqType == HttpReqType.GET_POINTCARD_SURPLUS){ - if(!::rxDialogShapeLoading.isInitialized) { - rxDialogShapeLoading = RxDialogShapeLoading(this) - } - rxDialogShapeLoading.setMessage("正在查询点卡余额,请稍后...") - if(!rxDialogShapeLoading.isShowing){ - rxDialogShapeLoading.show() - } - } - } - - override fun httpSuccess(httpStatus: HttpStatus.Success) { - if(httpStatus.reqType == HttpReqType.POINT_CARD_RECHARGE){ - if(::rxDialogShapeLoading.isInitialized) { - rxDialogShapeLoading.cancel() - } - if(httpStatus.rsp is NormalMessageRsp){ - (httpStatus.rsp as NormalMessageRsp).let { - if(it.code == "1000"){ - //TODO 充值成功 - RxToast.info("点卡充值成功!") - pointCardIdEt.text.clear() - pointCardVM.getPointCardSurplus() - }else{ - RxToast.error("${it.code}${it.message}") - return@httpSuccess - } - } - } - }else if(httpStatus.reqType == HttpReqType.GET_POINTCARD_SURPLUS){ - if(::rxDialogShapeLoading.isInitialized) { - rxDialogShapeLoading.cancel() - } - if(httpStatus.rsp is NormalRsp){ - (httpStatus.rsp as NormalRsp).let { - if(it.code == "1000"){ - //TODO 查询余额成功,展示余额 - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { - pointCardBalanceTv.text = Html.fromHtml( - "剩余点数:${it.data}", - Html.FROM_HTML_MODE_LEGACY - ) - }else{ - pointCardBalanceTv.text = Html.fromHtml( - "剩余点数:${it.data}" - ) - } - }else{ - RxToast.error("${it.code}${it.message}") - return@httpSuccess - } - } - } - } - } - - override fun httpFailure(httpStatus: HttpStatus.Failure) { - if(httpStatus.reqType == HttpReqType.POINT_CARD_RECHARGE) { - if (::rxDialogShapeLoading.isInitialized) { - rxDialogShapeLoading.cancel() - } - Logger.d("点卡充值异常:${httpStatus.msg}") - RxToast.error("点卡充值异常") - }else if(httpStatus.reqType == HttpReqType.GET_POINTCARD_SURPLUS) { - if (::rxDialogShapeLoading.isInitialized) { - rxDialogShapeLoading.cancel() - } - Logger.d("查询点卡余额异常:${httpStatus.msg}") - RxToast.error("查询点卡余额异常") - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/yingmao/clash/act/MyPointCardVM.kt b/app/src/main/java/com/yingmao/clash/act/MyPointCardVM.kt deleted file mode 100644 index ce21ad4..0000000 --- a/app/src/main/java/com/yingmao/clash/act/MyPointCardVM.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.yingmao.clash.act - - -import com.orhanobut.logger.Logger -import com.tencent.mmkv.MMKV -import com.yingmao.clash.base.BaseViewMode -import com.yingmao.clash.conf.BZYConstants -import com.yingmao.clash.net.http.HttpApi -import com.yingmao.clash.net.http.HttpReqType -import com.yingmao.clash.net.http.NetService - -class MyPointCardVM: BaseViewMode() { - fun rechargePointCard(cardCode:String){ - val httpApi = NetService.instances.createHttps(HttpApi::class.java) - val username = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME,"")!! - val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN,"")!! - val params = hashMapOf( - "phoneNumber" to username, - "cardCode" to cardCode, - "phToken" to phToken - ) - doAsync(HttpReqType.POINT_CARD_RECHARGE){httpApi.pointCardSurplusRecharge(params)} - } - - fun getPointCardSurplus() { - val username = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME,"")!! - val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN,"")!! - Logger.d("获取点卡信息") - val params =hashMapOf( - "phoneNumber" to username, - "phToken" to phToken - ) - val httpApi = NetService.instances.createHttps(HttpApi::class.java) - doAsync(HttpReqType.GET_POINTCARD_SURPLUS) { httpApi.getPointCardSurplus(params) } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/yingmao/clash/act/NewMainActivity.kt b/app/src/main/java/com/yingmao/clash/act/NewMainActivity.kt index 55ca6c4..a40c56e 100644 --- a/app/src/main/java/com/yingmao/clash/act/NewMainActivity.kt +++ b/app/src/main/java/com/yingmao/clash/act/NewMainActivity.kt @@ -496,34 +496,23 @@ class NewMainActivity : BaseActivity() { val lastNotice = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_NOTICE_READ, "") val data = it.data +// if (data?.notice != null) { +// initMainPageHorseRaceLamp(data.notice) +// } if (data?.notice != null && lastNotice != data.notice) { - val notice = data.notice - MaterialDialog(this).show { - this.cancelable(false) - cornerRadius(res = R.dimen.dp_10) - customView( - R.layout.dialog_notice_layout, - scrollable = false, - noVerticalPadding = true, - horizontalPadding = false - ) - val noticeContent = getCustomView().findViewById(R.id.tv_notice_content) - noticeContent.text=notice - noticeContent.movementMethod = LinkMovementMethod.getInstance() - - val noticeUrl = getCustomView().findViewById(R.id.tv_notice_url) - noticeUrl.text= context.resources.getString(R.string.ClientDownload)+"\n${data.downloadUrl}" - - getCustomView().findViewById(R.id.tv_sure).setOnClickListener { + val notice = data.notice!! + val dialog = DialogNotice(this@NewMainActivity, notice, data.downloadUrl) + dialog.setOnReadClickListener(object : DialogNotice.OnReadClickListener { + override fun onReadClick() { MMKV.defaultMMKV() - .encode(BZYConstants.MMKV_KEY_NOTICE_READ, data.notice) + .encode(BZYConstants.MMKV_KEY_NOTICE_READ, data.notice!!) MMKV.defaultMMKV().encode( BZYConstants.MMKV_KEY_NOTICE_DOWNLOAD_READ, data.downloadUrl ) - dismiss() + dialog.dismiss() } - } - + }) + dialog.show() } } } @@ -548,21 +537,14 @@ class NewMainActivity : BaseActivity() { mmkv.encode(BZYConstants.MMKV_KEY_VPN_EXPIRED, expired ?: true) mmkv.encode(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD, nowExpireTime) setExpireDate() - fragments.filterIsInstance().forEach { - it.setExpireDate() - it.changeUserState() - } + fragments.filterIsInstance().forEach { it.setExpireDate() } checkPayResultDia?.dismiss() mainAtyVM.getAirNodes() RxToast.info(resources.getString(R.string.SuccessfullyUpdatedUserInformation)) - mainAtyVM.getExpensesRecord(mPageInfo) } else { // RxToast.info(resources.getString(R.string.PaymentResultsStr)) } - } else if(checkLoginRsp.code == -2){ - RxToast.info(resources.getString(R.string.LoginOut)) - cleanUserInfoToLogout() - }else{ + } else { RxToast.info(resources.getString(R.string.QueryFailed)) } payResultLoading?.dismiss() @@ -590,25 +572,26 @@ class NewMainActivity : BaseActivity() { } else { RxToast.error(resources.getString(R.string.NodeAcquisitionFailed) + "${data.msg}") } - data.data.let { url -> + data.data?.let { url -> android.util.Log.e("Data", "机场URL:=${url}") // var url2="https://api.ymvpnpro11.cc:8700/7air2vr7ikiqzgvxz/api/v1/client/subscribe?token=5af82930d222840cbc2dec572b21d6c6" if (url.isNotEmpty()) { //todo 判断订阅地址是否修改过,未修改就用接口返回的地址反之使用本地修改的地址 - val proSubUrl = + var pro_sub_url = MMKV.defaultMMKV().decodeString(BZYConstants.PROFILE_SUB_URL, "") - if (!TextUtils.isEmpty(proSubUrl)){ - if (proSubUrl == url) { + if (!TextUtils.isEmpty(pro_sub_url)) { + if (pro_sub_url == url) { subUrl = url } else { - subUrl = proSubUrl + subUrl = pro_sub_url } - }else{ + } else { subUrl = url } lifecycleScope.launch(Dispatchers.IO) { +// setSub(url) subUrl?.let { setSub2(it) } } } @@ -631,149 +614,31 @@ class NewMainActivity : BaseActivity() { } else if (httpStatus.reqType == HttpReqType.GetActivity) { val data = httpStatus.rsp as GetActivityRsp if (data.code == 200) { - if (data.data.data.list.isNotEmpty()) { - if(data.data.data.list.size>1){ - val bannerImgBeans=mutableListOf() - data.data.data.list.forEach {item-> - bannerImgBeans.add(BannerImgBean(item.title,item.content,item.redirectLink,0)) - } - homeActivityDialog = HomeActivityDialog(this,bannerImgBeans) - homeActivityDialog!!.show() - homeActivityDialog?.setOnDialogClickListener(object : HomeActivityDialog.OnHADialogClickListener { - override fun onRechargeClickListener() { - //跳转到支付界面 - goBackupRechargeWeb() - } + if (data.data != null) { + if (data.data.data != null) { + if (data.data.data.list.isNotEmpty()) { + data.data.data.list[0].redirectLink.let { + if(activityDialog==null){ + activityDialog = + ActivityViewDialog(this, data.data.data.list[0].redirectLink) + activityDialog?.setOnDialogClickListener(object : + OnDialogClickListener { + override fun onRechargeClickListener() { + //跳转到支付界面 + goBackupRechargeWeb() + } - override fun onCancelClickListener() { - homeActivityDialog?.dismiss() - } - - override fun onClickImgType(position: Int) { - android.util.Log.i("Postion", "position::$position") - - if(bannerImgBeans.get(position).redirectLink.contains("https:")){ - val uri = Uri.parse(bannerImgBeans.get(position).redirectLink) - val intent = Intent(Intent.ACTION_VIEW) - intent.setData(uri) - startActivity(intent) - }else if(bannerImgBeans.get(position).redirectLink.contains("firstCharge")){ - goBackupRechargeWeb() - }else if(bannerImgBeans.get(position).redirectLink.contains("BindAccount")){ - var useraccount = - MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")!! - if (Utils.isEmail(useraccount) || Utils.isPhoneNumber(useraccount)) { - RxToast.info(resources.getString(R.string.bindingAgi)) - return - } - val dialog = DialogBandChoose(this@NewMainActivity) - dialog.setOnBandClickListener(object : DialogBandChoose.OnBandClickListener { - override fun onBandClick(isPhone: Boolean) { - val intent = Intent(CommonUtils.getApp(), BandPhoneActivity::class.java) - intent.putExtra("isPhone", isPhone) - startActivity(intent) + override fun onCancelClickListener() { + activityDialog?.dismiss() } }) - dialog.show() - }else if(bannerImgBeans.get(position).redirectLink.contains("SignIn")){ - mainAtyVM.vipSign() + activityDialog?.show() } } - }) - }else{ - data.data.data.list[0].redirectLink.let { - var bannerImgBeans=mutableListOf() - bannerImgBeans.add(BannerImgBean(data.data.data.list[0].title,data.data.data.list[0].content,data.data.data.list[0].redirectLink,0)) - homeActivityDialog = - HomeActivityDialog(this,bannerImgBeans) - homeActivityDialog!!.show() - homeActivityDialog?.setOnDialogClickListener(object : - HomeActivityDialog.OnHADialogClickListener { - override fun onRechargeClickListener() { - //跳转到支付界面 - goBackupRechargeWeb() - } - - override fun onCancelClickListener() { - homeActivityDialog?.dismiss() - } - - override fun onClickImgType(position: Int) { - android.util.Log.i("Postion", "position::$position") - if(bannerImgBeans.get(position).redirectLink.contains("https:")){ - var uri = Uri.parse(bannerImgBeans.get(position).redirectLink) - val intent = Intent(Intent.ACTION_VIEW) - intent.setData(uri) - startActivity(intent) - }else if(bannerImgBeans.get(position).redirectLink.contains("firstCharge")){ - goBackupRechargeWeb() - }else if(bannerImgBeans.get(position).redirectLink.contains("BindAccount")){ - var useraccount = - MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")!! - if (Utils.isEmail(useraccount) || Utils.isPhoneNumber(useraccount)) { - RxToast.info(resources.getString(R.string.bindingAgi)) - return - } - val dialog = DialogBandChoose(this@NewMainActivity) - dialog.setOnBandClickListener(object : DialogBandChoose.OnBandClickListener { - override fun onBandClick(isPhone: Boolean) { - val intent = Intent(CommonUtils.getApp(), BandPhoneActivity::class.java) - intent.putExtra("isPhone", isPhone) - startActivity(intent) - } - }) - dialog.show() - }else if(bannerImgBeans.get(position).redirectLink.contains("SignIn")){ - mainAtyVM.vipSign() - } - } - }) - } - } - - } - } - }else if(httpStatus.reqType == HttpReqType.SelectNode){ - (httpStatus.rsp as ShowNode).let { - if (it.code == 200) { - val countryFlag = it.data?.countryFlag - if(countryFlag == true){ - findViewById(R.id.clLocation).visibility=View.VISIBLE - } - } - } - }else if(httpStatus.reqType == HttpReqType.EXPENSES_RECORD){ - if(httpStatus.rsp is ExpensesRecordRsp){ - httpStatus.rsp.let { expensesRecordRsp -> - if(expensesRecordRsp.code == "1000"){ - if(expensesRecordRsp.data != null) { - val expensesRecordList = expensesRecordRsp.data.expensesRecords - if(expensesRecordList!=null){ - if(expensesRecordList.size==1){ - val orderID = expensesRecordList[0].id - val report = expensesRecordList[0].reportFlag - android.util.Log.i("UPLoad:","data:::"+report+"orderId:"+orderID) - if(report == null){ - //调用上报日志 记录数据 - if (orderID != null) { - mainAtyVM.getReport(orderID) - } - } - } - - } } } } } - }else if(httpStatus.reqType == HttpReqType.Report){ - (httpStatus.rsp as AppVersionCheckRsp).let { - if(it.code==200){ - //上报百度支付功能 - android.util.Log.i("reqType:","data:::"+it.code) - BaiduAction.logAction(ActionType.PURCHASE) - } - } } } @@ -812,34 +677,33 @@ class NewMainActivity : BaseActivity() { // fragments.add(RechargeFragment()) containerVP.adapter = MainVPAdapter(fragments, supportFragmentManager, lifecycle) containerVP.isUserInputEnabled = false - clHomeRecharge=findViewById(R.id.clHomeRecharge) - clDeepSeek=findViewById(R.id.clDeepSeek) - floating=findViewById(R.id.floating) - tv_exit=findViewById(R.id.tv_exit) - clSing=findViewById(R.id.clSing) - clSing.setOnClickListener { - mainAtyVM.vipSign() + var aniAct = findViewById(R.id.lottie_activity) + aniAct.setAnimation(R.raw.activity) + aniAct.playAnimation() + aniAct.setOnClickListener { + startActivity(Intent(CommonUtils.getApp(), ActivityActivity::class.java)) } - - clHomeRecharge.setOnClickListener { - goBackupRechargeWeb() - } - tv_exit.setOnClickListener { - cleanUserInfo() - finish() - } - clDeepSeek.setOnClickListener { - startActivity(Intent(this, CustomerServiceWebView::class.java)) - drawer.close() - } - floating.setOnClickListener { - startActivity(Intent(this, CustomerServiceWebView::class.java)) + findViewById(R.id.ll_activity).setOnClickListener { + startActivity(Intent(CommonUtils.getApp(), ActivityActivity::class.java)) } setSometion() } private fun initMainPageHorseRaceLamp(noticeData: String) { - + val mainPageHorseRaceLamp = findViewById(R.id.mainPageHorseRaceLamp) + if (noticeData.isNotEmpty()) { + mainPageHorseRaceLamp.text = noticeData + mainPageHorseRaceLamp.requestFocus() + mainPageHorseRaceLamp.marqueeRepeatLimit = Integer.MAX_VALUE + mainPageHorseRaceLamp.isFocusable = true + mainPageHorseRaceLamp.ellipsize = TextUtils.TruncateAt.MARQUEE + mainPageHorseRaceLamp.setSingleLine() + mainPageHorseRaceLamp.isFocusableInTouchMode = true + mainPageHorseRaceLamp.setHorizontallyScrolling(true) + } else { + val llNoticeBackground = findViewById(R.id.llNoticeBackground) + llNoticeBackground.visibility = View.GONE + } } private fun cleanUserInfo() { @@ -849,9 +713,6 @@ class NewMainActivity : BaseActivity() { MMKV.defaultMMKV().removeValueForKey(BZYConstants.NODE_SELECTED_NAME_KEY) MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_VPN_UserCommand) MMKV.defaultMMKV().removeValueForKey(BZYConstants.NODE_All_ITEM_NAME_KEY) - MMKV.defaultMMKV().removeValueForKey(BZYConstants.PROFILE_SUB_URL) - MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_Switch_Finsh_Set) - isSubbed =false Log.d("cleanUserInfo clashRunning==>${clashRunning}") if (clashRunning) { fragments.filterIsInstance().forEach { it.stopClash() } @@ -862,28 +723,6 @@ class NewMainActivity : BaseActivity() { startActivity(Intent(CommonUtils.getApp(), LoginActivity::class.java)) finish() } - private fun cleanUserInfoToLogout() { - MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_PH_TOKEN) - MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_TOKEN) - MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_CURRENT_NODE) - MMKV.defaultMMKV().removeValueForKey(BZYConstants.NODE_SELECTED_NAME_KEY) - MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_VPN_UserCommand) - MMKV.defaultMMKV().removeValueForKey(BZYConstants.NODE_All_ITEM_NAME_KEY) - MMKV.defaultMMKV().removeValueForKey(BZYConstants.PROFILE_SUB_URL) - MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_Switch_Finsh_Set) - isSubbed =false - Log.d("cleanUserInfo clashRunning==>${clashRunning}") - if (clashRunning) { - fragments.filterIsInstance().forEach { it.stopClash() } - } - stopUploadTimer() - mainAtyVM.stopHeartBeat() - cleanProfile() - val intent=Intent(CommonUtils.getApp(), LoginActivity::class.java) - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) - startActivity(intent) - finish() - } private fun cleanProfile() { @@ -906,11 +745,25 @@ class NewMainActivity : BaseActivity() { tv_username = findViewById(R.id.tv_username) iv_slider = findViewById(R.id.iv_slider) ll_slider = findViewById(R.id.ll_slider) + tv_exit = findViewById(R.id.tv_exit) tv_band = findViewById(R.id.tv_band) +// containerVP.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { +// override fun onPageSelected(position: Int) { +// super.onPageSelected(position) +// if (position == 1 || position == 2) { +// tv_rechar.visibility = View.GONE +// } else { +// tv_rechar.visibility = View.VISIBLE +// } +// } +// }) + findViewById(R.id.tv_version).text = resources.getString(R.string.edition) + "${BuildConfig.VERSION_NAME}." + BuildConfig.productId if (MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_IS_PERFECT)) { +// 临时用户显示默认密码 +// findViewById(R.id.tv_default_psw).visibility = View.VISIBLE tv_band.setOnClickListener {//绑定 showBingDialogChoose() drawer.close() @@ -924,37 +777,35 @@ class NewMainActivity : BaseActivity() { MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME) }" } - findViewById(R.id.clRecharge).setOnClickListener {//充值 + + tv_exit.setOnClickListener {//退出 + cleanUserInfo() + finish() + } + + findViewById(R.id.tv_viprecharge).setOnClickListener {//充值 + // tv_rechar.visibility = View.GONE + // iv_slider.setImageResource(R.drawable.ic_s_back) + drawer.close() + goBackupRechargeWeb() + } + findViewById(R.id.tv_vip_recharge).setOnClickListener { drawer.close() goBackupRechargeWeb() } - findViewById(R.id.clNotice).setOnClickListener {//通知 + findViewById(R.id.tv_notice).setOnClickListener {//通知 val notice = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_NOTICE_READ, "暂无新通知")!! - val downloadUrl = + val download_url = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_NOTICE_DOWNLOAD_READ, "")!! - MaterialDialog(this).show { - this.cancelable(false) - cornerRadius(res = R.dimen.dp_10) - customView( - R.layout.dialog_notice_layout, - scrollable = false, - noVerticalPadding = true, - horizontalPadding = false - ) - val noticeContent = getCustomView().findViewById(R.id.tv_notice_content) - noticeContent.text=notice - noticeContent.movementMethod = LinkMovementMethod.getInstance() - - val noticeUrl = getCustomView().findViewById(R.id.tv_notice_url) - noticeUrl.text= context.resources.getString(R.string.ClientDownload)+"\n${downloadUrl}" - - getCustomView().findViewById(R.id.tv_sure).setOnClickListener { - dismiss() + val dialog = DialogNotice(this@NewMainActivity, notice, download_url) + dialog.setOnReadClickListener(object : DialogNotice.OnReadClickListener { + override fun onReadClick() { + dialog.dismiss() } - } - + }) + dialog.show() drawer.close() } @@ -965,43 +816,68 @@ class NewMainActivity : BaseActivity() { clipboardManager.setPrimaryClip(clipData) RxToast.info(resources.getString(R.string.CopyToClipboard)) } - findViewById(R.id.clShare).setOnClickListener {//分享 + +// tv_rechar.setOnClickListener { +// goRechargeWeb() +// } + findViewById(R.id.tv_share).setOnClickListener {//分享 startActivity(Intent(this@NewMainActivity, ShareActivity::class.java)) drawer.close() } - findViewById(R.id.clSetting).setOnClickListener {//设置 + findViewById(R.id.tv_setting).setOnClickListener {//设置 startActivity(Intent(this, SettingActivity::class.java)) drawer.close() } + findViewById(R.id.tv_dianka).setOnClickListener {//点卡 + startActivity(Intent(this, MyPointCardActivity::class.java)) + drawer.close() + } + findViewById(R.id.tv_vip_sign).setOnClickListener {//会员签到 + mainAtyVM.vipSign() +// drawer.close() + } + findViewById(R.id.tv_tixian).setOnClickListener {//提现 + startActivity(Intent(this, ZFBTXActivity::class.java)) + drawer.close() + } + val telegramBtn = findViewById(R.id.tv_dianbao) - findViewById(R.id.clLocation).setOnClickListener {//变更 - if (checkExpire()) { - RxToast.info(resources.getString(R.string.AccountExpired)) - return@setOnClickListener + telegramBtn.setOnClickListener {//电报 + var uri = Uri.parse(BZYConstants.DefTGUrl) + val intent = Intent(Intent.ACTION_VIEW) + when { + BuildConfig.is_ym -> { + uri = Uri.parse(BZYConstants.YMTGUrl) + } + + BuildConfig.is_tz -> { + uri = Uri.parse(BZYConstants.TZTGUrl) + } + + BuildConfig.is_yunti -> { + uri = Uri.parse(BZYConstants.YunTiTGUrl) + } + + else -> { + uri = Uri.parse(BZYConstants.DefTGUrl) + } } - val intent = Intent(CommonUtils.getApp(), ChangeNodeActivity::class.java) - if (!TextUtils.isEmpty(newUuid)) { - intent.putExtra(BZYConstants.MMKV_KEY_CURRENT_NODE, newUuid) - intent.putExtra(BZYConstants.EXTRA_KEY_IS_RUNING, clashRunning) - } - startActivityForResult(intent, CHECK_NODE_REQUEST_CODE) + intent.setData(uri) + startActivity(intent) drawer.close() } - findViewById(R.id.clActivity).setOnClickListener {//活动 - startActivity(Intent(this, ActivityActivity::class.java)) - drawer.close() - } - findViewById(R.id.clAccount).setOnClickListener { - startActivity(Intent(this, MineInfoActivity::class.java)) - drawer.close() - } + findViewById(R.id.tv_kefu).setOnClickListener {//客服 + startActivity(Intent(this, BZYWebViewKeFu::class.java)) - findViewById(R.id.clKf).setOnClickListener {//客服 - startActivity(Intent(this, CustomerServiceWebView::class.java)) drawer.close() } + var fds_view = findViewById(R.id.tv_fds); + fds_view.setOnClickListener {//防丢失 + startActivity(Intent(this, LossPreventionActivity::class.java)) + drawer.close() + } drawer = findViewById(R.id.drawer) iv_slider.setOnClickListener { if (containerVP.currentItem != 0) { @@ -1011,6 +887,10 @@ class NewMainActivity : BaseActivity() { drawer.openDrawer(GravityCompat.START) } } + if (BuildConfig.is_tz && BuildConfig.productId == "182269") { + telegramBtn.visibility = View.INVISIBLE + fds_view.visibility = View.INVISIBLE + } } var checkPayResultDia: MaterialDialog? = null @@ -1032,7 +912,7 @@ class NewMainActivity : BaseActivity() { public fun goBackupRechargeWeb() { startActivityForResult( - Intent(this@NewMainActivity, MemberRechargeActivity::class.java), + Intent(this@NewMainActivity, BackupRechargeActivity::class.java), REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY ) } @@ -1072,6 +952,7 @@ class NewMainActivity : BaseActivity() { checkBindAccountDia = MaterialDialog(this).show { this.cancelable(false) + cornerRadius(res = R.dimen.dp_10) customView( R.layout.bind_account_dialog_layout, scrollable = false, @@ -1101,6 +982,9 @@ class NewMainActivity : BaseActivity() { dialog.show() } + var payResultLoading: RxDialogShapeLoading? = null + private var timerJob: Job? = null + private var loadingTimeoutNum = 3 private fun showLoadingDialog(msg: String) { payResultLoading = RxDialogShapeLoading(this) payResultLoading!!.setMessage(msg) @@ -1313,42 +1197,97 @@ class NewMainActivity : BaseActivity() { } startActivity(intent) } + + public suspend fun setSub2(url: String) { + Log.d("setSub2 2") + profileBinder?.let { pm -> + Log.d("setSub2 3") + pm.queryAll().forEach { itemPro -> + Log.d("setSub2 itemPro ==>${itemPro}") + if (itemPro.name != Conf.getClashConfName(this@NewMainActivity.applicationContext)) { + Log.d("setSub2 delete ==>${itemPro.name}") + pm.delete(itemPro.uuid) + } + } + val pro = pm.queryActive() + Log.d("setSub2 4") + pro?.let { + var actname = it.name + Log.d("new main actname==>" + actname) + Log.d("setSub2 pro 已存在 ==>") + pm.setActive(it) + delay(500) + if (!TextUtils.isEmpty(pro.source)) { +// Log.d("setSub2 pro.source==>${pro.source}, url==>${url}") + if (pro.source != url) { + Log.d("setSub2 patch") + pm.patch(pro.uuid, pro.name, url, 1800000L) + pm.commit(pro.uuid) { status -> + Log.d("setSub2 updateStatus: " + Gson().toJson(status.args) + ", pro==>" + status.progress) + } + } + } + pm.update(it.uuid) + + newUuid = pro.uuid.toString(); + isSubed = true + Log.d("setSub2 setActive end") + } ?: run { + createMyProfile(pm, url) + } + } + } + + + suspend fun createMyProfile(pm: IProfileManager, url: String) { + var uuid: UUID = pm.create( + Profile.Type.Url, Conf.getClashConfName(this@NewMainActivity.applicationContext) + ) + delay(500) + pm.queryByUUID(uuid)?.let { qPro -> + pm.setActive(qPro) + pm.patch( + qPro.uuid, qPro.name, +// "https://mojie0201.xn--8stx8olrwkucjq3b.com/api/v1/client/subscribe?token=169110d2674c49604b7e5b5cea341579", +// "https://www.otcopusapp.cc/lx3af288h5i8pz380/api/v1/client/subscribe?token=d6bc98c7ea53099fa5bd1a3ea415ebb6", +// "https://reg.bazhuayujiasu.cc/api/v1/client/subscribe?token=7f0f025ab341bcec4822d2c90aadf8b0", + url, 1800000L + ) +// coroutineScope { + pm.commit(qPro.uuid) { status -> + android.util.Log.d( + Conf.TAG, + "new updateStatus: " + Gson().toJson(status.args) + ", pro==>" + status.progress + ) + } + newUuid = qPro.uuid.toString(); + isSubed = true +// } + } + } + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) + if (requestCode == REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY) { if (activityDialog != null) { activityDialog?.dismiss() } goCheckLogin() showBindAccount() - }else if(requestCode == CHECK_NODE_REQUEST_CODE){ - fragments.filterIsInstance().forEach { it.nodeChooseBase(data) } } } override fun onDestroy() { - super.onDestroy() - stopUploadTimer() - mainAtyVM.stopHeartBeat() - if(dialogDoMainChoose!=null){ - if(dialogDoMainChoose!!.isShowing){ - dialogDoMainChoose!!.dismiss() - dialogDoMainChoose=null + if (activityDialog != null) { + if(activityDialog!!.isShowing){ + activityDialog!!.dismiss() } } + super.onDestroy() + stopUploadTimer() + mainAtyVM.stopHeartBeat() } - class PageInfo { - var page = 1 - fun nextPage() { - page++ - } - fun reset() { - page = 1 - } - - val isFirstPage: Boolean - get() = page == 1 - } } \ No newline at end of file diff --git a/app/src/main/java/com/yingmao/clash/act/ProxyModeActivity.kt b/app/src/main/java/com/yingmao/clash/act/ProxyModeActivity.kt index 6a03359..92ec5cb 100644 --- a/app/src/main/java/com/yingmao/clash/act/ProxyModeActivity.kt +++ b/app/src/main/java/com/yingmao/clash/act/ProxyModeActivity.kt @@ -14,8 +14,8 @@ import com.yingmao.clash.R import com.yingmao.clash.base.BaseActivity import com.cncat.vpn.common.log.Log import com.yingmao.clash.conf.BZYConstants -import com.yingmao.clash.fragment.NewAccFragment import com.cncat.vpn.service.model.AccessControlMode +import com.yingmao.clash.fragment.home.HomeFragment import com.yingmao.clash.view.RxToast import com.yingmao.clash.view.popwindow.CommonPopupWindow import okio.ByteString.Companion.encode @@ -120,7 +120,7 @@ class ProxyModeActivity : BaseActivity() { } } llApplicationMode.setOnClickListener { - if (NewAccFragment.clashRunning) { + if (HomeFragment.clashRunning) { RxToast.info("请关闭加速后再选择."); return@setOnClickListener } @@ -207,7 +207,7 @@ class ProxyModeActivity : BaseActivity() { when (proxyMode) { ProxyMode.PAC -> { - NewAccFragment.isGlo = false + HomeFragment.isGlo = false radio_but_global.isChecked = false radio_but_pac.isChecked = true radioApplicationMode.isChecked = false @@ -218,7 +218,7 @@ class ProxyModeActivity : BaseActivity() { } ProxyMode.GLOBAL -> { - NewAccFragment.isGlo = true + HomeFragment.isGlo = true radio_but_global.isChecked = true radio_but_pac.isChecked = false radioApplicationMode.isChecked = false diff --git a/app/src/main/java/com/yingmao/clash/act/SlpashHelper.kt b/app/src/main/java/com/yingmao/clash/act/SlpashHelper.kt index ce09ec0..dbaf4cf 100644 --- a/app/src/main/java/com/yingmao/clash/act/SlpashHelper.kt +++ b/app/src/main/java/com/yingmao/clash/act/SlpashHelper.kt @@ -21,9 +21,9 @@ class SplashHelper(private val splashAtyVM: PublicViewMode) { third: (AsyncCallback) -> Unit, callback: (Boolean) -> Unit ) { - first(createCallback("getHost method success", "getHostByGithub method failed", callback) { + first(createCallback("getHost method success", "getHost method failed", callback) { second(createCallback("getHostByAWS method success", "getHostByAWS method failed", callback) { - third(createCallback("getHost method success", "getHost methods failed", callback) { + third(createCallback("getHostByGithub method success", "getHostByGithub methods failed", callback) { callback(false) // 所有方法都失败 }) }) diff --git a/app/src/main/java/com/yingmao/clash/act/SplashActivity.kt b/app/src/main/java/com/yingmao/clash/act/SplashActivity.kt index 542f6d9..6132aeb 100644 --- a/app/src/main/java/com/yingmao/clash/act/SplashActivity.kt +++ b/app/src/main/java/com/yingmao/clash/act/SplashActivity.kt @@ -54,7 +54,7 @@ import com.yingmao.clash.R import com.yingmao.clash.app.MainApplication import com.yingmao.clash.app.MainApplication.Companion.OAID import com.yingmao.clash.base.BaseActivity -import com.yingmao.clash.captcha.Captcha + import com.yingmao.clash.conf.BZYConstants import com.yingmao.clash.conf.BZYConstants.Companion.MMKV_KEY_IS_REGISTER import com.yingmao.clash.conf.BZYConstants.Companion.MMKV_KEY_NOTE_DEFAULT_PSW @@ -79,9 +79,7 @@ import com.yingmao.clash.view.dialog.DialogDoMainChoose import com.yingmao.clash.view.dialog.RxDialogSureCancel import com.yingmao.clash.view.dialog.SplashDialog import com.yingmao.clash.vm.SplashAtyVM -import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.MainScope import kotlinx.coroutines.async import kotlinx.coroutines.delay @@ -434,56 +432,7 @@ class SplashActivity : BaseActivity() { super.onStarted() } - private fun graphicVerificationDialog() { - //开启人机验证 - MaterialDialog(this).show { - this.cancelable(false) - cornerRadius(res = R.dimen.dp_10) - customView( - R.layout.graphic_verification_dialog_layout, - scrollable = false, - noVerticalPadding = true, - horizontalPadding = false - ) - val captchaSimple = findViewById(R.id.captCha) - captchaSimple.setCaptchaListener(object : Captcha.CaptchaListener { - override fun onAccess(time: Long): String { - Toast.makeText( - this@SplashActivity, - resources.getString(R.string.VerificationSuccessful), - Toast.LENGTH_SHORT - ).show() - dismiss() - val intent = Intent(this@SplashActivity, LoginActivity::class.java) - startActivity(intent) - finish() - return resources.getString(R.string.VerificationSuccessful) - .replace("%d", "$time") - } - override fun onFailed(failedCount: Int): String { - Toast.makeText( - this@SplashActivity, - resources.getString(R.string.VerificationFailed), - Toast.LENGTH_SHORT - ).show() - return resources.getString(R.string.VerificationSuccessful) - .replace("%d", "$failedCount") - } - - override fun onMaxFailed(): String { - Toast.makeText( - this@SplashActivity, - resources.getString(R.string.VerifiedOnce), - Toast.LENGTH_SHORT - ) - .show() - finish() - return resources.getString(R.string.VerifiedOnce) - } - }) - } - } private fun isNeedRegister(isNeedRegister: Boolean) { if (!BuildConfig.is_free && BuildConfig.productId.isNotEmpty()) { //渠道包都自动注册登录,广州22222也是非自动注册 @@ -677,6 +626,7 @@ class SplashActivity : BaseActivity() { val expired = checkLoginRsp.data?.expired val isPerfect = checkLoginRsp.data?.isPerfect val userCommand = checkLoginRsp.data?.userCommand + val logSwitch = checkLoginRsp.data?.logSwitch val mmkv = MMKV.defaultMMKV() mmkv.encode(BZYConstants.MMKV_KEY_VPN_EXPIRED, expired ?: true) mmkv.encode( @@ -685,11 +635,8 @@ class SplashActivity : BaseActivity() { ) mmkv.encode(BZYConstants.MMKV_KEY_IS_PERFECT, isPerfect ?: true) mmkv.encode(BZYConstants.MMKV_KEY_VPN_UserCommand, userCommand ?: "") - - + mmkv.encode(BZYConstants.MMKV_KEY_VPN_LogSwitch, logSwitch ?: "") toMainPage() - - } else { toLoginPage() } diff --git a/app/src/main/java/com/yingmao/clash/act/UIMainActivity.kt b/app/src/main/java/com/yingmao/clash/act/UIMainActivity.kt index 102b577..4d555fd 100644 --- a/app/src/main/java/com/yingmao/clash/act/UIMainActivity.kt +++ b/app/src/main/java/com/yingmao/clash/act/UIMainActivity.kt @@ -47,6 +47,7 @@ import com.yingmao.clash.net.http.HttpReqType import com.yingmao.clash.net.http.HttpStatus import com.yingmao.clash.net.http.NetService import com.yingmao.clash.net.http.entity.AppVersionCheckRsp +import com.yingmao.clash.net.http.entity.ExpensesRecordRsp import com.yingmao.clash.net.http.entity.GetActivityRsp import com.yingmao.clash.net.http.entity.PhDownloadUrlRsp import com.yingmao.clash.net.http.entity.SubscriptionRsp @@ -83,7 +84,7 @@ import java.util.UUID class UIMainActivity : BaseActivity() { private lateinit var bottomNavigationView: BottomNavigationView - private val fragments = arrayListOf() + val fragments = arrayListOf() private lateinit var mainAtyVM: MainAtyVM private var payResultLoading: RxDialogShapeLoading? = null private val clashRunning: Boolean @@ -92,19 +93,20 @@ class UIMainActivity : BaseActivity() { private var timer: Timer? = null private var uTimerTask: TimerTask? = null private var newMainActGlo: Boolean = false - private var homeFragment:HomeFragment?=null - private var settingFragment:SettingFragment?=null + private var homeFragment: HomeFragment? = null + private var settingFragment: SettingFragment? = null + @SuppressLint("SimpleDateFormat") private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss") private var activityDialog: ActivityViewDialog? = null private var checkPayResultDia: MaterialDialog? = null private var checkBindAccountDia: MaterialDialog? = null - + private val mPageInfo = PageInfo() companion object { //记录心跳失败次数 var HEART_BEAT_FAILURE_FREQUENCY = 0 const val REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY = 1000 - var isSubbed = false + var isSubed = false var newUuid: String? = null var subUrl: String? = null var clashBinder: IClashManager? = null @@ -112,6 +114,71 @@ class UIMainActivity : BaseActivity() { var isUpload: Boolean = false var hostsMem: ArrayList = ArrayList() var newMainActGlo: Boolean = false + public suspend fun setSub2(url: String) { + profileBinder?.let { pm -> + pm.queryAll().forEach { itemPro -> + Log.d("uimain setSub2 itemPro.name==${itemPro.name}") + if (itemPro.name != Conf.getClashConfName(MainApplication.getApp()?.applicationContext)) { + Log.d("setSub2 delete ==>${itemPro.name}") + pm.delete(itemPro.uuid) + } + } + var mProfile = pm.queryAll().find { + it.name == Conf.getClashConfName(MainApplication.getApp()?.applicationContext) + } + + mProfile?.let { + var actname = it.name + Log.d("new main actname==>" + actname) + Log.d("setSub2 pro 已存在 ==>") + pm.setActive(it) + delay(500) + //判断配置文件source + if (!TextUtils.isEmpty(mProfile.source)) { + Log.d("setSub2 pro.source==>${mProfile.source}, url==>${url}") + //订阅链接不同就更换 + if (mProfile.source != url) { + pm.patch( + mProfile.uuid, mProfile.name, + url, 1800000L + ) + pm.commit(mProfile.uuid) { status -> + android.util.Log.d( + Conf.TAG, + "new updateStatus: " + Gson().toJson(status.args) + ", pro==>" + status.progress + ) + } + } + } + pm.update(it.uuid) + newUuid = mProfile.uuid.toString() + isSubed = true + } ?: run { + Log.d("setSub2 go create") + val uuid: UUID = pm.create( + Profile.Type.Url, Conf.getClashConfName(MainApplication.getApp()?.applicationContext) + ) + delay(500) + pm.queryByUUID(uuid)?.let { qPro -> + pm.setActive(qPro) + pm.patch( + qPro.uuid, qPro.name, + url, 1800000L + ) + pm.commit(qPro.uuid) { status -> + android.util.Log.d( + Conf.TAG, + "new updateStatus: " + Gson().toJson(status.args) + ", pro==>" + status.progress + ) + } + newUuid = qPro.uuid.toString() + isSubed = true + } + } + } + } + var isVip:Boolean=false + } override fun onCreate(savedInstanceState: Bundle?) { @@ -130,6 +197,7 @@ class UIMainActivity : BaseActivity() { newMainActGlo = isGlobal startLog() firstEntry() + mainAtyVM.getExpensesRecord(mPageInfo) } private fun initView(savedInstanceState: Bundle?) { @@ -147,6 +215,7 @@ class UIMainActivity : BaseActivity() { if (homeFragment == null) homeFragment = HomeFragment() showFragment(homeFragment!!) } + R.id.navigation_setting -> { if (settingFragment == null) settingFragment = SettingFragment() showFragment(settingFragment!!) @@ -162,6 +231,7 @@ class UIMainActivity : BaseActivity() { transaction.replace(R.id.fragmentContainer, fragment) transaction.commit() } + private fun showFragment(fragment: Fragment) { val fragmentManager = supportFragmentManager val transaction = fragmentManager.beginTransaction() @@ -178,6 +248,7 @@ class UIMainActivity : BaseActivity() { } transaction.commit() } + override fun httpLoading(httpStatus: HttpStatus.Loading) { if (httpStatus.reqType == HttpReqType.HEARTBEAT) { Logger.d("心跳中") @@ -195,6 +266,7 @@ class UIMainActivity : BaseActivity() { } data.data.let { url -> android.util.Log.e("Data", "机场URL:=${url}") +// var url2="https://api.ymvpnpro11.cc:8700/7air2vr7ikiqzgvxz/api/v1/client/subscribe?token=22f3d75079ec6fa546c1862c4354e448" // if (url.isNotEmpty()) { // subUrl = url // lifecycleScope.launch(Dispatchers.IO) { @@ -206,13 +278,13 @@ class UIMainActivity : BaseActivity() { var pro_sub_url = MMKV.defaultMMKV().decodeString(BZYConstants.PROFILE_SUB_URL, "") // Log.d("pro_sub_url==>${pro_sub_url}") - if (!TextUtils.isEmpty(pro_sub_url)){ + if (!TextUtils.isEmpty(pro_sub_url)) { if (pro_sub_url == url) { subUrl = url } else { subUrl = pro_sub_url } - }else{ + } else { subUrl = url } lifecycleScope.launch(Dispatchers.IO) { @@ -229,7 +301,7 @@ class UIMainActivity : BaseActivity() { if (data.code == 200) { if (data.data.data.list.isNotEmpty()) { data.data.data.list[0].redirectLink.let { - if(activityDialog==null){ + if (activityDialog == null) { activityDialog = ActivityViewDialog(this, data.data.data.list[0].redirectLink) activityDialog?.setOnDialogClickListener(object : @@ -262,8 +334,10 @@ class UIMainActivity : BaseActivity() { val expired = checkLoginRsp.data.expired mmkv.encode(BZYConstants.MMKV_KEY_VPN_EXPIRED, expired ?: true) mmkv.encode(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD, nowExpireTime) - val hf = supportFragmentManager.findFragmentById(R.id.fragmentContainer) as? HomeFragment - val sf = supportFragmentManager.findFragmentById(R.id.fragmentContainer) as? SettingFragment + val hf = + supportFragmentManager.findFragmentById(R.id.fragmentContainer) as? HomeFragment + val sf = + supportFragmentManager.findFragmentById(R.id.fragmentContainer) as? SettingFragment hf?.setExpireDate() sf?.setExpireDate() checkPayResultDia?.dismiss() @@ -272,7 +346,10 @@ class UIMainActivity : BaseActivity() { } else { // RxToast.info(resources.getString(R.string.PaymentResultsStr)) } - } else { + }else if(checkLoginRsp.code == -2){ + RxToast.info(resources.getString(R.string.LoginOut)) + cleanUserInfoToLogout() + }else { RxToast.info(resources.getString(R.string.QueryFailed)) } payResultLoading?.dismiss() @@ -304,7 +381,30 @@ class UIMainActivity : BaseActivity() { } } } - + HttpReqType.EXPENSES_RECORD ->{ + if(httpStatus.rsp is ExpensesRecordRsp){ + httpStatus.rsp.let { expensesRecordRsp -> + if(expensesRecordRsp.code == "1000"){ + if(expensesRecordRsp.data != null) { + val expensesRecordList = expensesRecordRsp.data.expensesRecords + if(expensesRecordList!=null){ + if(expensesRecordList.size>0){ + isVip=true + }else{ + isVip=false + } + }else{ + isVip=false + } + }else{ + isVip=false + } + }else{ + isVip=false + } + } + } + } else -> { } @@ -342,6 +442,7 @@ class UIMainActivity : BaseActivity() { } } } + private fun showLoadingDialog(msg: String) { payResultLoading = RxDialogShapeLoading(this) payResultLoading!!.setMessage(msg) @@ -355,10 +456,15 @@ class UIMainActivity : BaseActivity() { MMKV.defaultMMKV().removeValueForKey(BZYConstants.NODE_SELECTED_NAME_KEY) MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_VPN_UserCommand) MMKV.defaultMMKV().removeValueForKey(BZYConstants.NODE_All_ITEM_NAME_KEY) + MMKV.defaultMMKV().removeValueForKey(BZYConstants.PROFILE_SUB_URL) + MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_Switch_Finsh_Set) Log.d("cleanUserInfo clashRunning==>${clashRunning}") + //清除源切换记录 + if (clashRunning) { fragments.filterIsInstance().forEach { it.stopClash() } } + isSubed=false stopUploadTimer() mainAtyVM.stopHeartBeat() cleanProfile() @@ -367,6 +473,7 @@ class UIMainActivity : BaseActivity() { } fun startUploadTimer() { + stopUploadTimer() if (timer == null) { timer = Timer() uTimerTask = object : TimerTask() { @@ -400,61 +507,7 @@ class UIMainActivity : BaseActivity() { } } - private suspend fun setSub2(url: String) { - profileBinder?.let { pm -> - pm.queryAll().forEach { itemPro -> - if (itemPro.name != Conf.getClashConfName(this@UIMainActivity.applicationContext)) { - pm.delete(itemPro.uuid) - } - } - val pro = pm.queryActive() - pro?.let { - pm.setActive(it) - delay(500) - //判断配置文件source - if (!TextUtils.isEmpty(pro.source)) { - Log.d("setSub2 pro.source==>${pro.source}, url==>${url}") - //订阅链接不同就更换 - if (pro.source != url) { - pm.patch( - pro.uuid, pro.name, - url, 1800000L - ) - pm.commit(pro.uuid) { status -> - android.util.Log.d( - Conf.TAG, - "new updateStatus: " + Gson().toJson(status.args) + ", pro==>" + status.progress - ) - } - } - } - pm.update(it.uuid) - newUuid = pro.uuid.toString() - isSubbed = true - } ?: run { - val uuid: UUID = pm.create( - Profile.Type.Url, Conf.getClashConfName(this@UIMainActivity.applicationContext) - ) - delay(500) - pm.queryByUUID(uuid)?.let { qPro -> - pm.setActive(qPro) - pm.patch( - qPro.uuid, qPro.name, - url, 1800000L - ) - pm.commit(qPro.uuid) { status -> - android.util.Log.d( - Conf.TAG, - "new updateStatus: " + Gson().toJson(status.args) + ", pro==>" + status.progress - ) - } - newUuid = qPro.uuid.toString() - isSubbed = true - } - } - } - } private fun startLog() { @@ -558,7 +611,7 @@ class UIMainActivity : BaseActivity() { override fun onDestroy() { if (activityDialog != null) { - if(activityDialog!!.isShowing){ + if (activityDialog!!.isShowing) { activityDialog!!.dismiss() } @@ -681,4 +734,38 @@ class UIMainActivity : BaseActivity() { REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY ) } + private fun cleanUserInfoToLogout() { + MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_PH_TOKEN) + MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_TOKEN) + MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_CURRENT_NODE) + MMKV.defaultMMKV().removeValueForKey(BZYConstants.NODE_SELECTED_NAME_KEY) + MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_VPN_UserCommand) + MMKV.defaultMMKV().removeValueForKey(BZYConstants.NODE_All_ITEM_NAME_KEY) + MMKV.defaultMMKV().removeValueForKey(BZYConstants.PROFILE_SUB_URL) + Log.d("cleanUserInfo clashRunning==>${clashRunning}") + if (clashRunning) { + fragments.filterIsInstance().forEach { it.stopClash() } + } + isSubed=false + stopUploadTimer() + mainAtyVM.stopHeartBeat() + cleanProfile() + val intent=Intent(CommonUtils.getApp(), LoginActivity::class.java) + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) + startActivity(intent) + finish() + } + class PageInfo { + var page = 1 + fun nextPage() { + page++ + } + + fun reset() { + page = 1 + } + + val isFirstPage: Boolean + get() = page == 1 + } } \ No newline at end of file diff --git a/app/src/main/java/com/yingmao/clash/act/ZFBTXActivity.kt b/app/src/main/java/com/yingmao/clash/act/ZFBTXActivity.kt deleted file mode 100644 index 995e094..0000000 --- a/app/src/main/java/com/yingmao/clash/act/ZFBTXActivity.kt +++ /dev/null @@ -1,143 +0,0 @@ -package com.yingmao.clash.act - -import android.os.Bundle -import android.view.View -import android.widget.EditText -import android.widget.TextView -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.observe - -import com.yingmao.clash.view.dialog.RxDialogShapeLoading - -import com.tencent.mmkv.MMKV -import com.yingmao.clash.R -import com.yingmao.clash.base.BaseActivity -import com.yingmao.clash.conf.BZYConstants -import com.yingmao.clash.net.http.HttpReqType -import com.yingmao.clash.net.http.HttpStatus -import com.yingmao.clash.net.http.entity.AppDataInfoRsp -import com.yingmao.clash.net.http.entity.GetSMSCodeRsp -import com.yingmao.clash.view.RxToast - -class ZFBTXActivity : BaseActivity() { - - private lateinit var et_zfb_account: EditText - private lateinit var et_tixian_amount: EditText - private lateinit var tv_can_reward_amount: TextView - private var rewardAmount: String = "" - private lateinit var txAmount: String - private var isTiXia = false - private var zfbAccount = "" - private lateinit var rxDialogShapeLoading: RxDialogShapeLoading - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.layout_activity_zfbtx) - showTitleBar("现金奖励提现") - initView() - } - - private fun initView() { - val viewModel = ViewModelProvider(this).get(ZFBTXAtyVM::class.java) - viewModel.statusData.observe(this) { - when (it) { - is HttpStatus.Loading -> { - rxDialogShapeLoading = RxDialogShapeLoading(this) - if (it.reqType == HttpReqType.APPDATAINFO) { - rxDialogShapeLoading.setMessage("正在获取可提现余额...") - } else { - rxDialogShapeLoading.setMessage("正在提现...") - } - rxDialogShapeLoading.show() - } - is HttpStatus.Success -> { - rxDialogShapeLoading.cancel() - if (it.reqType == HttpReqType.APPDATAINFO) { - (it.rsp as AppDataInfoRsp).let { appDataRsp -> - if (appDataRsp.code == 1000) { - rewardAmount = appDataRsp.data?.rewardTotalAmount!! - tv_can_reward_amount.text = "${rewardAmount} 元" - tv_can_reward_amount.isClickable = false - if (isTiXia) { - val phone = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME,"")!! - viewModel.appRewardAmount(phone, txAmount, zfbAccount) - } - } else { - RxToast.warning("获取可提现金额失败,请重试") - isTiXia = false - tv_can_reward_amount.text = "重试" - tv_can_reward_amount.setOnClickListener { - MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME) - ?.let { it1 -> viewModel.appDataInfo(it1) } - } - } - } - } else { - (it.rsp as GetSMSCodeRsp).let { rsp -> - if (rsp.code == 1000) { - RxToast.success("提现发起成功,请等待到账") - setResult(101) - finish() - // viewModel.appDataInfo(MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME)) - } else { - RxToast.warning("提现失败:${rsp.message}") - } - } - } - } - is HttpStatus.Failure -> { - rxDialogShapeLoading.cancel() - if (it.reqType == HttpReqType.APPDATAINFO) { - RxToast.warning("获取可提现金额失败,请检查网络") - tv_can_reward_amount.setOnClickListener { - MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME) - ?.let { it1 -> viewModel.appDataInfo(it1) } - } - } else { - RxToast.warning("提现失败,请检查网络") - } - } - } - } - - et_zfb_account = findViewById(R.id.et_zfb_account) - tv_can_reward_amount = findViewById(R.id.tv_can_reward_amount) - et_tixian_amount = findViewById(R.id.et_tixian_amount) - - MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME) - ?.let { viewModel.appDataInfo(it) } - - - findViewById(R.id.btn_tixian).setOnClickListener { - zfbAccount = et_zfb_account.text.trim().toString() - txAmount = et_tixian_amount.text.trim().toString() - if (zfbAccount.isEmpty() || zfbAccount.length < 3) { - RxToast.warning("请输入有效的支付宝账号") - } else { - - if (!isNumber(txAmount)) { - RxToast.warning("请输入有效的金额") - return@setOnClickListener - } - - if (rewardAmount.isEmpty()) { - RxToast.warning("未能获取到可提现金额,请重试") - return@setOnClickListener - } - - if (txAmount.toFloat() > rewardAmount.toFloat()) { - RxToast.warning("已超过可提现金额") - return@setOnClickListener - } - - isTiXia = true - MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME) - ?.let { it1 -> viewModel.appDataInfo(it1) } - } - } - } - - fun isNumber(str: String): Boolean { - val regex = Regex("^[1-9]\\d*(\\.[0-9]+)?$") - return regex.matches(str) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/yingmao/clash/act/ZFBTXAtyVM.kt b/app/src/main/java/com/yingmao/clash/act/ZFBTXAtyVM.kt deleted file mode 100644 index d3047c7..0000000 --- a/app/src/main/java/com/yingmao/clash/act/ZFBTXAtyVM.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.yingmao.clash.act - -import com.tencent.mmkv.MMKV -import com.yingmao.clash.base.PublicViewMode -import com.yingmao.clash.conf.BZYConstants -import com.yingmao.clash.net.http.HttpApi -import com.yingmao.clash.net.http.HttpReqType -import com.yingmao.clash.net.http.NetService - -class ZFBTXAtyVM : PublicViewMode() { - - fun appRewardAmount(phone: String, rewardAmount: String, payAccount: String) { - val httpApi = NetService.instances.createHttps(HttpApi::class.java) - val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN,"")!! - val params = mutableMapOf( - "phoneNumber" to phone, - "rewardAmount" to rewardAmount, - "payAccount" to payAccount, - "phToken" to phToken, - ) - doAsync(HttpReqType.APPREWARDAMOUNT) { httpApi.appRewardAmount(params) } - } - - fun appDataInfo(phone: String) { - val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN,"")!! - val params = mutableMapOf( - "phoneNumber" to phone, - "phToken" to phToken - ) - val httpApi = NetService.instances.createHttps(HttpApi::class.java) - doAsync(HttpReqType.APPDATAINFO) { httpApi.appDataInfo(params) } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/yingmao/clash/app/MainApplication.kt b/app/src/main/java/com/yingmao/clash/app/MainApplication.kt index 1aec76f..2466c41 100644 --- a/app/src/main/java/com/yingmao/clash/app/MainApplication.kt +++ b/app/src/main/java/com/yingmao/clash/app/MainApplication.kt @@ -170,7 +170,21 @@ class MainApplication : Application() { BaiduAction.setActivateInterval(this, 7) } + fun logException(e: Throwable) { + val log = StringWriter().also { e.printStackTrace(PrintWriter(it)) }.toString() + Log.d("MainApplication logException==>${log}") +// val directory: File? = applicationContext.getExternalFilesDir("CrashLog") +// if (directory != null) { +// if (!directory.isDirectory) { +// directory.delete() +// } +// if (!directory.exists()) { +// directory.mkdirs() +// } +// } +// File(directory, "crash_${System.currentTimeMillis()}.log").writeText(log) + } fun updateActivity(language: String, locale: Locale) { MMKV.defaultMMKV().encode(BZYConstants.languageInfo, language) val resources = this.resources diff --git a/app/src/main/java/com/yingmao/clash/base/BaseActivity.kt b/app/src/main/java/com/yingmao/clash/base/BaseActivity.kt index 7757071..10671f8 100644 --- a/app/src/main/java/com/yingmao/clash/base/BaseActivity.kt +++ b/app/src/main/java/com/yingmao/clash/base/BaseActivity.kt @@ -6,6 +6,9 @@ import android.content.Context import android.content.Intent import android.content.pm.ActivityInfo import android.content.res.Configuration +import android.net.ConnectivityManager +import android.net.NetworkCapabilities +import android.os.Build import android.os.Bundle import android.text.TextUtils import android.util.Log @@ -13,13 +16,14 @@ import android.view.View import android.view.ViewGroup import android.view.inputmethod.InputMethodManager import android.widget.* +import androidx.annotation.RequiresApi import androidx.appcompat.app.AppCompatActivity +import androidx.collection.arraySetOf import androidx.lifecycle.ViewModelProvider import com.orhanobut.logger.Logger import com.tencent.mmkv.MMKV import com.yingmao.clash.BuildConfig import com.yingmao.clash.R -import com.yingmao.clash.act.MainActivity import com.yingmao.clash.conf.BZYConstants import com.yingmao.clash.conf.Conf import com.cncat.vpn.core.bridge.ClashException @@ -55,6 +59,10 @@ open class BaseActivity : AppCompatActivity(), CoroutineScope by MainScope(), Br var baseLoading: RxDialogShapeLoading? = null val serStore by lazy { ServiceStore(this) } + companion object { +// var switchFinshSet: MutableSet? = null + } + sealed class RequestTunnel { object ReloadAll : RequestTunnel() object ReLaunch : RequestTunnel() @@ -263,10 +271,11 @@ open class BaseActivity : AppCompatActivity(), CoroutineScope by MainScope(), Br } } - fun selectServer(){ + fun selectServer() { val mmkv = MMKV.defaultMMKV() val routerHost = mmkv.decodeStringSet(BZYConstants.MMKV_KEY_ROUTER_HOST, HashSet()) } + @Synchronized fun switchServer(): Boolean { var isChange = false @@ -305,6 +314,16 @@ open class BaseActivity : AppCompatActivity(), CoroutineScope by MainScope(), Br return isChange } + @RequiresApi(Build.VERSION_CODES.M) + fun isNetworkAvailable(context: Context): Boolean { + val connectivityManager = + context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + + val network = connectivityManager.activeNetwork ?: return false + val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false + + return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + } @Synchronized fun switchServer2(): Boolean { var isChange = false diff --git a/app/src/main/java/com/yingmao/clash/base/BaseNotTitleActivity.kt b/app/src/main/java/com/yingmao/clash/base/BaseNotTitleActivity.kt index 67da8dd..57e0850 100644 --- a/app/src/main/java/com/yingmao/clash/base/BaseNotTitleActivity.kt +++ b/app/src/main/java/com/yingmao/clash/base/BaseNotTitleActivity.kt @@ -15,7 +15,6 @@ import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.ViewModelProvider import com.orhanobut.logger.Logger import com.yingmao.clash.R -import com.yingmao.clash.act.MainActivity import com.cncat.vpn.common.log.Log //import com.yingmao.clash.design.model.DarkMode //import com.yingmao.clash.design.store.UiStore diff --git a/app/src/main/java/com/yingmao/clash/base/BaseViewMode.kt b/app/src/main/java/com/yingmao/clash/base/BaseViewMode.kt index 27ece1a..dc93b8b 100644 --- a/app/src/main/java/com/yingmao/clash/base/BaseViewMode.kt +++ b/app/src/main/java/com/yingmao/clash/base/BaseViewMode.kt @@ -26,8 +26,11 @@ import okhttp3.RequestBody import okhttp3.RequestBody.Companion.toRequestBody import org.json.JSONArray import org.json.JSONObject +import java.io.File import java.io.PrintWriter import java.io.StringWriter +import java.text.SimpleDateFormat +import java.util.Locale open class BaseViewMode : ViewModel() { @@ -68,11 +71,21 @@ open class BaseViewMode : ViewModel() { } } } + fun postErrLog(phone: String) { - fun doAsync2(reqType: HttpReqType, doInAsync: suspend () -> Any) { + val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN,"")!! + val params = mutableMapOf( + "phoneNumber" to phone, + "phToken" to phToken + ) + + } + fun doAsync2(reqType: HttpReqType, doInAsync: suspend () -> Any?) { viewModelScope.launch( - CoroutineExceptionHandler { _, - exception -> + CoroutineExceptionHandler { + _, + exception, + -> Log.e("BaseViewMode_doAsync:${exception.toString()}", exception) statusData.value = if (exception.message.isNullOrBlank()) HttpStatus.Failure( @@ -93,7 +106,7 @@ open class BaseViewMode : ViewModel() { Log.i("请求结果:$rsp") statusData.value = HttpStatus.Success(reqType, rsp) } catch (e: Exception) { - Log.e( "网络请求异常",e) + Log.e("网络请求异常", e) statusData.value = HttpStatus.Failure(reqType, e.toString()) } } @@ -131,11 +144,13 @@ open class BaseViewMode : ViewModel() { fun doAsyncDelay( reqType: HttpReqType, delayTimeMillis: Long, - doInAsync: suspend () -> BaseRsp + doInAsync: suspend () -> BaseRsp, ) { viewModelScope.launch( - CoroutineExceptionHandler { _, - exception -> + CoroutineExceptionHandler { + _, + exception, + -> Log.e("BaseViewMode_doAsyncDelay:${exception.toString()}", exception) statusData.value = if (exception.message.isNullOrBlank()) HttpStatus.Failure( @@ -158,7 +173,7 @@ open class BaseViewMode : ViewModel() { Log.i("请求结果:$rsp") statusData.value = HttpStatus.Success(reqType, rsp) } catch (e: Exception) { - Log.e( "网络请求异常",e) + Log.e("网络请求异常", e) // statusData.value = HttpStatus.Failure(reqType,e.toString()) } } @@ -166,8 +181,10 @@ open class BaseViewMode : ViewModel() { fun doAsyncStrResult(reqType: HttpReqType, doInAsync: suspend () -> String) { viewModelScope.launch( - CoroutineExceptionHandler { _, - exception -> + CoroutineExceptionHandler { + _, + exception, + -> Log.e("BaseViewMode_doAsyncStrResult:${exception.toString()}", exception) @@ -179,7 +196,7 @@ open class BaseViewMode : ViewModel() { val rsp = result.await() Log.i("请求结果:$rsp") } catch (e: Exception) { - Log.e( "网络请求异常",e) + Log.e("网络请求异常", e) } } } @@ -187,11 +204,13 @@ open class BaseViewMode : ViewModel() { fun doAsyncEncodeStr( reqType: HttpReqType, classOfT: Class, - doInAsync: suspend () -> String + doInAsync: suspend () -> String, ) { viewModelScope.launch( - CoroutineExceptionHandler() { _, - exception -> + CoroutineExceptionHandler() { + _, + exception, + -> Log.e("BaseViewMode_doAsyncEncodeStr:${exception.toString()}", exception) statusData.value = if (exception.message.isNullOrBlank()) HttpStatus.Failure( @@ -221,20 +240,22 @@ open class BaseViewMode : ViewModel() { statusData.value = HttpStatus.Success(reqType, rsp) } } catch (e: Exception) { - Log.e("网络请求异常",e) + Log.e("网络请求异常", e) throw e - statusData.value = HttpStatus.Failure(reqType,e.toString()) + statusData.value = HttpStatus.Failure(reqType, e.toString()) } } } suspend fun doAsyncEncodeStrBg( classOfT: Class, - doInAsync: suspend () -> String + doInAsync: suspend () -> String, ): BaseRsp? { return viewModelScope.async( - CoroutineExceptionHandler() { _, - exception -> + CoroutineExceptionHandler() { + _, + exception, + -> Log.e("BaseViewMode_doAsyncEncodeStrBg:${exception.toString()}", exception) }) { @@ -247,7 +268,7 @@ open class BaseViewMode : ViewModel() { val rsp = Gson().fromJson(decodeRspStr, classOfT) return@async rsp } catch (e: Exception) { - Log.e("网络请求异常",e) + Log.e("网络请求异常", e) } return@async null }.await() @@ -262,7 +283,7 @@ open class BaseViewMode : ViewModel() { } result.await() } catch (e: Exception) { - Log.e("网络请求异常",e) + Log.e("网络请求异常", e) } } } diff --git a/app/src/main/java/com/yingmao/clash/base/PublicViewMode.kt b/app/src/main/java/com/yingmao/clash/base/PublicViewMode.kt index 29ddd95..52804fd 100644 --- a/app/src/main/java/com/yingmao/clash/base/PublicViewMode.kt +++ b/app/src/main/java/com/yingmao/clash/base/PublicViewMode.kt @@ -30,7 +30,7 @@ open class PublicViewMode : BaseViewMode() { } BuildConfig.is_tz -> { - rt.getTzHostGithub() + rt.getTzHostTZ() } BuildConfig.is_yunti -> { @@ -38,7 +38,7 @@ open class PublicViewMode : BaseViewMode() { } else -> { - rt.getBzyHostGithub() + rt.getBzyHostDef() } } host.takeIf { it.isNotEmpty() }?.let { diff --git a/app/src/main/java/com/yingmao/clash/captcha/BitmapLoaderTask.java b/app/src/main/java/com/yingmao/clash/captcha/BitmapLoaderTask.java deleted file mode 100644 index fbf2318..0000000 --- a/app/src/main/java/com/yingmao/clash/captcha/BitmapLoaderTask.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.yingmao.clash.captcha; - -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.os.AsyncTask; - -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; - -/** - * 网络加载图片的Task类 - * - */ - -class BitmapLoaderTask extends AsyncTask { - - private Callback callback; - - public BitmapLoaderTask(Callback callback) { - this.callback = callback; - } - - interface Callback{ - void result(Bitmap bitmap); - } - @Override - protected Bitmap doInBackground(String... params) { - Bitmap result = null; - URL url = null; - HttpURLConnection conn = null; - InputStream is = null; - try { - url = new URL(params[0]); - conn = (HttpURLConnection) url.openConnection(); - conn.setRequestMethod("GET"); - int code = conn.getResponseCode(); - if (code == 200) { - is = conn.getInputStream(); - result = BitmapFactory.decodeStream(is); - } - } catch (MalformedURLException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } finally { - try { - if (is != null) { - is.close(); - } - if (conn != null) { - conn.disconnect(); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - return result; - } - - @Override - protected void onPostExecute(Bitmap bitmap) { - super.onPostExecute(bitmap); - callback.result(bitmap); - } -} diff --git a/app/src/main/java/com/yingmao/clash/captcha/Captcha.java b/app/src/main/java/com/yingmao/clash/captcha/Captcha.java deleted file mode 100644 index fd55251..0000000 --- a/app/src/main/java/com/yingmao/clash/captcha/Captcha.java +++ /dev/null @@ -1,352 +0,0 @@ -package com.yingmao.clash.captcha; - -import android.animation.Animator; -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.os.AsyncTask; - -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.view.View; -import android.view.animation.AccelerateDecelerateInterpolator; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.SeekBar; -import android.widget.TextView; - -import androidx.annotation.AttrRes; -import androidx.annotation.DrawableRes; -import androidx.annotation.IntDef; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.yingmao.clash.R; - -/** - * Created by luozhanming on 2018/1/17. - */ - -public class Captcha extends LinearLayout { - - //控件成员 - private PictureVertifyView vertifyView; //拼图块 - private TextSeekbar seekbar; //滑动条块 - private View accessSuccess, accessFailed; //验证成功/失败显示的视图 - private TextView accessText, accessFailedText; //验证成功/失败显示的文字 - private ImageView refreshView; //刷新按钮 - //控件属性 - private int drawableId = -1; //验证图片资源id - private int progressDrawableId; //滑动条背景id - private int thumbDrawableId; //滑动条滑块id - private int mMode; //控件验证模式(有滑动条/无滑动条) - private int maxFailedCount; //最大失败次数 - private int failCount; //已失败次数 - private int blockSize; //拼图缺块大小 - - //处理滑动条逻辑 - private boolean isResponse; - private boolean isDown; - - private CaptchaListener mListener; - - private BitmapLoaderTask mTask; - /** - * 带滑动条验证模式 - */ - public static final int MODE_BAR = 1; - /** - * 不带滑动条验证,手触模式 - */ - public static final int MODE_NONBAR = 2; - - @IntDef(value = {MODE_BAR, MODE_NONBAR}) - public @interface Mode { - } - - - public interface CaptchaListener { - - /** - * Called when captcha access. - * - * @param time cost of access time - * @return text to show,show default when return null - */ - String onAccess(long time); - - /** - * Called when captcha failed. - * - * @param failCount fail count - * @return text to show,show default when return null - */ - String onFailed(int failCount); - - /** - * Called when captcha failed - * - * @return text to show,show default when return null - */ - String onMaxFailed(); - - } - - - public Captcha(@NonNull Context context) { - super(context); - } - - public Captcha(@NonNull Context context, @Nullable AttributeSet attrs) { - this(context, attrs, 0); - } - - public Captcha(@NonNull final Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) { - super(context, attrs, defStyleAttr); - TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.Captcha); -// drawableId = typedArray.getResourceId(R.styleable.Captcha_src, R.drawable.gv_icon); - progressDrawableId = typedArray.getResourceId(R.styleable.Captcha_progressDrawable, R.drawable.po_seekbar); - thumbDrawableId = typedArray.getResourceId(R.styleable.Captcha_thumbDrawable,R.drawable.thumb); - mMode = typedArray.getInteger(R.styleable.Captcha_mode, MODE_BAR); - maxFailedCount = typedArray.getInteger(R.styleable.Captcha_max_fail_count, 3); - blockSize = typedArray.getDimensionPixelSize(R.styleable.Captcha_blockSize, Utils.dp2px(getContext(), 50)); - typedArray.recycle(); - init(); - } - - - private void init() { - View parentView = LayoutInflater.from(getContext()).inflate(R.layout.container, this, true); - vertifyView = (PictureVertifyView) parentView.findViewById(R.id.vertifyView); - seekbar = (TextSeekbar) parentView.findViewById(R.id.seekbar); - accessSuccess = parentView.findViewById(R.id.accessRight); - accessFailed = parentView.findViewById(R.id.accessFailed); - accessText = (TextView) parentView.findViewById(R.id.accessText); - accessFailedText = (TextView) parentView.findViewById(R.id.accessFailedText); - refreshView = (ImageView) parentView.findViewById(R.id.refresh); - setMode(mMode); - if(drawableId!=-1){ - vertifyView.setImageResource(drawableId); - } - setBlockSize(blockSize); - vertifyView.callback(new PictureVertifyView.Callback() { - @Override - public void onSuccess(long time) { - if (mListener != null) { - String s = mListener.onAccess(time); - if (s != null) { - accessText.setText(s); - } else {//默认文案 - accessText.setText(String.format(getResources().getString(R.string.vertify_access), time)); - } - } - accessSuccess.setVisibility(VISIBLE); - accessFailed.setVisibility(GONE); - } - - @Override - public void onFailed() { - seekbar.setEnabled(false); - vertifyView.setTouchEnable(false); - failCount = failCount > maxFailedCount ? maxFailedCount : failCount + 1; - accessFailed.setVisibility(VISIBLE); - accessSuccess.setVisibility(GONE); - if (mListener != null) { - if (failCount == maxFailedCount) { - String s = mListener.onMaxFailed(); - if (s != null) { - accessFailedText.setText(s); - } else {//默认文案 - accessFailedText.setText(String.format(getResources().getString(R.string.vertify_failed), maxFailedCount - failCount)); - } - } else { - String s = mListener.onFailed(failCount); - if (s != null) { - accessFailedText.setText(s); - } else {//默认文案 - accessFailedText.setText(String.format(getResources().getString(R.string.vertify_failed), maxFailedCount - failCount)); - } - } - } - } - - }); - setSeekBarStyle(progressDrawableId, thumbDrawableId); - //用于处理滑动条渐滑逻辑 - seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if (isDown) { //手指按下 - isDown = false; - if (progress > 10) { //按下位置不正确 - isResponse = false; - } else { - isResponse = true; - accessFailed.setVisibility(GONE); - vertifyView.down(0); - } - } - if (isResponse) { - vertifyView.move(progress); - } else { - seekBar.setProgress(0); - } - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - isDown = true; - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - if (isResponse) { - vertifyView.loose(); - } - } - }); - refreshView.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - startRefresh(v); - } - }); - } - - private void startRefresh(View v) { - //点击刷新按钮,启动动画 - v.animate().rotationBy(360).setDuration(500) - .setInterpolator(new AccelerateDecelerateInterpolator()) - .setListener(new Animator.AnimatorListener() { - @Override - public void onAnimationStart(Animator animation) { - - } - - @Override - public void onAnimationEnd(Animator animation) { - reset(false); - } - - @Override - public void onAnimationCancel(Animator animation) { - - } - - @Override - public void onAnimationRepeat(Animator animation) { - - } - }); - } - - - public void setCaptchaListener(CaptchaListener listener) { - this.mListener = listener; - } - - public void setCaptchaStrategy(CaptchaStrategy strategy) { - if (strategy != null) { - vertifyView.setCaptchaStrategy(strategy); - } - } - - public void setSeekBarStyle(@DrawableRes int progressDrawable, @DrawableRes int thumbDrawable) { - seekbar.setProgressDrawable(getResources().getDrawable(progressDrawable)); - seekbar.setThumb(getResources().getDrawable(thumbDrawable)); - seekbar.setThumbOffset(0); - } - - /** - * 设置滑块图片大小,单位px - */ - public void setBlockSize(int blockSize) { - vertifyView.setBlockSize(blockSize); - } - - /** - * 设置滑块验证模式 - */ - public void setMode(@Mode int mode) { - this.mMode = mode; - vertifyView.setMode(mode); - if (mMode == MODE_NONBAR) { - seekbar.setVisibility(GONE); - vertifyView.setTouchEnable(true); - } else { - seekbar.setVisibility(VISIBLE); - seekbar.setEnabled(true); - } - hideText(); - } - - public int getMode() { - return this.mMode; - } - - public void setMaxFailedCount(int count) { - this.maxFailedCount = count; - } - - public int getMaxFailedCount() { - return this.maxFailedCount; - } - - - public void setBitmap(int drawableId) { - Bitmap bitmap = BitmapFactory.decodeResource(getResources(), drawableId); - setBitmap(bitmap); - } - - public void setBitmap(Bitmap bitmap) { - vertifyView.setImageBitmap(bitmap); - reset(false); - } - - public void setBitmap(String url) { - mTask = new BitmapLoaderTask(new BitmapLoaderTask.Callback() { - @Override - public void result(Bitmap bitmap) { - setBitmap(bitmap); - } - }); - mTask.execute(url); - } - - @Override - protected void onDetachedFromWindow() { - if(mTask!=null&&mTask.getStatus().equals(AsyncTask.Status.RUNNING)){ - mTask.cancel(true); - } - super.onDetachedFromWindow(); - } - - /** - * 复位 - * @param clearFailed 是否清除失败次数 - */ - public void reset(boolean clearFailed) { - hideText(); - vertifyView.reset(); - if (clearFailed) { - failCount = 0; - } - if (mMode == MODE_BAR) { - seekbar.setEnabled(true); - seekbar.setProgress(0); - } else { - vertifyView.setTouchEnable(true); - } - } - - /** - * 隐藏成功失败文字显示 - * */ - public void hideText() { - accessFailed.setVisibility(GONE); - accessSuccess.setVisibility(GONE); - } - - -} diff --git a/app/src/main/java/com/yingmao/clash/captcha/CaptchaStrategy.java b/app/src/main/java/com/yingmao/clash/captcha/CaptchaStrategy.java deleted file mode 100644 index c9f1a1c..0000000 --- a/app/src/main/java/com/yingmao/clash/captcha/CaptchaStrategy.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.yingmao.clash.captcha; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Path; - -/** - * Captcha的拼图区域策咯 - * - */ - -public abstract class CaptchaStrategy { - - protected Context mContext; - - public CaptchaStrategy(Context ctx) { - this.mContext = ctx; - } - - protected Context getContext() { - return mContext; - } - - /** - * 定义缺块的形状 - * - * @param blockSize 单位dp,注意转化为px - * @return path of the shape - */ - public abstract Path getBlockShape(int blockSize); - - /** - * 定义缺块的位置信息 - * - * @param width picture width unit:px - * @param height picture height unit:px - * @param blockSize - * @return position info of the block - */ - public abstract PositionInfo getBlockPostionInfo(int width, int height, int blockSize); - - /** - * 定义滑块图片的位置信息(只有设置为无滑动条模式有用) - * - * @param width picture width - * @param height picture height - * @return position info of the block - */ - public PositionInfo getPositionInfoForSwipeBlock(int width, int height, int blockSize){ - return getBlockPostionInfo(width,height,blockSize); - } - - /** - * 获得缺块阴影的Paint - */ - public abstract Paint getBlockShadowPaint(); - - /** - * 获得滑块图片的Paint - */ - public abstract Paint getBlockBitmapPaint(); - - /** - * 装饰滑块图片,在绘制图片后执行,即绘制滑块前景 - */ - public void decoreateSwipeBlockBitmap(Canvas canvas, Path shape) { - - } -} diff --git a/app/src/main/java/com/yingmao/clash/captcha/DefaultCaptchaStrategy.java b/app/src/main/java/com/yingmao/clash/captcha/DefaultCaptchaStrategy.java deleted file mode 100644 index 46862f5..0000000 --- a/app/src/main/java/com/yingmao/clash/captcha/DefaultCaptchaStrategy.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.yingmao.clash.captcha; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.DashPathEffect; -import android.graphics.Paint; -import android.graphics.Path; - -import androidx.annotation.NonNull; - -import java.util.Random; - -/** - * 默认CaptchaStrategy - * - */ - -public class DefaultCaptchaStrategy extends CaptchaStrategy { - - public DefaultCaptchaStrategy(Context ctx) { - super(ctx); - } - - @Override - public Path getBlockShape(int blockSize) { - int gap = (int) (blockSize/5f); - Path path = new Path(); - path.moveTo(0, gap); - path.rLineTo(blockSize/2.5f, 0); - path.rLineTo(0, -gap); - path.rLineTo(gap, 0); - path.rLineTo(0, gap); - path.rLineTo(2 * gap, 0); - path.rLineTo(0, 4 * gap); - path.rLineTo(-5 * gap, 0); - path.rLineTo(0, -1.5f * gap); - path.rLineTo(gap, 0); - path.rLineTo(0, -gap); - path.rLineTo(-gap, 0); - path.close(); - return path; - } - - @Override - public @NonNull PositionInfo getBlockPostionInfo(int width, int height, int blockSize) { - Random random = new Random(); - int left = random.nextInt(width - blockSize +1); - //Avoid robot frequently and quickly click the start point to access the captcha. - if (left < blockSize) { - left = blockSize; - } - int top = random.nextInt(height - blockSize +1); - if (top < 0) { - top = 0; - } - return new PositionInfo(left, top); - } - - @Override - public @NonNull PositionInfo getPositionInfoForSwipeBlock(int width, int height, int blockSize) { - Random random = new Random(); - int left = random.nextInt(width - blockSize+1); - int top = random.nextInt(height - blockSize+1); - if (top < 0) { - top = 0; - } - return new PositionInfo(left, top); - } - - @Override - public Paint getBlockShadowPaint() { - Paint shadowPaint = new Paint(); - shadowPaint.setColor(Color.parseColor("#000000")); - shadowPaint.setAlpha(165); - return shadowPaint; - } - - @Override - public Paint getBlockBitmapPaint() { - Paint paint = new Paint(); - return paint; - } - - - @Override - public void decoreateSwipeBlockBitmap(Canvas canvas, Path shape) { - Paint paint = new Paint(); - paint.setColor(Color.parseColor("#FFFFFF")); - paint.setStyle(Paint.Style.STROKE); - paint.setStrokeWidth(10); - paint.setPathEffect(new DashPathEffect(new float[]{20,20},10)); - Path path = new Path(shape); - canvas.drawPath(path,paint); - } -} diff --git a/app/src/main/java/com/yingmao/clash/captcha/PictureVertifyView.java b/app/src/main/java/com/yingmao/clash/captcha/PictureVertifyView.java deleted file mode 100644 index eaa97c9..0000000 --- a/app/src/main/java/com/yingmao/clash/captcha/PictureVertifyView.java +++ /dev/null @@ -1,304 +0,0 @@ -package com.yingmao.clash.captcha; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Path; -import android.util.AttributeSet; -import android.view.MotionEvent; -import android.view.View; - -import androidx.annotation.Nullable; -import androidx.appcompat.widget.AppCompatImageView; - -/** - * 拼图区域控件 - * - */ - -class PictureVertifyView extends AppCompatImageView { - - //状态码 - private static final int STATE_DOWN = 1; - private static final int STATE_MOVE = 2; - private static final int STATE_LOOSEN = 3; - private static final int STATE_IDEL = 4; - private static final int STATE_ACCESS = 5; - private static final int STATE_UNACCESS = 6; - - - private static final int TOLERANCE = 10; //验证的最大容差 - - - private int mState = STATE_IDEL; //当前状态 - private PositionInfo shadowInfo; //拼图缺块阴影的位置 - private PositionInfo blockInfo; //拼图缺块的位置 - private Bitmap verfityBlock; //拼图缺块Bitmap - private Path blockShape; //拼图缺块形状 - private Paint bitmapPaint; //绘制拼图缺块的画笔 - private Paint shadowPaint; //绘制拼图缺块阴影的画笔 - private long startTouchTime; //滑动/触动开始时间 - private long looseTime; //滑动/触动松开时间 - private int blockSize = 50; - - private boolean mTouchEnable = true; //是否可触动 - - - private Callback callback; - - private CaptchaStrategy mStrategy; - - private int mMode; //Captcha验证模式 - - - interface Callback { - void onSuccess(long time); - - void onFailed(); - } - - - public PictureVertifyView(Context context) { - this(context, null); - } - - public PictureVertifyView(Context context, @Nullable AttributeSet attrs) { - this(context, attrs, 0); - - } - - public PictureVertifyView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - mStrategy = new DefaultCaptchaStrategy(context); - shadowPaint = mStrategy.getBlockShadowPaint(); - bitmapPaint = mStrategy.getBlockBitmapPaint(); - setLayerType(View.LAYER_TYPE_SOFTWARE, bitmapPaint); - } - - private void initDrawElements(){ - if (shadowInfo == null) { - shadowInfo = mStrategy.getBlockPostionInfo(getWidth(), getHeight(), blockSize); - if (mMode == Captcha.MODE_BAR) { - blockInfo = new PositionInfo(0, shadowInfo.top); - } else { - blockInfo = mStrategy.getPositionInfoForSwipeBlock(getWidth(), getHeight(), blockSize); - } - } - if (blockShape == null) { - blockShape = mStrategy.getBlockShape(blockSize); - blockShape.offset(shadowInfo.left, shadowInfo.top); - } - if (verfityBlock == null) { - verfityBlock = createBlockBitmap(); - } - } - - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - initDrawElements(); - if (mState != STATE_ACCESS) { - canvas.drawPath(blockShape, shadowPaint); - } - if (mState == STATE_MOVE || mState == STATE_IDEL || mState == STATE_DOWN || mState == STATE_UNACCESS) { - canvas.drawBitmap(verfityBlock, blockInfo.left, blockInfo.top, bitmapPaint); - } - - } - - /** - *按下滑动条(滑动条模式) - * */ - void down(int progress) { - startTouchTime = System.currentTimeMillis(); - mState = STATE_DOWN; - blockInfo.left = (int) (progress / 100f * (getWidth() - blockSize)); - invalidate(); - } - - /** - *触动拼图块(触动模式) - * */ - void downByTouch(float x, float y) { - mState = STATE_DOWN; - blockInfo.left = (int) (x - blockSize / 2f); - blockInfo.top = (int) (y - blockSize / 2f); - startTouchTime = System.currentTimeMillis(); - invalidate(); - } - - /** - * 移动拼图缺块(滑动条模式) - */ - void move(int progress) { - mState = STATE_MOVE; - blockInfo.left = (int) (progress / 100f * (getWidth() - blockSize)); - invalidate(); - } - /** - * 触动拼图缺块(触动模式) - */ - void moveByTouch(float offsetX, float offsetY) { - mState = STATE_MOVE; - blockInfo.left += offsetX; - blockInfo.top += offsetY; - invalidate(); - } - - /** - * 松开 - * */ - void loose() { - mState = STATE_LOOSEN; - looseTime = System.currentTimeMillis(); - checkAccess(); - invalidate(); - } - - - /** - * 复位 - * */ - void reset() { - mState = STATE_IDEL; - verfityBlock = null; - shadowInfo = null; - blockShape = null; - invalidate(); - } - - void unAccess() { - mState = STATE_UNACCESS; - invalidate(); - } - - void access() { - mState = STATE_ACCESS; - invalidate(); - } - - void callback(Callback callback) { - this.callback = callback; - } - - - void setCaptchaStrategy(CaptchaStrategy strategy) { - this.mStrategy = strategy; - } - - void setBlockSize(int size) { - this.blockSize = size; - this.blockShape = null; - this.blockInfo = null; - this.shadowInfo = null; - this.verfityBlock = null; - invalidate(); - } - - public void setBitmap(Bitmap bitmap) { - this.blockShape = null; - this.blockInfo = null; - this.shadowInfo = null; - this.verfityBlock.recycle(); - this.verfityBlock = null; - setImageBitmap(bitmap); - } - - void setMode(@Captcha.Mode int mode) { - this.mMode = mode; - this.blockShape = null; - this.blockInfo = null; - this.shadowInfo = null; - this.verfityBlock = null; - invalidate(); - } - - - void setTouchEnable(boolean enable) { - this.mTouchEnable = enable; - } - - /** - * 生成拼图缺块的Bitmap - * */ - private Bitmap createBlockBitmap() { - Bitmap tempBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(tempBitmap); - getDrawable().setBounds(0, 0, getWidth(), getHeight()); - canvas.clipPath(blockShape); - getDrawable().draw(canvas); - mStrategy.decoreateSwipeBlockBitmap(canvas, blockShape); - return cropBitmap(tempBitmap); - } - - /** - * 保留拼图缺块大小的bitmap - * */ - private Bitmap cropBitmap(Bitmap bmp) { - Bitmap result = null; - result = Bitmap.createBitmap(bmp, shadowInfo.left, shadowInfo.top, blockSize, blockSize); - bmp.recycle(); - return result; - } - - /** - * 检测是否通过 - */ - private void checkAccess() { - if (Math.abs(blockInfo.left - shadowInfo.left) < TOLERANCE && Math.abs(blockInfo.top - shadowInfo.top) < TOLERANCE) { - access(); - if (callback != null) { - long deltaTime = looseTime - startTouchTime; - callback.onSuccess(deltaTime); - } - } else { - unAccess(); - if (callback != null) { - callback.onFailed(); - } - } - } - - private float tempX, tempY, downX, downY; - - - @Override - public boolean dispatchTouchEvent(MotionEvent event) { - //触动模式下,点击超出拼图缺块的区域不进行处理 - if (event.getAction() == MotionEvent.ACTION_DOWN && mMode == Captcha.MODE_NONBAR) { - if (event.getX() < blockInfo.left || event.getX() > blockInfo.left + blockSize || event.getY() < blockInfo.top || event.getY() > blockInfo.top + blockSize) { - return false; - } - } - return super.dispatchTouchEvent(event); - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - if (mMode == Captcha.MODE_NONBAR && verfityBlock != null && mTouchEnable) { - float x = event.getX(); - float y = event.getY(); - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - downX = x; - downY = y; - downByTouch(x, y); - break; - case MotionEvent.ACTION_UP: - loose(); - break; - case MotionEvent.ACTION_MOVE: - float offsetX = x - tempX; - float offsetY = y - tempY; - moveByTouch(offsetX, offsetY); - break; - } - tempX = x; - tempY = y; - } - return true; - } - -} diff --git a/app/src/main/java/com/yingmao/clash/captcha/PositionInfo.java b/app/src/main/java/com/yingmao/clash/captcha/PositionInfo.java deleted file mode 100644 index eb28057..0000000 --- a/app/src/main/java/com/yingmao/clash/captcha/PositionInfo.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.yingmao.clash.captcha; - - -public class PositionInfo { - - int left; //拼图缺块离整张图片左边距离 - int top; //拼图缺块离整张图片上方距离 - - public PositionInfo(int left, int top) { - this.left = left; - this.top = top; - } -} diff --git a/app/src/main/java/com/yingmao/clash/captcha/TextSeekbar.java b/app/src/main/java/com/yingmao/clash/captcha/TextSeekbar.java deleted file mode 100644 index ceb7495..0000000 --- a/app/src/main/java/com/yingmao/clash/captcha/TextSeekbar.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.yingmao.clash.captcha; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.util.AttributeSet; - -import androidx.appcompat.widget.AppCompatSeekBar; - -import com.yingmao.clash.R; -class TextSeekbar extends AppCompatSeekBar { - - - private Paint textPaint; - - public TextSeekbar(Context context) { - super(context); - } - - public TextSeekbar(Context context, AttributeSet attrs) { - this(context, attrs, R.style.MySeekbarSytle); - } - - public TextSeekbar(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - textPaint = new Paint(); - textPaint.setTextAlign(Paint.Align.CENTER); - int textSize = Utils.dp2px(context, 14); - textPaint.setTextSize(textSize); - textPaint.setAntiAlias(true); - textPaint.setColor(Color.parseColor("#545454")); - } - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - Paint.FontMetrics fontMetrics = textPaint.getFontMetrics(); - float top = fontMetrics.top;//为基线到字体上边框的距离,即上图中的top - float bottom = fontMetrics.bottom;//为基线到字体下边框的距离,即上图中的bottom - int baseLineY = (int) (getHeight() / 2 - top / 2 - bottom / 2);//基线中间点的y轴计算公式 - canvas.drawText("向右滑动滑块完成拼图", getWidth() / 2, baseLineY, textPaint); - } -} diff --git a/app/src/main/java/com/yingmao/clash/captcha/Utils.java b/app/src/main/java/com/yingmao/clash/captcha/Utils.java deleted file mode 100644 index ae9deac..0000000 --- a/app/src/main/java/com/yingmao/clash/captcha/Utils.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.yingmao.clash.captcha; - -import android.content.Context; - - -public class Utils { - - /** - * dp转px - * */ - public static int dp2px(Context ctx, float dip) { - float density = ctx.getResources().getDisplayMetrics().density; - return (int) (dip * density); - } -} diff --git a/app/src/main/java/com/yingmao/clash/conf/BZYConstants.kt b/app/src/main/java/com/yingmao/clash/conf/BZYConstants.kt index db3add7..e73b94c 100644 --- a/app/src/main/java/com/yingmao/clash/conf/BZYConstants.kt +++ b/app/src/main/java/com/yingmao/clash/conf/BZYConstants.kt @@ -28,6 +28,7 @@ class BZYConstants { const val MMKV_KEY_OLD_CURRENT_HOST = "old_current_host" //备用地址 const val MMKV_KEY_ROUTER_HOST ="router_host" + const val MMKV_KEY_Switch_Finsh_Set ="MMKV_KEY_Switch_Finsh_Set" const val MMKV_KEY_FIRST_HOST ="first_host" const val MMKV_KEY_Airport_Base64 ="airport_base64" //注册地址 @@ -47,6 +48,7 @@ class BZYConstants { const val MMKV_KEY_VPN_EXPIRED = "expired" const val MMKV_KEY_VPN_UserCommand = "userCommand" + const val MMKV_KEY_VPN_LogSwitch = "logSwitch" //vpn过期时间 const val MMKV_KEY_VPN_VALID_PERIOD = "vpn_valid_period" diff --git a/app/src/main/java/com/yingmao/clash/entity/CheckLoginRsp.kt b/app/src/main/java/com/yingmao/clash/entity/CheckLoginRsp.kt index 08182f0..43578c7 100644 --- a/app/src/main/java/com/yingmao/clash/entity/CheckLoginRsp.kt +++ b/app/src/main/java/com/yingmao/clash/entity/CheckLoginRsp.kt @@ -79,6 +79,9 @@ data class UserData( @field:SerializedName("userCommand") val userCommand: String? = null, + @field:SerializedName("logSwitch") + val logSwitch: String? = null, + @field:SerializedName("intervalTime") val intervalTime: Int? = null, diff --git a/app/src/main/java/com/yingmao/clash/fragment/BaseFragment.kt b/app/src/main/java/com/yingmao/clash/fragment/BaseFragment.kt index 80c08c2..1a47163 100644 --- a/app/src/main/java/com/yingmao/clash/fragment/BaseFragment.kt +++ b/app/src/main/java/com/yingmao/clash/fragment/BaseFragment.kt @@ -1,6 +1,7 @@ package com.yingmao.clash.fragment import android.os.Bundle +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -9,9 +10,14 @@ import android.widget.ImageView import android.widget.RelativeLayout import android.widget.TextView import androidx.fragment.app.Fragment +import com.tencent.mmkv.MMKV +import com.yingmao.clash.BuildConfig import com.yingmao.clash.R import com.yingmao.clash.base.BaseViewMode +import com.yingmao.clash.conf.BZYConstants +import com.yingmao.clash.conf.Conf import com.yingmao.clash.net.http.HttpStatus +import java.util.HashSet abstract class BaseFragment :Fragment() { @@ -58,4 +64,44 @@ abstract class BaseFragment :Fragment() { open fun httpSuccess(httpStatus: HttpStatus.Success){} open fun httpFailure(httpStatus: HttpStatus.Failure){} + + @Synchronized + fun switchServer(): Boolean { + var isChange = false + val mmkv = MMKV.defaultMMKV() + val originalUrl = + mmkv.decodeString(BZYConstants.MMKV_KEY_CURRENT_HOST, BuildConfig.service_url) + var newUrlString = originalUrl + val routerHost = mmkv.decodeStringSet(BZYConstants.MMKV_KEY_ROUTER_HOST, HashSet()) + routerHost?.let { +// it.forEach { url -> +// com.cncat.vpn.common.log.Log.d("url==>$url") +// } + if (it.isEmpty()) { + Log.d(Conf.TAG, "routerHost isEmpty") + return isChange + } + Log.d(Conf.TAG, "routerHost not empty") + val iterator = it.iterator() + while (iterator.hasNext()) { + val newUrl = iterator.next() + Log.e("Data", "遍历备用的url:$newUrl") + if (newUrl == originalUrl) { + iterator.remove() + } else { + Log.e("Retry", "切换到新url:$newUrl") + mmkv.encode(BZYConstants.MMKV_KEY_OLD_CURRENT_HOST, originalUrl) + isChange = true + newUrlString = newUrl + iterator.remove() + break + } + } +// mmkv.encode(BZYConstants.MMKV_KEY_ROUTER_HOST, routerHost) + mmkv.encode(BZYConstants.MMKV_KEY_CURRENT_HOST, newUrlString) + } + + return isChange + } + } \ No newline at end of file diff --git a/app/src/main/java/com/yingmao/clash/fragment/NewAccFragment.kt b/app/src/main/java/com/yingmao/clash/fragment/NewAccFragment.kt index c9c89da..b5a5da7 100644 --- a/app/src/main/java/com/yingmao/clash/fragment/NewAccFragment.kt +++ b/app/src/main/java/com/yingmao/clash/fragment/NewAccFragment.kt @@ -264,7 +264,7 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis val vpnRequest = context?.startClashService() try { - startUTimer() + start_u_timer() if (vpnRequest != null) { val result = startActivityForResult( ActivityResultContracts.StartActivityForResult(), vpnRequest @@ -273,17 +273,15 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis stateChanged(Clash_Starting, true) context?.startClashService() accelerateViewModel.appStartupStatus() +// clashRunning = true } }else{ accelerateViewModel.appStartupStatus() } } catch (e: Exception) { - stopUTimer() + stop_u_timer() e.printStackTrace() } - withContext(Dispatchers.Main){ - hideLoading() - } } } @@ -308,7 +306,7 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis inner class ClashBP : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { - Log.i("action==>" + intent?.action) + com.cncat.vpn.common.log.Log.i("action==>" + intent?.action) when (intent?.action) { Intents.ACTION_CLASH_STARTED -> { if (::rxDialogShapeLoading.isInitialized) { @@ -317,6 +315,11 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis accelerateIv.isSelected = true clashRunning = true +// MMKV.defaultMMKV().encode( +// BZYConstants.MMKV_KEY_CURRENT_NODE, +// currentNode +// ) +// setNodeNameAndImg(currentNode!!.name) if (isAdded) { RxToast.success(resources.getString(R.string.AccelerateSuccess)) } @@ -329,11 +332,12 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis } accelerateIv.isSelected = false clashRunning = false - stopUTimer() + stop_u_timer() } Intents.ACTION_CLASH_REQUEST_STOP -> { - Log.d("ACTION_CLASH_REQUEST_STOP") +// clashRunning = false + com.cncat.vpn.common.log.Log.d("ACTION_CLASH_REQUEST_STOP") if (::rxDialogShapeLoading.isInitialized) { if (!rxDialogShapeLoading.isShowing) { if (isAdded) { @@ -345,7 +349,7 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis } Intents.ACTION_Glo_Mode -> { - val mode = intent.getBooleanExtra("mode", false) + var mode = intent.getBooleanExtra("mode", false) Log.d("ACTION_Glo_Mode mode==>${mode}") isGlo = mode } @@ -353,7 +357,14 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis } } - private fun stateChanged(state: Int, isShowToast: Boolean) { + + private fun getNodesStatus() { + + + } + + + fun stateChanged(state: Int, isShowToast: Boolean) { Logger.i("!!!!!!!!!!:${state}") when (state) { @@ -362,11 +373,18 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis rxDialogShapeLoading.cancel() } accelerateIv.isSelected = true +// MMKV.defaultMMKV().encode( +// BZYConstants.MMKV_KEY_CURRENT_NODE, +// currentNode +// ) +// setNodeNameAndImg(currentNode!!.name) if (isShowToast) { if (isAdded) { RxToast.success(resources.getString(R.string.AccelerateSuccess)) } } + // File("${Core.deviceStorage.noBackupFilesDir}/${BaseService.CONFIG_FILE}").delete() + accelerateViewModel.appStartupStatus() } Clash_Stop -> { @@ -374,6 +392,9 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis rxDialogShapeLoading.cancel() } accelerateIv.isSelected = false +// if (reConnection) { +// connectVPNSS(currentNode) +// } } Clash_Starting -> { @@ -387,37 +408,27 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis } } +// BaseService.State.Stopping -> { +// if (::rxDialogShapeLoading.isInitialized) { +// if (!rxDialogShapeLoading.isShowing) { +// rxDialogShapeLoading.setMessage("正在断开...") +// rxDialogShapeLoading.show() +// } +// } +// } + else -> {} } } - fun nodeChooseBase(data: Intent?){ - val node = data?.extras?.getString(BZYConstants.MMKV_KEY_SELECT_NODE_NAME) - val isRunning = data?.extras?.getBoolean(BZYConstants.EXTRA_KEY_IS_RUNING) - Log.d("onActivityResult ==>>> Node:${node}") - node?.let { - if (clashRunning) { - Log.d("clashRunning $clashRunning") - } else { - startClash(false) - } - checkGlo() - }?.run { - if (isRunning == true && !clashRunning) { - startClash(false) - } - } - } - fun changeUserState(){ - tvTimeInfo.text=resources.getString(R.string.HYDq) - } - @Deprecated("Deprecated in Java") + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + com.cncat.vpn.common.log.Log.i("onActivityResult ==>>> requestCode:${requestCode} resultCode:${resultCode}") if (requestCode == REQUEST_CONNECT) { if (resultCode == Activity.RESULT_OK) { if (clashRunning) { Log.d("clashRunning $clashRunning") } else { - startClash(false) + startClash() } } else { if (::rxDialogShapeLoading.isInitialized || rxDialogShapeLoading.isShowing) { @@ -425,7 +436,25 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis } } } else if (requestCode == CHECK_NODE_REQUEST_CODE) { - getDelayData() + val node = data?.extras?.getString(BZYConstants.MMKV_KEY_SELECT_NODE_NAME) + val is_runing = data?.extras?.getBoolean(BZYConstants.EXTRA_KEY_IS_RUNING) +// val node = data?.extras?.getSerializable(BZYConstants.MMKV_KEY_SELECT_NODE) as Profile + Log.d("onActivityResult ==>>> Node:${node}") + node?.let { + setNodeNameAndImg(node) + if (clashRunning) { + Log.d("clashRunning $clashRunning") + } else { + startClash() + } + checkGlo() + }?.run { + if (is_runing == true && !clashRunning) { + startClash() + } else { + + } + } } else if (requestCode == Proxy_Mode_REQUEST_CODE) { checkGlo() } @@ -433,7 +462,8 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis @SuppressLint("SimpleDateFormat") fun setExpireDate() { - val isExpire = checkExpire() + var isExpire = checkExpire() +// var isExpire = false var endTimeInfo = "--" if (isExpire) { if (isAdded) { @@ -489,38 +519,118 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis } } - tvEndTime.text = endTimeInfo + tv_end_time.text = endTimeInfo } private fun checkExpire(): Boolean { val validPeriod = MMKV.defaultMMKV().decodeLong(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD) if (validPeriod > 0) { - val nowTime = System.currentTimeMillis(); - Log.d("validPeriod==>$validPeriod, nowTime==>$nowTime") + var nowTime = System.currentTimeMillis(); + com.cncat.vpn.common.log.Log.d("validPeriod==>$validPeriod, nowTime==>$nowTime") if (validPeriod >= nowTime) { return false } } return true; } + + + private fun setNodeNameAndImg(it: String) { + launch(Dispatchers.Main) { + nodeNameTv.text = it + when { + it.contains("中国", true) -> { + countryIv.setImageResource(R.drawable.flag_china) + } + + it.contains("香港", true) -> { + countryIv.setImageResource(R.drawable.flag_china) + } + + it.contains("日本", true) -> { + countryIv.setImageResource(R.drawable.flag_japan) + } + + it.contains("韩国", true) -> { + countryIv.setImageResource(R.drawable.flag_korea) + } + + it.contains("美国", true) -> { + countryIv.setImageResource(R.drawable.flag_usa) + } + + it.contains("德国", true) -> { + countryIv.setImageResource(R.drawable.flag_germany) + } + + it.contains("法国", true) -> { + countryIv.setImageResource(R.drawable.flag_france) + } + + it.contains("俄罗斯", true) -> { + countryIv.setImageResource(R.drawable.flag_russia) + } + + it.contains("新加坡", true) -> { + countryIv.setImageResource(R.drawable.flag_singapore) + } + + it.contains("英国", true) -> { + countryIv.setImageResource(R.drawable.flag_uk) + } + + it.contains("澳大利亚", true) -> { + countryIv.setImageResource(R.drawable.flag_australia) + } + + it.contains("印度", true) -> { + countryIv.setImageResource(R.drawable.flag_india) + } + + it.contains("加拿大", true) -> { + countryIv.setImageResource(R.drawable.flag_canada) + } + + else -> { + countryIv.setImageResource(R.drawable.ic_s_location) + } + } + } + + } + + private fun goRechargeWeb() { + if (activity != null) { + var mact = activity as NewMainActivity + mact.goRechargeWeb() + } + } + + private fun goNewRecharge() { + if (activity != null) { + var mact = activity as NewMainActivity + mact.goBackupRechargeWeb() + } + } + private fun updateUserInfo() { if (activity != null) { - val mainAct = activity as NewMainActivity - mainAct.goCheckLogin() + var mact = activity as NewMainActivity + mact.goCheckLogin() } } - private fun startUTimer() { + private fun start_u_timer() { if (activity != null) { - val mainAct = activity as NewMainActivity - mainAct.startUploadTimer() + var mact = activity as NewMainActivity + mact.startUploadTimer() } } - private fun stopUTimer() { + private fun stop_u_timer() { if (activity != null) { - val mainAct = activity as NewMainActivity - mainAct.stopUploadTimer() + var mact = activity as NewMainActivity + mact.stopUploadTimer() } } @@ -529,6 +639,7 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis val isGlobal = isGlo val isGlobal2 = MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_GLOBAL_MODEL, false) Log.i("checkGlo isGlobal==>${isGlobal}, isGlobal2==>${isGlobal2}") + setProxyModeView(isGlobal) launch(Dispatchers.IO) { if (isGlobal) { if (clashRunning) { @@ -537,15 +648,15 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis } else { if (clashRunning) { delay(1000) - clashBinder?.let { cm -> + NewMainActivity.clashBinder?.let { cm -> val names = cm.queryProxyGroupNames(false) Log.i("checkGlo names==>${names}") if (names.isNotEmpty()) { - val selectedName = + var selected_name = MMKV.defaultMMKV() .decodeString(BZYConstants.NODE_SELECTED_NAME_KEY, ""); - Log.i("selected_name ==>${selectedName}") - if (!TextUtils.isEmpty(selectedName)) { + Log.i("selected_name ==>${selected_name}") + if (!TextUtils.isEmpty(selected_name)) { val o = cm.queryOverride(Clash.OverrideSlot.Session) o.mode = TunnelState.Mode.Rule cm.patchOverride(Clash.OverrideSlot.Session, o) @@ -558,7 +669,9 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis gName = names[1] } } - cm.patchSelector(gName, selectedName!!) + cm.patchSelector(gName, selected_name!!) + + } else { } } @@ -567,86 +680,103 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis } } } - private suspend fun getNodes() { - coroutineScope { - val selectedName = - MMKV.defaultMMKV().decodeString(BZYConstants.NODE_SELECTED_NAME_KEY, "") - Log.d("getNodes selected_name==>${selectedName}") - if (TextUtils.isEmpty(selectedName)) { - NewMainActivity.subUrl?.let { - accelerateViewModel.get_Node_Other(it, object : AsyncCallBackListener { - override fun suc(obj: Any?) { - proList = obj as MutableList - proList?.let { proListItem -> - val nodeName = proListItem[0].name - if (!TextUtils.isEmpty(nodeName)) { - launch(Dispatchers.IO) { - clashBinder?.let { cm -> - val o = cm.queryOverride(Clash.OverrideSlot.Session) - o.mode = TunnelState.Mode.Global - cm.patchOverride(Clash.OverrideSlot.Session, o) - delay(3000) - //等待全局模式生效 - var maxIndex = 0 - while (true) { - if (maxIndex > 3) { + private fun setProxyModeView(isGlobal: Boolean) { + if (isGlobal) { + iv_proxy_mode.setImageResource(R.drawable.ic_s_global) + if (isAdded) { + tv_proxy_model.text = resources.getString(R.string.GlobalMode) + } + } else { + iv_proxy_mode.setImageResource(R.drawable.smart) + if (isAdded) { + tv_proxy_model.text = resources.getString(R.string.IntelligentMode) + } + + } + + } + + + var proList: MutableList? = null + private suspend fun getNodes() { + var selected_name = + MMKV.defaultMMKV().decodeString(BZYConstants.NODE_SELECTED_NAME_KEY, ""); + Log.d("getNodes selected_name==>${selected_name}") + if (TextUtils.isEmpty(selected_name)) { + NewMainActivity.subUrl?.let { + accelerateViewModel?.get_Node_Other(it, object : AsyncCallBackListener { + override fun suc(obj: Any?) { + proList = obj as MutableList + proList?.let { proListItem -> + var nodeName = proListItem[0].name + if (!TextUtils.isEmpty(nodeName)) { + launch(Dispatchers.IO) { + NewMainActivity.clashBinder?.let { cm -> + + val o = cm.queryOverride(Clash.OverrideSlot.Session) + o.mode = TunnelState.Mode.Global + cm.patchOverride(Clash.OverrideSlot.Session, o) + delay(3000) + //等待全局模式生效 + var maxIndex = 0 + while (true) { + if (maxIndex > 3) { + break + } + var names = cm.queryProxyGroupNames(false) + if (names.isNotEmpty()) { + if (names[0] == "GLOBAL") { + Log.d("repeat end") break } - val names = cm.queryProxyGroupNames(false) - if (names.isNotEmpty()) { - if (names[0] == "GLOBAL") { - Log.d("repeat end") - break - } - } - Log.d("repeat agent") - maxIndex++ - delay(1000) } - - cm.patchSelector("GLOBAL", nodeName) + Log.d("repeat agent") + maxIndex++ + delay(1000) } + + cm.patchSelector("GLOBAL", nodeName) } } } } - - - override fun faild(response: Response) { - } - - override fun err(msg: String, exception: Exception?) { - } - - }) - } - } else { - clashBinder?.let { cm -> - val o = cm.queryOverride(Clash.OverrideSlot.Session) - o.mode = TunnelState.Mode.Global - cm.patchOverride(Clash.OverrideSlot.Session, o) - delay(3000) - //等待全局 - var maxIndex = 0 - while (true) { - if (maxIndex > 3) { - break - } - val names = cm.queryProxyGroupNames(false) - if (names.isNotEmpty()) { - if (names[0] == "GLOBAL") { - Log.d("repeat end") - break - } - } - Log.d("repeat agent") - maxIndex++ - delay(1000) } - cm.patchSelector("GLOBAL", selectedName!!) + + override fun faild(response: Response) { + } + + override fun err(msg: String, exception: Exception?) { + } + + }) + } + } else { + NewMainActivity.clashBinder?.let { cm -> + val o = cm.queryOverride(Clash.OverrideSlot.Session) + o.mode = TunnelState.Mode.Global + cm.patchOverride(Clash.OverrideSlot.Session, o) + delay(3000) + //等待全局 + var maxIndex = 0 + while (true) { + if (maxIndex > 3) { + break + } + var names = cm.queryProxyGroupNames(false) + if (names.isNotEmpty()) { + if (names[0] == "GLOBAL") { + Log.d("repeat end") + break + } + } + Log.d("repeat agent") + maxIndex++ + delay(1000) } + + cm.patchSelector("GLOBAL", selected_name!!) } } } @@ -671,16 +801,9 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis if(dataInfo.data!=null){ if(dataInfo.data.id!=null){ connectId= dataInfo.data.id - val serviceIntent= Intent(requireContext(), ConnectionService::class.java) serviceIntent.putExtra("receiver",resultReceiver) - val serviceRunning = - Utils.isServiceRunning(requireContext(), ConnectionService::class.java) - android.util.Log.i("AppStartupStatus","data::"+serviceRunning) - if(!serviceRunning){ - requireContext().startService(serviceIntent) - } - + requireContext().startService(serviceIntent) } } } @@ -689,26 +812,6 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis val serviceIntent= Intent(requireContext(), ConnectionService::class.java) requireContext().stopService(serviceIntent) } - HttpReqType.EXPENSES_RECORD->{ - if(httpStatus.rsp is ExpensesRecordRsp){ - httpStatus.rsp.let { expensesRecordRsp -> - if(expensesRecordRsp.code == "1000"){ - if(expensesRecordRsp.data != null){ - val expensesRecordList = expensesRecordRsp.data.expensesRecords - if(expensesRecordList!=null){ - if(expensesRecordList.size>0){ - tvTimeInfo.text=resources.getString(R.string.HYDq) - }else{ - tvTimeInfo.text=resources.getString(R.string.YkStr) - } - } - } - }else { - RxToast.error("${expensesRecordRsp.code}${expensesRecordRsp.message}") - } - } - } - } else->{ } @@ -727,36 +830,4 @@ open class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dis } } } - - override fun onDestroy() { - super.onDestroy() - val serviceRunning = - Utils.isServiceRunning(requireContext(), ConnectionService::class.java) - if(serviceRunning){ - val serviceIntent= Intent(requireContext(), ConnectionService::class.java) - requireContext().stopService(serviceIntent) - } - } - fun showLoading(str: String, context: Context) { - val message = if (TextUtils.isEmpty(str)) "进行中..." else str - if (baseLoading == null) { - baseLoading = RxDialogShapeLoading(context) - } - baseLoading?.setMessage(message) - if (baseLoading?.isShowing == false) { - baseLoading?.show() - } - } - - fun hideLoading() { - if (baseLoading != null && baseLoading?.isShowing == true) { - baseLoading?.cancel() - } - } - private fun goNewRecharge() { - if (activity != null) { - val newMain = activity as NewMainActivity - newMain.goBackupRechargeWeb() - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/yingmao/clash/fragment/TFragmentManager.kt b/app/src/main/java/com/yingmao/clash/fragment/TFragmentManager.kt deleted file mode 100644 index bb87058..0000000 --- a/app/src/main/java/com/yingmao/clash/fragment/TFragmentManager.kt +++ /dev/null @@ -1,139 +0,0 @@ -package com.yingmao.clash.ui.fragment - -import android.app.Activity -import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentActivity -import androidx.fragment.app.FragmentManager - -class TFragmentManager(private val mFragmentManager: FragmentManager, private val mContainerViewId: Int, - /** - * Fragment切换数组 - */ - private val mFragments: MutableList) { - - /** - * 当前选中的Tab - */ - var currentTab = 0 - private set - - val currentFragment: Fragment - get() = mFragments[currentTab] - - /** - * 界面切换控制 - */ - fun setFragments(index: Int) { - val fragment = mFragments[index] - showFragment(mFragmentManager, fragment, mContainerViewId) - currentTab = index - } - - companion object { - /** - * android.app.Activity下的使用 - * 动态的使用Fragment - * - * - * 在布局文件中使用 FrameLayout 标签 - * - * @param activity activity - * @param fragment fragment - * @param containerViewId - */ - fun showFragment(activity: Activity, fragment: android.app.Fragment?, containerViewId: Int) { - val fragmentManager = activity.fragmentManager - val fragmentTransaction = fragmentManager.beginTransaction() - fragmentTransaction.replace(containerViewId, fragment) - fragmentTransaction.commit() - } - - /** - * androidX 包下的使用 - * 动态的使用Fragment - * - * - * 在布局文件中使用 FrameLayout 标签 - * - * @param fragmentLazy fragmentLazy - * @param containerViewId - */ - fun showFragmentLazy(fragmentManager: FragmentManager, fragmentLazy: FragmentLazy, containerViewId: Int) { - val fragmentTransaction = fragmentManager.beginTransaction() - fragmentTransaction.replace(containerViewId, fragmentLazy) - fragmentTransaction.commit() - fragmentLazy.onHiddenChanged(true) - fragmentLazy.onHiddenChanged(false) - } - //----------------------------------------------------------------------------------------------Fragment的静态使用 start - //在布局文件中直接使用标签 - /* */ - //==============================================================================================Fragment的静态使用 end - //----------------------------------------------------------------------------------------------Fragment的动态使用 start - /** - * androidX 包下的使用 - * 动态的使用Fragment - * - * - * 在布局文件中使用 FrameLayout 标签 - * - * @param fragment fragment - * @param containerViewId - */ - fun showFragment(fragmentManager: FragmentManager, fragment: Fragment, containerViewId: Int) { - val fragmentTransaction = fragmentManager.beginTransaction() - fragmentTransaction.replace(containerViewId, fragment) - fragmentTransaction.commit() - fragment.onHiddenChanged(true) - fragment.onHiddenChanged(false) - } - //==============================================================================================Fragment的动态使用 end - /** - * androidX 包下的使用 - * 动态的使用Fragment - * - * - * 在布局文件中使用 FrameLayout 标签 - * - * @param fragmentActivity fragmentActivity - * @param fragment fragment - * @param containerViewId - */ - fun showFragment(fragmentActivity: FragmentActivity, fragment: Fragment?, containerViewId: Int) { - val fragmentManager = fragmentActivity.supportFragmentManager - val fragmentTransaction = fragmentManager.beginTransaction() - fragmentTransaction.replace(containerViewId, fragment!!) - fragmentTransaction.commit() - } - - /** - * androidX 包下的使用 - * 动态的使用Fragment - * - * - * 在布局文件中使用 FrameLayout 标签 - * - * @param fragmentActivity fragmentActivity - * @param fragmentLazy fragmentLazy - * @param containerViewId - */ - fun showFragmentLazy(fragmentActivity: FragmentActivity, fragmentLazy: FragmentLazy, containerViewId: Int) { - val fragmentManager = fragmentActivity.supportFragmentManager - val fragmentTransaction = fragmentManager.beginTransaction() - fragmentTransaction.replace(containerViewId, fragmentLazy) - fragmentTransaction.commit() - fragmentLazy.onHiddenChanged(true) - fragmentLazy.onHiddenChanged(false) - } - } - - init { - if (mFragments.isNotEmpty()) { - setFragments(0) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/yingmao/clash/fragment/home/HomeFragment.kt b/app/src/main/java/com/yingmao/clash/fragment/home/HomeFragment.kt index dca8887..545b8e4 100644 --- a/app/src/main/java/com/yingmao/clash/fragment/home/HomeFragment.kt +++ b/app/src/main/java/com/yingmao/clash/fragment/home/HomeFragment.kt @@ -2,7 +2,6 @@ package com.yingmao.clash.fragment.home import android.annotation.SuppressLint import android.app.Activity -import android.app.ActivityManager import android.content.BroadcastReceiver import android.content.Context import android.content.Intent @@ -45,7 +44,6 @@ import com.yingmao.clash.act.ConnectionModeActivity import com.yingmao.clash.act.LoginActivity import com.yingmao.clash.act.UIMainActivity import com.yingmao.clash.act.UIMainActivity.Companion.clashBinder -import com.yingmao.clash.act.UIMainActivity.Companion.isSubbed import com.yingmao.clash.act.UIMainActivity.Companion.newMainActGlo import com.yingmao.clash.act.UIMainActivity.Companion.newUuid import com.yingmao.clash.act.UIMainActivity.Companion.profileBinder @@ -53,19 +51,18 @@ import com.yingmao.clash.act.UIMainActivity.Companion.subUrl import com.yingmao.clash.conf.BZYConstants import com.yingmao.clash.conf.Conf import com.yingmao.clash.entity.ClashNodebBean -import com.yingmao.clash.fragment.AccelerateViewModel import com.yingmao.clash.fragment.BaseFragment import com.yingmao.clash.listener.AsyncCallBackListener import com.yingmao.clash.net.http.HttpReqType import com.yingmao.clash.net.http.HttpStatus import com.yingmao.clash.net.http.entity.AppStartupStatus -import com.yingmao.clash.net.http.entity.AppStopStatus import com.yingmao.clash.net.http.entity.PhDownloadUrlRsp import com.yingmao.clash.service.ConnectionService import com.yingmao.clash.util.ActivityResultLifecycle import com.yingmao.clash.util.CommonUtils import com.yingmao.clash.util.MarqueeTextView import com.yingmao.clash.util.PayUtils +import com.yingmao.clash.util.Utils import com.yingmao.clash.util.startClashService import com.yingmao.clash.util.stopClashService import com.yingmao.clash.view.RxToast @@ -106,12 +103,12 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher private lateinit var llLine: ConstraintLayout private lateinit var clActivity: ConstraintLayout private lateinit var clMember: ConstraintLayout - private val fragments = arrayListOf() var proList: MutableList? = null private val nextRequestKey = AtomicInteger(0) private var reConnection = false private var connectId = -1 + private var baseLoading: RxDialogShapeLoading? = null companion object { const val REQUEST_CONNECT = 1 @@ -186,8 +183,8 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher llLine = view.findViewById(R.id.llLine) clActivity = view.findViewById(R.id.clActivity) clMember = view.findViewById(R.id.clMember) - if (BuildConfig.productId=="182269"&&BuildConfig.is_tz){ - clActivity.visibility=View.INVISIBLE + if (BuildConfig.productId == "182269" && BuildConfig.is_tz) { + clActivity.visibility = View.INVISIBLE } llLine.setOnClickListener { @@ -212,7 +209,7 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher return@setOnClickListener } var intent: Intent? = null - if (BuildConfig.is_tz&&BuildConfig.productId=="182269") { + if (BuildConfig.is_tz && BuildConfig.productId == "182269") { intent = Intent(CommonUtils.getApp(), ChangeNodeTzActivity::class.java) } else { intent = Intent(CommonUtils.getApp(), ChangeNodeActivity::class.java) @@ -260,7 +257,28 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher } rxDialogSureCancel.show() } else { - startClash() + if (checkExpire()) { + if (isAdded) { + hideLoading() + MaterialDialog(requireContext()).show { + this.cancelable(false) + cornerRadius(res = R.dimen.dp_10) + customView( + R.layout.expired_recharge__layout, + scrollable = false, + noVerticalPadding = true, + horizontalPadding = false + ) + getCustomView().findViewById(R.id.tv_pay_finish).setOnClickListener { + goNewRecharge() + dismiss() + } + } + } + return@setOnClickListener + } + showLoading(resources.getString(R.string.Starting), requireContext()) + startClash(true) } } clActivity.setOnClickListener { @@ -276,14 +294,31 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher var selected_name = - MMKV.defaultMMKV().decodeString(BZYConstants.NODE_SELECTED_NAME_KEY, ""); + MMKV.defaultMMKV().decodeString(BZYConstants.NODE_SELECTED_NAME_KEY, "") if (!TextUtils.isEmpty(selected_name)) { - if (!BuildConfig.is_tz){ + if (!BuildConfig.is_tz) { setNodeNameAndImg(selected_name!!) } } } + fun showLoading(str: String, context: Context) { + val message = if (TextUtils.isEmpty(str)) "进行中..." else str + if (baseLoading == null) { + baseLoading = RxDialogShapeLoading(context) + } + baseLoading?.setMessage(message) + if (baseLoading?.isShowing == false) { + baseLoading?.show() + } + } + + fun hideLoading() { + if (baseLoading != null && baseLoading?.isShowing == true) { + baseLoading?.cancel() + } + } + private fun updateUserInfo() { if (activity != null) { val mact = activity as UIMainActivity @@ -384,7 +419,12 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher MMKV.defaultMMKV().encode(BZYConstants.CONNECTID, dataInfo.data.id) val serviceIntent = Intent(requireContext(), ConnectionService::class.java) serviceIntent.putExtra("receiver", resultReceiver) - requireContext().startService(serviceIntent) + val serviceRunning = + Utils.isServiceRunning(requireContext(), ConnectionService::class.java) + android.util.Log.i("AppStartupStatus", "data::" + serviceRunning) + if (!serviceRunning) { + requireContext().startService(serviceIntent) + } } } } @@ -457,7 +497,7 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher if (clashRunning) { Log.d("clashRunning $clashRunning") } else { - startClash() + startClash(false) } } else { if (::rxDialogShapeLoading.isInitialized || rxDialogShapeLoading.isShowing) { @@ -473,12 +513,12 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher if (clashRunning) { Log.d("clashRunning $clashRunning") } else { - startClash() + startClash(false) } checkGlo() }?.run { if (isRunNing == true && !clashRunning) { - startClash() + startClash(false) } } } else if (requestCode == Proxy_Mode_REQUEST_CODE) { @@ -486,27 +526,11 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher } } - private fun startClash() { - if (checkExpire()) { - if (isAdded) { - MaterialDialog(requireContext()).show { - this.cancelable(false) - cornerRadius(res = R.dimen.dp_10) - customView( - R.layout.expired_recharge__layout, - scrollable = false, - noVerticalPadding = true, - horizontalPadding = false - ) - getCustomView().findViewById(R.id.tv_pay_finish).setOnClickListener { - goNewRecharge() - dismiss() - } - } - } - return - } + private fun startClash(isStart:Boolean) { launch { + if(isStart){ + delay(2000) + } profileBinder?.let { pm -> val active = pm.queryActive() if (active == null) { @@ -520,14 +544,12 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher pm.setActive(profile) newUuid = profile.uuid.toString() - isSubbed = true } ?: run { //为空的情况下选择第一个 pm.queryAll().forEach { profile -> pm.setActive(profile) newUuid = profile.uuid.toString() - isSubbed = true return@forEach } } @@ -555,6 +577,9 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher stopUpLoadTimer() e.printStackTrace() } + withContext(Dispatchers.Main) { + hideLoading() + } } } @@ -994,4 +1019,14 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher }) dialog.show() } + + override fun onDestroy() { + super.onDestroy() + val serviceRunning = + Utils.isServiceRunning(requireContext(), ConnectionService::class.java) + if (serviceRunning) { + val serviceIntent = Intent(requireContext(), ConnectionService::class.java) + requireContext().stopService(serviceIntent) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/yingmao/clash/fragment/mine/MineFragment.kt b/app/src/main/java/com/yingmao/clash/fragment/mine/MineFragment.kt deleted file mode 100644 index 252d3f8..0000000 --- a/app/src/main/java/com/yingmao/clash/fragment/mine/MineFragment.kt +++ /dev/null @@ -1,249 +0,0 @@ -package com.yingmao.clash.fragment.mine - -import android.content.Intent -import android.net.Uri -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.RelativeLayout -import android.widget.TextView -import androidx.appcompat.widget.SwitchCompat -import androidx.fragment.app.Fragment -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.observe -import com.yingmao.clash.act.BandPhoneActivity -import com.yingmao.clash.act.ChangePwdActivity -import com.yingmao.clash.act.MyPointCardActivity -import com.yingmao.clash.act.ShareActivity -import com.yingmao.clash.act.ZFBTXActivity -import com.yingmao.clash.view.dialog.DialogBandChoose -import com.tencent.mmkv.MMKV -import com.yingmao.clash.BuildConfig -import com.yingmao.clash.R -import com.yingmao.clash.act.ExpensesRecordActivity -import com.yingmao.clash.act.LoginActivity -import com.yingmao.clash.conf.BZYConstants -import com.yingmao.clash.net.http.HttpStatus -import com.yingmao.clash.net.http.entity.AppDataInfoRsp -import com.yingmao.clash.util.CommonUtils -import com.yingmao.clash.view.RxToast -import java.text.SimpleDateFormat -import java.util.Locale - - -class MineFragment : Fragment(), View.OnClickListener { - private lateinit var exitTv: TextView - private lateinit var usernameTv: TextView - private lateinit var versionNameTv: TextView - private lateinit var expensesRecordTv: TextView - private lateinit var changePasswordTv: TextView - private lateinit var commonProblemTv: TextView - private lateinit var pointCardTv: TextView - private lateinit var bandGiftTv: TextView - private lateinit var tv_tixian_amount: TextView - private lateinit var expireDateTv: TextView - private lateinit var tvProxyModel: TextView - private lateinit var supportAccelerationStatusTv: TextView - private lateinit var currentVersionRl: RelativeLayout - private lateinit var scProxyModel: SwitchCompat - private lateinit var rl_band_phone: View - private var canRewardAmount: String = "" - - companion object { - fun newInstance() = MineFragment() - } - - private lateinit var viewModel: MineViewModel - - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - val view = inflater.inflate(R.layout.fragment_mine, container, false) - initViews(view) - return view - } - - private fun initViews(view: View?) { - - view?.let { - usernameTv = it.findViewById(R.id.tv_username) - versionNameTv = it.findViewById(R.id.tv_version_name) - versionNameTv.text = BuildConfig.VERSION_NAME - usernameTv.text = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME) - - exitTv = it.findViewById(R.id.tv_exit) - exitTv.setOnClickListener(this) - expensesRecordTv = it.findViewById(R.id.tv_expenses_record) - expensesRecordTv.setOnClickListener(this) - changePasswordTv = it.findViewById(R.id.tv_change_password) - changePasswordTv.setOnClickListener(this) - commonProblemTv = it.findViewById(R.id.tv_common_problem) - commonProblemTv.setOnClickListener(this) - pointCardTv = it.findViewById(R.id.tv_point_card) - pointCardTv.setOnClickListener(this) - currentVersionRl = it.findViewById(R.id.rl_current_version) - currentVersionRl.setOnClickListener(this) - it.findViewById(R.id.rl_kefu).setOnClickListener(this) - it.findViewById(R.id.rl_add_freiend).setOnClickListener(this) - rl_band_phone = it.findViewById(R.id.rl_band_phone) - - it.findViewById(R.id.rl_tixian).setOnClickListener(this) - bandGiftTv = it.findViewById(R.id.tv_band_gift) - tv_tixian_amount = it.findViewById(R.id.tv_tixian_amount) - - tvProxyModel = it.findViewById(R.id.tv_proxy_model) - scProxyModel = it.findViewById(R.id.sc_proxy_model) - scProxyModel.setOnCheckedChangeListener { _, b -> - MMKV.defaultMMKV().encode(BZYConstants.MMKV_KEY_GLOBAL_MODEL, b) - if (b) { - tvProxyModel.setText("全局模式") - } else { - tvProxyModel.setText("智能模式") - } - RxToast.success("已切换,重连接生效") - } - - if (MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_GLOBAL_MODEL)) { - tvProxyModel.setText("全局模式") - } - - if (MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_IS_PERFECT)) { - rl_band_phone.setOnClickListener(this) - rl_band_phone.visibility = View.VISIBLE - } - - - expireDateTv = it.findViewById(R.id.tv_expire_date) - val validPeriod = MMKV.defaultMMKV().decodeLong(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD) - if (validPeriod > 0) { - val dateFormat = SimpleDateFormat("yyyy.MM.dd HH:mm", Locale.CHINA) - expireDateTv.text = dateFormat.format(validPeriod) - } else { - expireDateTv.text = "--" - } - - supportAccelerationStatusTv = it.findViewById(R.id.tv_support_acceleration_status) - val isExpired = MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_VPN_EXPIRED) - val valid_period = MMKV.defaultMMKV().decodeLong(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD) - - updateAccountStatus(isExpired, valid_period) - } - - viewModel = ViewModelProvider(this).get(MineViewModel::class.java) - viewModel.statusData.observe(viewLifecycleOwner) { - when (it) { - is HttpStatus.Success -> { - (it.rsp as AppDataInfoRsp).let { data -> - if (data.code == 1000) { - bandGiftTv.text = "完善成功,赠送 ${data.data?.dataGiftdays} 天" - // tv_tixian_amount.text = "可提现金额 ${data.data?.rewardTotalAmount} 元" - if (data.data?.rewardTotalAmount != null) { - canRewardAmount = data.data?.rewardTotalAmount!! - } - } - } - } - - else -> {} - } - } - MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME) - ?.let { viewModel.appDataInfo(it) } - } - - /*override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) - }*/ - - override fun onClick(v: View?) { - when (v?.id) { - R.id.tv_expenses_record -> { - val intent = Intent(CommonUtils.getApp(), ExpensesRecordActivity::class.java) - startActivity(intent) - } - - R.id.tv_point_card -> { - val intent = Intent(CommonUtils.getApp(), MyPointCardActivity::class.java) - startActivity(intent) - } - - R.id.tv_change_password -> { - val intent = Intent(CommonUtils.getApp(), ChangePwdActivity::class.java) - startActivity(intent) - } - - R.id.rl_kefu -> { - val intent = Intent(Intent.ACTION_VIEW) - val uri = Uri.parse("https://t.me/bazhuayuvpn") - intent.setData(uri) - startActivity(intent) - } - - R.id.rl_current_version -> { - RxToast.success("已经是最新版本") - } - - R.id.tv_exit -> { - MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_TOKEN) - MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_CURRENT_NODE) - startActivity(Intent(CommonUtils.getApp(), LoginActivity::class.java)) - activity?.finish() - } - - R.id.rl_add_freiend -> { - val intent = Intent(CommonUtils.getApp(), ShareActivity::class.java) - startActivity(intent) - } - - R.id.rl_band_phone -> { - val dialog = DialogBandChoose(activity) - dialog.setOnBandClickListener(object : DialogBandChoose.OnBandClickListener { - override fun onBandClick(isPhone: Boolean) { - val intent = Intent(CommonUtils.getApp(), BandPhoneActivity::class.java) - intent.putExtra("isPhone", isPhone) - startActivityForResult(intent, 98) - } - }) - dialog.show() - } - - R.id.rl_tixian -> { - val intent = Intent(CommonUtils.getApp(), ZFBTXActivity::class.java) - startActivityForResult(intent, 90) - } - } - } - - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - if (requestCode == 98 && resultCode == 100) { - MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_TOKEN) - MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_CURRENT_NODE) - startActivity(Intent(CommonUtils.getApp(), LoginActivity::class.java)) - activity?.finish() - } else if (requestCode == 90 && resultCode == 101) { - // viewModel.appDataInfo(MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME)) - } - } - - fun updateAccountStatus(isExpired: Boolean, validityPeriod: Long) { - if (::supportAccelerationStatusTv.isInitialized) { - if (isExpired) { - supportAccelerationStatusTv.text = "不支持加速" - } else { - supportAccelerationStatusTv.text = "支持加速" - } - } - if (::expireDateTv.isInitialized) { - if (validityPeriod > 0) { - val dateFormat = SimpleDateFormat("yyyy.MM.dd HH:mm", Locale.CHINA) - expireDateTv.text = dateFormat.format(validityPeriod) - } else { - expireDateTv.text = "--" - } - } - } - - -} \ No newline at end of file diff --git a/app/src/main/java/com/yingmao/clash/fragment/mine/MineViewModel.kt b/app/src/main/java/com/yingmao/clash/fragment/mine/MineViewModel.kt deleted file mode 100644 index 04c1c95..0000000 --- a/app/src/main/java/com/yingmao/clash/fragment/mine/MineViewModel.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.yingmao.clash.fragment.mine - - -import com.tencent.mmkv.MMKV -import com.yingmao.clash.base.PublicViewMode -import com.yingmao.clash.conf.BZYConstants -import com.yingmao.clash.net.http.HttpApi -import com.yingmao.clash.net.http.HttpReqType -import com.yingmao.clash.net.http.NetService - - -class MineViewModel : PublicViewMode() { - - fun appDataInfo(phone: String) { - val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN,"")!! - val params = mutableMapOf( - "phoneNumber" to phone, - "phToken" to phToken - ) - val httpApi = NetService.instances.createHttps(HttpApi::class.java) - doAsync(HttpReqType.APPDATAINFO) { httpApi.appDataInfo(params) } - } - - -} \ No newline at end of file diff --git a/app/src/main/java/com/yingmao/clash/fragment/recharge/RechargeFragment.kt b/app/src/main/java/com/yingmao/clash/fragment/recharge/RechargeFragment.kt index 5f3ef47..e69de29 100644 --- a/app/src/main/java/com/yingmao/clash/fragment/recharge/RechargeFragment.kt +++ b/app/src/main/java/com/yingmao/clash/fragment/recharge/RechargeFragment.kt @@ -1,1113 +0,0 @@ -package com.yingmao.clash.fragment.recharge - -import android.app.Activity -import android.content.Context -import android.content.Intent -import android.graphics.Color -import android.net.Uri -import android.os.Bundle -import android.text.TextUtils -import android.util.Log -import android.view.View -import android.widget.Button -import android.widget.FrameLayout -import android.widget.ImageView -import android.widget.LinearLayout -import android.widget.ProgressBar -import android.widget.RelativeLayout -import android.widget.Switch -import android.widget.TextView -import android.widget.Toast -import androidx.appcompat.widget.AppCompatImageView -import androidx.lifecycle.ViewModelProvider -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout -import com.afollestad.materialdialogs.MaterialDialog -import com.afollestad.materialdialogs.customview.customView -import com.afollestad.materialdialogs.customview.getCustomView -import com.alipay.sdk.app.PayTask -import com.chad.library.adapter.base.BaseQuickAdapter -//import com.google.zxing.BarcodeFormat -//import com.google.zxing.MultiFormatWriter -//import com.journeyapps.barcodescanner.BarcodeEncoder -import com.orhanobut.logger.Logger -import com.stripe.android.PaymentConfiguration -import com.stripe.android.Stripe -import com.stripe.android.confirmAlipayPayment -import com.stripe.android.model.ConfirmPaymentIntentParams -import com.stripe.android.model.StripeIntent -import com.tencent.mmkv.MMKV -import com.yingmao.clash.R -import com.yingmao.clash.act.ExpensesRecordActivity -import com.yingmao.clash.act.NewMainActivity -import com.yingmao.clash.act.SplashHelper -import com.yingmao.clash.conf.BZYConstants -import com.yingmao.clash.conf.PayType -import com.yingmao.clash.entity.CheckLoginRsp -import com.yingmao.clash.entity.PayUploadParamData -import com.yingmao.clash.fragment.BaseFragment -import com.yingmao.clash.fragment.NewAccFragment -import com.yingmao.clash.fragment.recharge.adapter.RechargeListAdapter -import com.yingmao.clash.net.http.HttpReqType -import com.yingmao.clash.net.http.HttpStatus -import com.yingmao.clash.net.http.entity.BiLaiPayStatusRsp -import com.yingmao.clash.net.http.entity.Grade -import com.yingmao.clash.net.http.entity.NormalMessageRsp -import com.yingmao.clash.net.http.entity.NormalRsp -import com.yingmao.clash.net.http.entity.PayRsp -import com.yingmao.clash.net.http.entity.QRPayRsp -import com.yingmao.clash.net.http.entity.QRPayStatusRsp -import com.yingmao.clash.net.http.entity.RechargeInfoRsp -import com.yingmao.clash.net.http.entity.Trade -import com.yingmao.clash.util.CommonUtils -import com.yingmao.clash.util.PayUtils -import com.yingmao.clash.util.ThreadUtils.runOnUiThread -import com.yingmao.clash.view.RxToast -import com.yingmao.clash.view.dialog.DialogDoMainChoose -import com.yingmao.clash.view.dialog.DialogPayTypeChoose -import com.yingmao.clash.view.dialog.RxDialogShapeLoading -import com.yingmao.clash.webview.BZYWebViewActivity -import com.yingmao.clash.webview.BZYWebViewNormal -import kotlinx.coroutines.DelicateCoroutinesApi -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.MainScope -import kotlinx.coroutines.launch -import java.text.DecimalFormat - - -class RechargeFragment : BaseFragment() { - - private lateinit var viewModel: RechargeViewModel - private lateinit var rechargeListRv: RecyclerView - private lateinit var pointCardSurplusSwitch: Switch - private lateinit var pointLoadingPb: ProgressBar - private lateinit var pointTv: TextView - private lateinit var payTv: TextView - private var selectedGrade: Grade? = null - private var pointCard: String = "0" - private var mPayType: String = "1" - private lateinit var rxDialogShapeLoading: RxDialogShapeLoading - private lateinit var dialogPayTypeChoose: DialogPayTypeChoose - private lateinit var swipeLayout: SwipeRefreshLayout - private var wx_pay_outTradeNo: String = "" - private var customizedProduct = "八爪鱼" - private lateinit var tv_pay: TextView - private var qrPayDialog: MaterialDialog? = null - private var outTradeNo = "" - - //实际需要支付金额 - private lateinit var actualPaymentAmount: String - - private var selectedGradeID: Int = 0 - - companion object { - //记录心跳失败次数 - const val REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY = 1000 - } - - var baseLoading: RxDialogShapeLoading? = null - - //stripePay 支付 - private var paymentIntentClientSecret: String = "" - private val stripe: Stripe by lazy { - Stripe( - requireActivity(), - PaymentConfiguration.getInstance(requireActivity()).publishableKey - ) - } - - override fun init( - titleBarRl: RelativeLayout, - backIv: ImageView, - moreTv: TextView, - titleTv: TextView, - container: FrameLayout, - ) { - titleBarRl.visibility = View.VISIBLE - backIv.visibility = View.VISIBLE - moreTv.visibility = View.VISIBLE - titleTv.visibility = View.VISIBLE - moreTv.setOnClickListener { - startActivity(Intent(activity, ExpensesRecordActivity::class.java)) - } - backIv.setOnClickListener { - activity?.finish() - } - titleTv.text = resources.getString(R.string.recharge) - moreTv.text = resources.getString(R.string.expenses_record) - val view = View.inflate(CommonUtils.getApp(), R.layout.fragment_recharge_new, null) - initViews(view) - container.addView(view) - } - - private fun initViews(view: View) { - tv_pay = view.findViewById(R.id.tv_pay) - swipeLayout = view.findViewById(R.id.swipeLayout) - payTv = view.findViewById(R.id.tv_pay) - payTv.text = resources.getString(R.string.PayNow) - swipeLayout.setColorSchemeColors(Color.rgb(47, 223, 189)) - swipeLayout.setOnRefreshListener { - selectedGrade = null - payTv.text = resources.getString(R.string.PayNow) - val username = - MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")!! - val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN, "")!! -// viewModel.getPointCardSurplus(username, phToken) - //获取充值列表 - val userId = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_USER_ID)!! - viewModel.getPhRechargeInfo(username, phToken, userId) - } - - rechargeListRv = view.findViewById(R.id.rv_recharge_list) - - pointLoadingPb = view.findViewById(R.id.pb_point_loading) - pointTv = view.findViewById(R.id.tv_point) - - - pointCardSurplusSwitch = view.findViewById(R.id.switch_balance) - pointCardSurplusSwitch.setOnCheckedChangeListener { _, isChecked -> - if (selectedGrade != null) { - val point = pointCard.toFloat() - val amount = selectedGrade!!.amount?.toFloat() - if (amount != null) { - val decimalFormat = DecimalFormat("¥#0.00") - if (isChecked) { - if (amount > point) { - pointCardSurplusSwitch.isChecked = false //暂时先这样,点数不够一次付款不能用点 - RxToast.warning(resources.getString(R.string.InsufficientPoints)) - } else { - tv_pay.text = resources.getString(R.string.PayNow) + "(¥0.00)" - } - } else { - tv_pay.text = - resources.getString(R.string.PayNow) + "(${decimalFormat.format(amount)})" - } - } - } else { - RxToast.warning(resources.getString(R.string.PleaseChoosePackage)) - pointCardSurplusSwitch.isChecked = false //暂时先这样,点数不够一次付款不能用点 - } - } - - payTv.setOnClickListener { - if (selectedGrade == null) { - RxToast.info(resources.getString(R.string.selectRechargeAmount)) - return@setOnClickListener - } - var isUsePointCard = false - if (pointCardSurplusSwitch.isChecked) { //使用点卡 - val point = pointCard.toFloat() - val amount = selectedGrade!!.amount?.toFloat() - if (amount != null) { -// if(amount > point) { //点卡不足 -// isUsePointCard = true -// actualPaymentAmount = "${amount-point}" -// }else { //点卡充足使用纯点卡支付 - Logger.d("纯点卡支付") - viewModel.purePointCardPayment(selectedGrade!!, pointCard) - return@setOnClickListener - } - } else { - isUsePointCard = false - actualPaymentAmount = "${selectedGrade!!.amount}" - } - - actualPaymentAmount = "${selectedGrade!!.amount}" - activity?.apply { - viewModel.pay("1", selectedGrade!!, pointCard) -// if (!::dialogPayTypeChoose.isInitialized) { -// dialogPayTypeChoose = DialogPayTypeChoose(this) -// } -// dialogPayTypeChoose.setTitle("请选择支付方式") -// dialogPayTypeChoose.setOnPayTypeCheckedListener(object : DialogPayTypeChoose.OnPayTypeCheckedListener { -// var isNeedGetOutTradeNo = false //是否需要先获取订单号再进行支付。 -// override fun onPayTypeChecked(payType: String) { -// -// mPayType = if (isUsePointCard) { -// when (payType) { -// PayType.PAY_TYPE_ALI_APP -> { //吊起App支付 -// isNeedGetOutTradeNo = true -// PayType.PAY_TYPE_ALI_POINT -// } -// -// else -> { -// if (payType != PayType.PAY_TYPE_Stripe) {//stripe不需要先获取订单号 -// isNeedGetOutTradeNo = true -// } -// payType -// } -// } -// } else { -// if (payType == PayType.PAY_TYPE_ALI_APP) { -// isNeedGetOutTradeNo = true -// PayType.PAY_TYPE_ALI -// } else { -// payType -// } -// } -// -// -// if (isNeedGetOutTradeNo) { -// viewModel.pay(mPayType, selectedGrade!!, pointCard) -// } else if (payType == PayType.PAY_TYPE_Stripe) { -// //跳转到浏览器进行支付无需获取订单号 -// val intent = Intent(activity, BZYWebViewOther::class.java) -// intent.putExtra("payUrl", selectedGrade!!.stripePay) -// // startActivityForResult(intent,MainActivity.REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY) -// startActivityFromFragment(this@RechargeFragment, intent, REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY) -// } else if (payType == PayType.PAY_TYPE_BiLai_ZFB) { //币来 -// viewModel.pay("1", selectedGrade!!, pointCard) -// } else if (payType == PayType.PAY_TYPE_BiLai_WX) { //币来 -// viewModel.pay("2", selectedGrade!!, pointCard) -// } else if (payType == PayType.PAY_TYPE_BiLai_JD) {//币来 -// viewModel.pay("1", selectedGrade!!, pointCard) -// } else if (payType == PayType.PAY_TYPE_BiLai_WEB) {// todo 币来网页支付 -// viewModel.pay("1", selectedGrade!!, pointCard) -// } else { -// val money = selectedGrade!!.amount?.toFloat()?.toInt().toString() -// viewModel.codePay(mPayType, selectedGrade!!, money, customizedProduct) -// } -// -// if (dialogPayTypeChoose.isShowing) { -// dialogPayTypeChoose.cancel() -// } -// } -// }) -// if (!dialogPayTypeChoose.isShowing) { -// dialogPayTypeChoose.show() -// } - } - } - } - - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) - viewModel = ViewModelProvider(this).get(RechargeViewModel::class.java) - //获取充值列表 - val username = - MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")!! - - val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN, "")!! -// viewModel.getPointCardSurplus(username, phToken) - val userId = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_USER_ID)!! - viewModel.getPhRechargeInfo(username, phToken, userId) - observe(this, viewModel) - } - - override fun onResume() { - super.onResume() -// val username = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME,"")!! -// val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN,"")!! -// viewModel.getPointCardSurplus(username, phToken) - } - - override fun httpLoading(httpStatus: HttpStatus.Loading) { - when (httpStatus.reqType) { - HttpReqType.GET_POINTCARD_SURPLUS -> { - Logger.d("开始获取点卡余额") - pointCardSurplusSwitch.isEnabled = false - pointLoadingPb.visibility = View.VISIBLE - pointTv.visibility = View.GONE - } - - HttpReqType.GET_RECHARGE_INFO -> { - Logger.d("获取充值续费信息") - swipeLayout.isRefreshing = true - } - - HttpReqType.PAY -> { - Logger.d("支付获取订单号") - showLoadingDialog(resources.getString(R.string.GeneratingOrder)) - } - - HttpReqType.APP_ALI_PAY -> { - Logger.d("RechargeFragment:支付宝支付") - showLoadingDialog(resources.getString(R.string.RequestingPayment)) - } - - HttpReqType.PURE_POINT_CARD_PAYMENT -> { - Logger.d("纯点卡支付") - showLoadingDialog(resources.getString(R.string.PaymentIn)) - } - - HttpReqType.QRPAY -> { - showLoadingDialog(resources.getString(R.string.GeneratingOrder)) - } - - HttpReqType.QRPAYSTATU -> { - showLoadingDialog(resources.getString(R.string.QueryingPaymentResult)) - } - - HttpReqType.WEBPAYQUERY -> { - showLoadingDialog(resources.getString(R.string.QueryingPaymentResult)) - } - - else -> {} - } - } - - private fun hideLoadingDialog() { - if (::rxDialogShapeLoading.isInitialized && rxDialogShapeLoading.isShowing) { - rxDialogShapeLoading.cancel() - } - } - - private fun showLoadingDialog(content: String) { - activity?.apply { - if (!::rxDialogShapeLoading.isInitialized) { - rxDialogShapeLoading = RxDialogShapeLoading(this) - } - rxDialogShapeLoading.setLoadingText(content) - rxDialogShapeLoading.setCancelable(false) - if (!rxDialogShapeLoading.isShowing) { - rxDialogShapeLoading.show() - } - } - } - - override fun httpSuccess(httpStatus: HttpStatus.Success) { - when (httpStatus.reqType) { - HttpReqType.GET_POINTCARD_SURPLUS -> { - Logger.d("获取点卡余额请求成功") - pointLoadingPb.visibility = View.GONE - pointTv.visibility = View.VISIBLE - if (pointCardSurplusSwitch.isChecked) { - pointCardSurplusSwitch.isChecked = false - } - (httpStatus.rsp as NormalRsp).let { - if (it.code != "1000") { - //RxToast.error(if (it.message.isNullOrBlank()) "获取点卡余额失败(${it.code})" else "${it.code}:${it.message}") - pointTv.text = resources.getString(R.string.retry) - pointCard = "0" - pointTv.setTextColor(resources.getColor(R.color.white_50)) - pointTv.setOnClickListener { - val username = MMKV.defaultMMKV() - .decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")!! - val phToken = MMKV.defaultMMKV() - .decodeString(BZYConstants.MMKV_KEY_PH_TOKEN, "")!! - viewModel.getPointCardSurplus(username, phToken) - } - } else { - pointCard = "${it.data}" - pointCardSurplusSwitch.isEnabled = pointCard.toInt() > 0 - pointTv.setTextColor(resources.getColor(R.color.white)) - pointTv.text = - resources.getString(R.string.RemainingPoints) + ": ${if (it.data.isNullOrEmpty()) "0.00" else it.data}" - } - } - } - - HttpReqType.GET_RECHARGE_INFO -> { - Logger.d("获取充值续费信息请求成功") - dialogDoMainChoose?.dismiss() - swipeLayout.isRefreshing = false - (httpStatus.rsp as RechargeInfoRsp).let { it -> - if (it.code != "1000") { - RxToast.error(if (it.message.isNullOrBlank()) resources.getString(R.string.FailedRechargeList) + "(${it.code})" else "${it.code}:${it.message}") - } else { - it.data?.let { it1 -> - Logger.d("AAAAAAAAAAA:::${it1.grade}") - it1.grade?.let { - Logger.d("AAAAAAAAAAA:::${it} size ${it.size}") - if (it.size > 0) { - customizedProduct = it1.customizedProduct!! - initAdapter(it) - } - } - } - } - } - } - - HttpReqType.PAY -> { - hideLoadingDialog() - Logger.d("生成订单请求成功") - (httpStatus.rsp as PayRsp).let { rsp -> - if (rsp.code != "1000") { - RxToast.error(if (rsp.message.isNullOrBlank()) resources.getString(R.string.OrderGenerationFailed) + "(${rsp.code})" else "${rsp.code}:${rsp.message}") - } else { - activity.let { - outTradeNo = rsp.data?.outTradeNo!! - val newUrl = rsp.data?.payUrl.toString() - orderPayment(rsp.data) - Logger.e("支付url:${newUrl}") - } - } - } - } - - HttpReqType.unionPay -> { - (httpStatus.rsp as PayRsp).let { rsp -> - if (rsp.code != "1000") { - RxToast.error(if (rsp.message.isNullOrBlank()) resources.getString(R.string.OrderGenerationFailed) + "(${rsp.code})" else "${rsp.code}:${rsp.message}") - } else { - if (rsp.data != null) { - startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(rsp.data.payUrl))) - } - } - } - } - - HttpReqType.PURE_POINT_CARD_PAYMENT -> { - Logger.d("纯点卡支付请求成功") - val username = - MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")!! - val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN, "")!! - viewModel.getPointCardSurplus(username, phToken) - hideLoadingDialog() - (httpStatus.rsp as NormalMessageRsp).let { - if (it.code != "1000") { - RxToast.error(if (it.message.isNullOrBlank()) resources.getString(R.string.PointCardFailed) + "(${it.code})" else "${it.code}:${it.message}") - } else { - RxToast.success(resources.getString(R.string.PointCardSuccessful)) - Logger.d("点卡支付成功更新有效期") - viewModel.checkLogin() - } - } - } - - HttpReqType.CHECK_LOGIN -> { - Logger.d("支付成功更新有效期") - val checkLoginRsp = httpStatus.rsp - if (checkLoginRsp is CheckLoginRsp) { - if (checkLoginRsp.code == 0) { - Logger.d("支付成功更新有效期${activity}") - val expired = checkLoginRsp.data?.expired - val mmkv = MMKV.defaultMMKV() - mmkv.encode(BZYConstants.MMKV_KEY_VPN_EXPIRED, expired ?: true) - mmkv.encode( - BZYConstants.MMKV_KEY_VPN_VALID_PERIOD, - checkLoginRsp.data?.vpnExpireTime ?: 0 - ) - if (activity is NewMainActivity) { - val newMainAt = activity as NewMainActivity - newMainAt.setExpireDate() - } - } else { - Logger.d("微信或者支付宝支付成功更新有效期失败:${checkLoginRsp.code}${checkLoginRsp.msg}") - } - } - } - - HttpReqType.QRPAY -> { - hideLoadingDialog() - (httpStatus.rsp as QRPayRsp).let { - if (it.code == 1000) { - val url = it.data?.code_url - outTradeNo = it.data?.outTradeNo!! - activity?.let { - qrPayDialog = MaterialDialog(it).show { - this.cancelable(false) - cornerRadius(res = R.dimen.dp_10) - customView( - R.layout.qrpay_dialog_layout, - scrollable = false, - noVerticalPadding = true, - horizontalPadding = false - ) - - if (mPayType == PayType.PAY_TYPE_ALI) { - getCustomView().findViewById(R.id.tv_qr_pay_note) - .setText(R.string.qr_pay_note_zfb) - } else { - getCustomView().findViewById(R.id.tv_qr_pay_note) - .setText(R.string.qr_pay_note_wx) - } - - val ivQr = getCustomView().findViewById(R.id.iv_qr) - -// val writer = MultiFormatWriter() -// val matrix = writer.encode(url, BarcodeFormat.QR_CODE, 300, 300) -// val encoder = BarcodeEncoder() -// val bitmap = encoder.createBitmap(matrix) -// ivQr.setImageBitmap(bitmap) - - getCustomView().findViewById(R.id.tv_pay_finish) - .setOnClickListener { - showLoadingDialog(resources.getString(R.string.QueryingPaymentResult)) - viewModel.codePayStatus(outTradeNo) - } - -// getCustomView().findViewById(R.id.tv_pay_cancle).setOnClickListener { -// if (bitmap != null && !bitmap.isRecycled) { -// bitmap.recycle() -// dismiss() -// } -// } - } - } - } else { - RxToast.error(resources.getString(R.string.FailedPaymentQRCode)) - } - } - } - - HttpReqType.QRPAYSTATU -> { - hideLoadingDialog() - (httpStatus.rsp as QRPayStatusRsp).let { - if (it.code == 1000) { - RxToast.success(resources.getString(R.string.upUser)) - qrPayDialog?.dismiss() - viewModel.checkLogin() - } else { - RxToast.error(resources.getString(R.string.paymentFound)) - } - } - } - - HttpReqType.WEBPAYQUERY -> { - hideLoadingDialog() - (httpStatus.rsp as NormalMessageRsp).let { - if (it.code == "1000") { - RxToast.success(resources.getString(R.string.upUser)) - qrPayDialog?.dismiss() - viewModel.checkLogin() - } else { - RxToast.error(resources.getString(R.string.paymentFound)) - } - } - } - - HttpReqType.BILAIPAYSTATUS -> { - hideLoadingDialog() - (httpStatus.rsp as BiLaiPayStatusRsp).let { - if (it.code == 1000) { - RxToast.error(resources.getString(R.string.paymentFound)) - qrPayDialog?.dismiss() - viewModel.checkLogin() - } else { - RxToast.error(resources.getString(R.string.paymentFound)) - } - } - } - - HttpReqType.BILAIPAY -> { - hideLoadingDialog() -// if (mPayType == PayType.PAY_TYPE_BiLai_ZFB) { -// goWebViewStartPayClient(httpStatus.rsp, false) -// } else if (mPayType == PayType.PAY_TYPE_BiLai_WX) { -// goWebViewStartPayClient(httpStatus.rsp, false) -// } else if (mPayType == PayType.PAY_TYPE_BiLai_WEB) { -// goWebViewStartPayClient(httpStatus.rsp, true) -// } else { -// goWebViewStartPayClient(httpStatus.rsp, false) -// } - } - - HttpReqType.StripeType -> { - (httpStatus.rsp as PayUploadParamData).let { - if (it.data != null) { - paymentIntentClientSecret = it.data.clientSecret.toString() - startCheckout() - } else { - hideLoading() - RxToast.info(getString(R.string.NoPaymentReceipt)) - } - } - } - - else -> {} - } - } - - private fun orderPayment(data: Trade) { - if (data.payType != null) { - activity?.let { - MaterialDialog(it).show { - this.cancelable(true) - cornerRadius(res = R.dimen.dp_10) - customView( - R.layout.backup_payment_dialog, - scrollable = false, - noVerticalPadding = true, - horizontalPadding = false - ) -// for (index in data.payType!!) { -// if (index.payModel == 10) { -// findViewById(R.id.llAggregatePayment).visibility = -// View.VISIBLE -// val JUhePay = findViewById(R.id.JUhePay) -// JUhePay.visibility = View.VISIBLE -// JUhePay.text = index.payChannel -// if (index.payType == 1) { -// val ivAlipay = findViewById(R.id.ivAlipay) -// ivAlipay.visibility = View.VISIBLE -// ivAlipay.setOnClickListener { -// val payModel = index.payModel -// val payType = index.payType -// val payParam = index.payParam -// if (payModel != null && payType != null && payParam != null) { -// viewModel.orderPayment(data, payModel, payType, payParam) -// } else { -// viewModel.orderPayment(data, 10, 1, "ip@影猫充值") -// } -// } -// } else if (index.payType == 2) { -// val ivWechatPay = findViewById(R.id.ivWechatPay) -// ivWechatPay.visibility = View.VISIBLE -// ivWechatPay.setOnClickListener { -// val payModel = index.payModel -// val payType = index.payType -// val payParam = index.payParam -// if (payModel != null && payType != null && payParam != null) { -// viewModel.orderPayment(data, payModel, payType, payParam) -// } else { -// viewModel.orderPayment(data, 10, 2, "ip@影猫充值") -// } -// -// } -// } -// } else if (index.payModel == 11) { -// findViewById(R.id.llQuickPayment).visibility = -// View.VISIBLE -// val KJPay = findViewById(R.id.KJPay) -// KJPay.visibility = View.VISIBLE -// KJPay.text = index.payChannel -// if (index.payType == 1) { -// val ivQuickPayment = -// findViewById(R.id.ivQuickPayment) -// ivQuickPayment.visibility = View.VISIBLE -// ivQuickPayment.setOnClickListener { -// val payModel = index.payModel -// val payType = index.payType -// val payParam = index.payParam -// if (payModel != null && payType != null && payParam != null) { -// viewModel.orderPayment(data, payModel, payType, payParam) -// } else { -// viewModel.orderPayment(data, 11, 1, "ip@影猫充值") -// } -// } -// } else if (index.payType == 2) { -// val ivQPWechatPay = -// findViewById(R.id.ivQPWechatPay) -// ivQPWechatPay.visibility = View.VISIBLE -// ivQPWechatPay.setOnClickListener { -// val payModel = index.payModel -// val payType = index.payType -// val payParam = index.payParam -// if (payModel != null && payType != null && payParam != null) { -// viewModel.orderPayment(data, payModel, payType, payParam) -// } else { -// viewModel.orderPayment(data, 11, 1, "ip@影喵充值") -// } -// } -// } -// } else if (index.payModel == 7) { -// findViewById(R.id.llStripe).visibility = View.VISIBLE -// findViewById(R.id.llStripePay).visibility = View.VISIBLE -// var payinfo = findViewById(R.id.tvStripePay) -// payinfo.visibility = View.VISIBLE -// -// payinfo.text = index.payChannel -// findViewById(R.id.ivStripeAlipay).visibility = -// View.VISIBLE -// findViewById(R.id.ivStripeAlipay).setOnClickListener { -// if (selectedGradeID != 0) { -// if (!PayUtils.isAlipayInstalled(requireActivity())) { -// RxToast.error(resources.getString(R.string.AlipayNotInstalled)) -// return@setOnClickListener -// } -// dismiss() -// showLoading( -// resources.getString(R.string.PaymentIn), -// requireActivity() -// ) -// Log.i("PayGradeID:", "PayGradeID:${selectedGradeID}") -// viewModel.getPayClientSecret(selectedGradeID) -// } else { -// RxToast.info(getString(R.string.NoPaymentReceipt)) -// } -// } -// } -// } - getCustomView().findViewById(R.id.ivBack) - .setOnClickListener { - dismiss() - } - } - } - } - } - -// private fun goWebViewStartPayClient(rsp: BaseRsp, isPayWeb: Boolean) { -// (rsp as BiLaiNormalRsp).let { -// if (it.code != "1000") { -// RxToast.error(if (it.message.isNullOrBlank()) "获取支付信息失败(${it.code})" else "${it.code}:${it.message}") -// } else { -// if (isPayWeb) { -// activity?.let { -// if (rsp.data != null) { -//// goWebPay(it, rsp.data!!) -//// goWebPay(it, newUrl) -// } else { -// RxToast.error("未能获取到支付信息,请联系客服") -// } -// } -// return -// } -// -// val gson = Gson().fromJson(it.data!!, BiLaiRsp::class.java) -// Logger.d("跳转支付宝支付页面:" + gson.payurl) -// var realPayUrl = "" -// var isNeedScan = false -// if (gson.payurl != null) { -// realPayUrl = gson.payurl!! -// isNeedScan = false -// } else if (gson.qrcode != null) { -// realPayUrl = gson.qrcode!! -// isNeedScan = true -// } else { -// realPayUrl = gson.urlscheme!! -// isNeedScan = true -// } -// // Log.e("data==", "html:" + realPayUrl); -// -// -// activity?.let { -// if (!isNeedScan) { -//// goWebPay(it, newUrl) -// } else { -// //二维码支付 -// qrPayDialog = MaterialDialog(it).show { -// this.cancelable(false) -// cornerRadius(res = R.dimen.dp_10) -// customView(R.layout.qrpay_dialog_layout, scrollable = false, noVerticalPadding = true, horizontalPadding = false) -// getCustomView().findViewById(R.id.tv_qr_pay_note).setText(R.string.qr_pay_note_wx) -// -// val ivQr = getCustomView().findViewById(R.id.iv_qr) -// -// val writer = MultiFormatWriter() -// val matrix = writer.encode(realPayUrl, BarcodeFormat.QR_CODE, 300, 300) -// val encoder = BarcodeEncoder() -// val bitmap = encoder.createBitmap(matrix) -// ivQr.setImageBitmap(bitmap) -// -// getCustomView().findViewById(R.id.tv_pay_finish).setOnClickListener { -// showLoadingDialog("正在查询支付结果...") -// viewModel.codePayStatus(outTradeNo) -// } -// -// getCustomView().findViewById(R.id.tv_pay_cancle).setOnClickListener { -// if (bitmap != null && !bitmap.isRecycled) { -// bitmap.recycle() -// dismiss() -// } -// } -// } -// } -// } -// } -// } -// }/ - - fun goWebPay(it: Activity, realPayUrl: String) { - val intent = Intent(context, BZYWebViewNormal::class.java) - intent.putExtra(BZYConstants.EXTRA_KEY_PAY_TYPE, PayType.PAY_TYPE_WX) - intent.putExtra("url", realPayUrl) - intent.putExtra(BZYConstants.EXTRA_KEY_WX_PAY_OUT_TRADE_NO, wx_pay_outTradeNo) - startActivityForResult(intent, REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY) - - qrPayDialog = MaterialDialog(it).show { - this.cancelable(false) - cornerRadius(res = R.dimen.dp_10) - customView( - R.layout.payconfirm_dialog_layout, - scrollable = false, - noVerticalPadding = true, - horizontalPadding = false - ) - getCustomView().findViewById(R.id.tv_pay_finish).setOnClickListener { - showLoadingDialog(resources.getString(R.string.QueryingPaymentResult)) -// viewModel.biLaiPayStatus(outTradeNo) - viewModel.webPayStatus(outTradeNo) - } - getCustomView().findViewById(R.id.tv_pay_cancle).setOnClickListener { - dismiss() - } - } - } - - var dialogDoMainChoose: DialogDoMainChoose? = null - private fun showDomainList() { - try { - SplashHelper(viewModel).getHostWithFallback { success -> - MainScope().launch { - if (success) { - if (dialogDoMainChoose == null) { - dialogDoMainChoose = DialogDoMainChoose(this@RechargeFragment.activity) - } - if (dialogDoMainChoose?.isShowing == false) { - dialogDoMainChoose?.setOnTryButtonListener(object : - DialogDoMainChoose.OnTryButtonListener { - override fun tryButton() { - val username = MMKV.defaultMMKV() - .decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")!! - - val phToken = MMKV.defaultMMKV() - .decodeString(BZYConstants.MMKV_KEY_PH_TOKEN, "")!! -// viewModel.getPointCardSurplus(username, phToken) - val userId = MMKV.defaultMMKV() - .decodeString(BZYConstants.MMKV_KEY_USER_ID)!! - viewModel.getPhRechargeInfo(username, phToken, userId) - } - - override fun cancel() { - com.cncat.vpn.common.log.Log.d("tryButton CHECK_LOGIN cancel") - dialogDoMainChoose?.dismiss() - } - }) - dialogDoMainChoose?.setOnListItemListener(object : - DialogDoMainChoose.OnListItemListener { - override fun listItemClick() { - val username = MMKV.defaultMMKV() - .decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")!! - - val phToken = MMKV.defaultMMKV() - .decodeString(BZYConstants.MMKV_KEY_PH_TOKEN, "")!! -// viewModel.getPointCardSurplus(username, phToken) - val userId = MMKV.defaultMMKV() - .decodeString(BZYConstants.MMKV_KEY_USER_ID)!! - viewModel.getPhRechargeInfo(username, phToken, userId) - } - - }) - dialogDoMainChoose?.show() - } - } - } - } - - } catch (e: Exception) { - e.printStackTrace() - } - } - - override fun httpFailure(httpStatus: HttpStatus.Failure) { - if (::rxDialogShapeLoading.isInitialized && rxDialogShapeLoading.isShowing) { - rxDialogShapeLoading.cancel() - } - if (HttpReqType.CHECK_LOGIN == httpStatus.reqType) { - Logger.d("微信或者支付宝支付成功更新有效期异常") - } - val msgs: String = when (httpStatus.reqType) { - HttpReqType.GET_POINTCARD_SURPLUS -> { - Logger.d("获取点卡余额异常${httpStatus.msg}") - if (pointCardSurplusSwitch.isChecked) { - pointCardSurplusSwitch.isChecked = false - } - pointLoadingPb.visibility = View.GONE - pointTv.visibility = View.VISIBLE - pointTv.text = resources.getString(R.string.retry) - pointTv.setOnClickListener { - val username = MMKV.defaultMMKV() - .decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")!! - val phToken = - MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN, "")!! - viewModel.getPointCardSurplus(username, phToken) - } - resources.getString(R.string.AbnormalPointCard) - } - - HttpReqType.GET_RECHARGE_INFO -> { - showDomainList() - Logger.d("获取充值续费信息异常${httpStatus.msg}") - swipeLayout.isRefreshing = false - resources.getString(R.string.DataError) - } - - HttpReqType.PAY -> { - Logger.d("获取支付订单号异常${httpStatus.msg}") - resources.getString(R.string.DataPayNumber) - } - - HttpReqType.APP_ALI_PAY -> { - Logger.d("支付宝支付异常${httpStatus.msg}") - resources.getString(R.string.AlipayDataError) - } - - HttpReqType.APP_WX_PAY -> { - Logger.d("微信支付异常${httpStatus.msg}") - resources.getString(R.string.weChatPayError) - } - - HttpReqType.PURE_POINT_CARD_PAYMENT -> { - Logger.d("纯点卡支付异常${httpStatus.msg}") - resources.getString(R.string.PayCardException) - } - - HttpReqType.QRPAY -> { - resources.getString(R.string.AbnormalQRCode) - } - - HttpReqType.BILAIPAYSTATUS -> { - resources.getString(R.string.paymentResultsFailed) - } - - HttpReqType.WEBPAYQUERY -> { - resources.getString(R.string.paymentResultsFailed) - } - - HttpReqType.BILAIPAY -> { - resources.getString(R.string.paymentResultsFailed) - } - - HttpReqType.StripeType -> { - hideLoading() - resources.getString(R.string.NoPaymentReceipt) - } - - else -> { - hideLoading() - Logger.d("${httpStatus.reqType}${resources.getString(R.string.RequestException)}${httpStatus.msg}") - resources.getString(R.string.RequestException) + "${httpStatus.reqType}" - } - } - RxToast.error(msgs) - } - - private fun initAdapter(recharge: MutableList) { - val rechargeListAdapter = RechargeListAdapter(R.layout.recharge_list_item_layout) - rechargeListAdapter.animationEnable = false - rechargeListRv.layoutManager = LinearLayoutManager(CommonUtils.getApp()) - - rechargeListAdapter.data = recharge - rechargeListRv.adapter = rechargeListAdapter -// rechargeListAdapter.setOnItemClickListener { adapter, view, position -> -// -// } - rechargeListAdapter.setOnItemClickListener { baseQuickAdapter: BaseQuickAdapter<*, *>, view: View, position: Int -> - val selectedItem = baseQuickAdapter.getItem(position) - Logger.d("################$selectedItem") - if (selectedItem is Grade) { - selectedGrade = selectedItem -// RxToast.info(baseQuickAdapter.getItem(position).toString()) -// rechargeListAdapter.notifyItemChanged(rechargeListAdapter.selectorPosition) - if (rechargeListAdapter.selectorPosition == position) { - return@setOnItemClickListener - } - rechargeListAdapter.selectorPosition = position -// rechargeListAdapter.notifyItemChanged(position) - rechargeListAdapter.notifyDataSetChanged() - val amount = selectedGrade!!.amount?.toFloat() - if (amount != null) { - Log.i("AAAAAAAAA11", "${selectedGrade!!.id!!}") - if (selectedGrade!!.id != null) { - Log.i("AAAAAAAAA222", "${selectedGrade!!.id!!}") - selectedGradeID = selectedGrade!!.id!! - } - val decimalFormat = DecimalFormat("¥#0.00") - tv_pay.text = - resources.getString(R.string.PayNow) + "(${decimalFormat.format(amount)})" -// if (pointCardSurplusSwitch.isChecked) { -// val point = pointCard.toFloat() -// if (amount > point) { -// tv_pay.text = resources.getString(R.string.PayNow)+"(${decimalFormat.format(amount - point)})" -// } else { -// tv_pay.text =resources.getString(R.string.PayNow)+ "(¥0.00)" -// } -// } else { -// tv_pay.text = resources.getString(R.string.PayNow)+"(${decimalFormat.format(amount)})" -// } - } - } - } - } - - override fun onDestroy() { - super.onDestroy() -// val main = activity as NewMainActivity -// main.tv_rechar.visibility = View.VISIBLE - } - - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - if (requestCode == REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY) { - if (resultCode == BZYConstants.REQUEST_CODE_PAY_WEB_Stripe) { - RxToast.success(resources.getString(R.string.upUser), Toast.LENGTH_LONG) - viewModel.checkLogin() - } else if (resultCode == BZYWebViewActivity.ALI_PAY_SUCCESS || resultCode == BZYWebViewActivity.WX_PAY_SUCCESS) { - viewModel.checkLogin() - RxToast.success(resources.getString(R.string.upUser), Toast.LENGTH_LONG) - Log.e("data", "微信或者支付宝支付成功更新有效期") - } else if (resultCode == BZYConstants.REQUEST_CODE_PAY_WEB_BiLai) { -// activity?.let { -// MaterialDialog(it).show { -// this.cancelable(false) -// cornerRadius(res = R.dimen.dp_10) -// customView(R.layout.payconfirm_dialog_layout, scrollable = false, noVerticalPadding = true, horizontalPadding = false) -// -// getCustomView().findViewById(R.id.tv_pay_finish).setOnClickListener { -// showLoadingDialog("正在查询支付结果...") -// viewModel.codePayStatus(outTradeNo) -// } -// -// getCustomView().findViewById(R.id.tv_pay_cancle).setOnClickListener { -// dismiss() -// } -// } -// } - } - } - super.onActivityResult(requestCode, resultCode, data) - } - - @OptIn(DelicateCoroutinesApi::class) - private fun startCheckout() { - GlobalScope.launch { - runCatching { - stripe.confirmAlipayPayment( - ConfirmPaymentIntentParams.createAlipay(paymentIntentClientSecret), - { data -> PayTask(requireActivity()).payV2(data, true) } - ) - }.fold( - onSuccess = { result -> - hideLoading() - val paymentIntent = result.intent - when (paymentIntent.status) { - StripeIntent.Status.Succeeded -> { - Log.i("startCheckout", "支付成功") - runOnUiThread { - RxToast.info(getString(R.string.PaymentCompleted)) - } - } - - StripeIntent.Status.RequiresAction -> { - Log.i("startCheckout", "RequiresAction") - runOnUiThread { - RxToast.info(getString(R.string.PaymentCancellation)) - } - } - - else -> { - Log.i("startCheckout", "status::${paymentIntent.status}") - } - } - }, - onFailure = { - Log.i("startCheckout", "支付失败${it.message}") - hideLoading() - runOnUiThread { - RxToast.info(getString(R.string.NoPaymentReceipt)) - } - } - ) - } - } - - private fun showLoading(str: String, context: Context) { - val message = if (TextUtils.isEmpty(str)) "进行中..." else str - if (baseLoading == null) { - baseLoading = RxDialogShapeLoading(context) - } - baseLoading?.setMessage(message) - if (baseLoading?.isShowing == false) { - baseLoading?.show() - } - } - - fun hideLoading() { - if (baseLoading != null && baseLoading?.isShowing == true) { - baseLoading?.cancel() - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/yingmao/clash/fragment/setting/SettingFragment.kt b/app/src/main/java/com/yingmao/clash/fragment/setting/SettingFragment.kt index 4e72d38..937fa89 100644 --- a/app/src/main/java/com/yingmao/clash/fragment/setting/SettingFragment.kt +++ b/app/src/main/java/com/yingmao/clash/fragment/setting/SettingFragment.kt @@ -1,8 +1,6 @@ package com.yingmao.clash.fragment.setting import android.annotation.SuppressLint -import android.app.AlarmManager -import android.app.PendingIntent import android.content.ClipData import android.content.ClipboardManager import android.content.Context @@ -11,8 +9,6 @@ import android.net.Uri import android.os.Build import android.os.Bundle import android.os.Environment -import android.os.Handler -import android.os.Looper import android.provider.Settings import android.text.TextUtils import android.view.View @@ -43,14 +39,12 @@ import com.google.gson.Gson import com.hjq.permissions.OnPermissionCallback import com.hjq.permissions.Permission import com.hjq.permissions.XXPermissions -import com.jakewharton.processphoenix.ProcessPhoenix import com.orhanobut.logger.Logger import com.tencent.mmkv.MMKV import com.yingmao.clash.BuildConfig import com.yingmao.clash.R import com.yingmao.clash.act.AgreementAndPrivacyActivity import com.yingmao.clash.act.ChangePwdActivity -import com.yingmao.clash.act.InstallApplicationActivity import com.yingmao.clash.act.LoginActivity import com.yingmao.clash.act.LossPreventionActivity import com.yingmao.clash.act.NewMainActivity @@ -82,7 +76,6 @@ import com.yingmao.clash.view.RxToast import com.yingmao.clash.view.adapter.LanguageAdapter import com.yingmao.clash.view.dialog.DialogDoMainChoose import com.yingmao.clash.view.dialog.DialogNotice -import com.yingmao.clash.view.dialog.DialogSureRestartChoose import com.yingmao.clash.view.dialog.RxDialogShapeLoading import com.yingmao.clash.vm.MainAtyVM import com.yingmao.clash.webview.BZYWebViewKeFu @@ -97,7 +90,6 @@ import java.text.SimpleDateFormat import java.util.Date import java.util.Locale import java.util.UUID -import kotlin.system.exitProcess class SettingFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatchers.IO) { @@ -257,10 +249,10 @@ class SettingFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatc } setExpireDate() - if (checkExpire()) { - userIdentity.text = requireActivity().resources.getString(R.string.TemporaryUser) - } else { + if (isVip) { userIdentity.text = requireActivity().resources.getString(R.string.VIPMember) + } else { + userIdentity.text = requireActivity().resources.getString(R.string.TemporaryUser) } userIdentityNumber.text = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME) @@ -328,7 +320,16 @@ class SettingFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatc startActivity(intent) } initializationRepair.setOnClickListener { + if (checkExpire()) { + RxToast.info(resources.getString(R.string.AccountExpired)) + return@setOnClickListener + } + if(clashRunning){ + RxToast.info("请关闭加速后在进行初始化操作") + return@setOnClickListener + } if (TextUtils.isEmpty(subUrl)) { + RxToast.success(resources.getString(R.string.tooFast)) return@setOnClickListener } cleanNodeMmkv() @@ -337,6 +338,7 @@ class SettingFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatc launch(Dispatchers.IO) { profileBinder?.let { pm -> pm.queryAll().forEach { profile -> + Log.d("setting profile delete ==>${profile.name}") pm.delete(profile.uuid) } @@ -636,6 +638,12 @@ class SettingFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatc MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_VPN_UserCommand) MMKV.defaultMMKV().removeValueForKey(BZYConstants.NODE_All_ITEM_NAME_KEY) MMKV.defaultMMKV().removeValueForKey(BZYConstants.PROFILE_SUB_URL) + + MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_Switch_Finsh_Set) + + //清除源切换记录 + + UIMainActivity.isSubed=false Log.d("cleanUserInfo clashRunning==>${clashRunning}") if (clashRunning) { fragments.filterIsInstance().forEach { it.stopClash() } diff --git a/app/src/main/java/com/yingmao/clash/net/http/HttpApi.kt b/app/src/main/java/com/yingmao/clash/net/http/HttpApi.kt index 6fda09f..efd3172 100644 --- a/app/src/main/java/com/yingmao/clash/net/http/HttpApi.kt +++ b/app/src/main/java/com/yingmao/clash/net/http/HttpApi.kt @@ -228,8 +228,10 @@ interface HttpApi { @GET("/taiziregister.txt") suspend fun getTzRegister(): String + @GET("/taiziregister_182269.txt") suspend fun getTz182269Register(): String + @GET("/bzyregister.txt") suspend fun getBzyRegister(): String diff --git a/app/src/main/java/com/yingmao/clash/net/http/NetService.kt b/app/src/main/java/com/yingmao/clash/net/http/NetService.kt index e05d3fa..c870f2b 100644 --- a/app/src/main/java/com/yingmao/clash/net/http/NetService.kt +++ b/app/src/main/java/com/yingmao/clash/net/http/NetService.kt @@ -16,6 +16,7 @@ import okhttp3.Callback import okhttp3.Cookie import okhttp3.CookieJar import okhttp3.HttpUrl +import okhttp3.Interceptor import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.OkHttpClient import okhttp3.Request @@ -72,6 +73,37 @@ class NetService private constructor() : INetService { var httpClient: OkHttpClient? = null; var downHttpClient: OkHttpClient? = null; + class ExceptionLoggingInterceptor : Interceptor { + override fun intercept(chain: Interceptor.Chain): Response { + val request = chain.request() + return try { + val response = chain.proceed(request) + // 如果需要也可记录非 2xx 的响应 + if (!response.isSuccessful) { + logHttpError(request, response.code, null) + } + response + } catch (e: Exception) { + logHttpError(request, null, e) + throw e // 抛出异常让上层处理 + } + } + + private fun logHttpError(request: Request, code: Int?, e: Exception?) { + val log = buildString { + append("URL: ${request.url}\n") + append("Method: ${request.method}\n") + append("Headers: ${request.headers}\n") + append("Body: ${request.body}\n") + code?.let { append("Response Code: $code\n") } + e?.let { append("Exception: ${e.message}\n${e.stackTraceToString()}") } + } + + // 这里可以上传到服务端,或者保存到本地文件 + println("❌ 网络请求异常:\n$log") + // FirebaseCrashlytics.getInstance().recordException(e) // 如果用了 Firebase + } + } override fun httpsClient(connTO:Long,readTO:Long,writeTO:Long): OkHttpClient { var loggingInterceptor = HttpLoggingInterceptor( @@ -79,8 +111,10 @@ class NetService private constructor() : INetService { override fun log(message: String) { Log.d("loggingInterceptor==>$message") } + } ) + loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY var builder = OkHttpClient.Builder() .retryOnConnectionFailure(true) @@ -95,6 +129,7 @@ class NetService private constructor() : INetService { .hostnameVerifier(getHostnameVerifier()!!) if (BuildConfig.DEBUG) { builder.addInterceptor(loggingInterceptor) +// builder.addInterceptor(ExceptionLoggingInterceptor()) } // builder.addInterceptor(loggingInterceptor) return builder.build() @@ -161,6 +196,7 @@ class NetService private constructor() : INetService { .addConverterFactory(ScalarsConverterFactory.create())//json解析器Gson .baseUrl(baseUrl) //设置BaseURL需以'/'结尾 .build() //创建Retrofit对象 + return retrofit.create(HttpApi::class.java) } fun createFreeBaseUrl2(): HttpApi { diff --git a/app/src/main/java/com/yingmao/clash/service/ConnectionService.java b/app/src/main/java/com/yingmao/clash/service/ConnectionService.java index 4181205..18b1cfc 100644 --- a/app/src/main/java/com/yingmao/clash/service/ConnectionService.java +++ b/app/src/main/java/com/yingmao/clash/service/ConnectionService.java @@ -13,7 +13,7 @@ import com.yingmao.clash.fragment.AccelerateViewModel; public class ConnectionService extends Service { private static final String TAG = "TimerService"; - private static final long INTERVAL_MILLIS = 60000; // 10 秒 + private static final long INTERVAL_MILLIS = 60000; // 60 秒 private Handler handler = new Handler(); private Intent intent; private Runnable runnable = new Runnable() { diff --git a/app/src/main/java/com/yingmao/clash/view/dialog/DialogAutoDoMainChoose.kt b/app/src/main/java/com/yingmao/clash/view/dialog/DialogAutoDoMainChoose.kt new file mode 100644 index 0000000..08f6992 --- /dev/null +++ b/app/src/main/java/com/yingmao/clash/view/dialog/DialogAutoDoMainChoose.kt @@ -0,0 +1,112 @@ +package com.yingmao.clash.view.dialog + +import android.annotation.SuppressLint +import android.app.Activity +import android.content.Context +import android.content.DialogInterface +import android.view.LayoutInflater +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.tencent.mmkv.MMKV +import com.yingmao.clash.BuildConfig +import com.yingmao.clash.R +import com.yingmao.clash.conf.BZYConstants + + + +/** + * @author tamsiree + * @date 2016/7/19 + * 确认 取消 Dialog + */ +open class DialogAutoDoMainChoose : RxDialog { + lateinit var titleView: TextView + private set + lateinit var but_try: TextView + private set + lateinit var but_cancel: TextView + private set + lateinit var domainRecyclerView: RecyclerView + private set + lateinit var onTryListener: OnTryButtonListener + + lateinit var onDomainListItemListener: OnListItemListener + + var domainFininshSet = mutableSetOf(); + + constructor(context: Context?, themeResId: Int) : super(context!!, themeResId) { + initView() + } + + constructor( + context: Context?, + cancelable: Boolean, + cancelListener: DialogInterface.OnCancelListener?, + ) : super(context!!, cancelable, cancelListener) { + initView() + } + + constructor(context: Context?) : super(context!!) { + initView() + } + + constructor(context: Activity?) : super(context!!) { + initView() + } + + constructor(context: Context?, alpha: Float, gravity: Int) : super(context, alpha, gravity) { + initView() + } + + + private fun initView() { + val dialogView = LayoutInflater.from(context).inflate(R.layout.dialog_domain_choose, null) + titleView = dialogView.findViewById(R.id.tv_title) + but_try = dialogView.findViewById(R.id.but_try) + but_cancel = dialogView.findViewById(R.id.but_cancel) + domainRecyclerView = dialogView.findViewById(R.id.domian_list) + + but_try.setOnClickListener { + onTryListener.tryButton() + } + but_cancel.setOnClickListener { onTryListener.cancel() } + + setContentView(dialogView) + setCancelable(false) + window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) + setNewData() + } + + @SuppressLint("NotifyDataSetChanged") + private fun setNewData() { + var mmkv = MMKV.defaultMMKV() + val originalUrl = + mmkv.decodeString(BZYConstants.MMKV_KEY_CURRENT_HOST, BuildConfig.service_url) + var newUrlString = originalUrl + + val routerHost = mmkv.decodeStringSet(BZYConstants.MMKV_KEY_ROUTER_HOST, HashSet()) + + + } + + fun setOnTryButtonListener(listener: OnTryButtonListener) { + this.onTryListener = listener + } + + + private fun changeSubUrl(originalUrl: String, newUrl: String): String { + return originalUrl.replace(Regex("https://[^/]+/"), "$newUrl/") + + } + + interface OnTryButtonListener { + fun tryButton() + fun cancel() + } + + interface OnListItemListener { + fun listItemClick() + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/yingmao/clash/view/dialog/DialogDoMainChoose.kt b/app/src/main/java/com/yingmao/clash/view/dialog/DialogDoMainChoose.kt index 8c74c93..2b42bf5 100644 --- a/app/src/main/java/com/yingmao/clash/view/dialog/DialogDoMainChoose.kt +++ b/app/src/main/java/com/yingmao/clash/view/dialog/DialogDoMainChoose.kt @@ -107,7 +107,6 @@ open class DialogDoMainChoose : RxDialog { } domainListAdapter.notifyDataSetChanged() } - } fun setOnTryButtonListener(listener: OnTryButtonListener) { diff --git a/app/src/main/java/com/yingmao/clash/vm/MainAtyVM.kt b/app/src/main/java/com/yingmao/clash/vm/MainAtyVM.kt index e3dff78..5b992c1 100644 --- a/app/src/main/java/com/yingmao/clash/vm/MainAtyVM.kt +++ b/app/src/main/java/com/yingmao/clash/vm/MainAtyVM.kt @@ -12,12 +12,12 @@ import com.yingmao.clash.act.NewMainActivity import com.yingmao.clash.base.PublicViewMode import com.cncat.vpn.common.log.Log import com.google.gson.Gson -import com.yingmao.clash.act.PageInfo import com.yingmao.clash.app.MainApplication import com.yingmao.clash.conf.BZYConstants import com.yingmao.clash.entity.CheckLoginRsp import com.yingmao.clash.entity.ClashNodebBean import com.yingmao.clash.entity.Node +import com.yingmao.clash.fragment.setting.SettingFragment import com.yingmao.clash.http.OkHttpBase import com.yingmao.clash.listener.AsyncCallBackListener import com.yingmao.clash.listener.DownLoadListener diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index 834f5aa..12ebfac 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -401,4 +401,5 @@ Service Description\n It is detected that the current account is logged in on other devices. If it is not your own operation, please change the password immediately and log out of the unfamiliar device. The application is initializing. Please wait for 1~2 seconds and try again. Starting + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d38a107..c1a0f59 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -412,8 +412,8 @@ 切换中,请稍后 当前节点拥堵请手动切换 请关闭加速后在进行源切换 + 检测到当前账号在其他设备登录,如非本人操作,请立即修改密码并退出陌生设备。 应用初始化中,请等待1~2秒后重试 启动中 - \ No newline at end of file