添加切换源时重启app功能

This commit is contained in:
cyh 2025-04-25 13:41:12 +08:00
parent f9a87d3553
commit c49627cba7
12 changed files with 678 additions and 266 deletions

View File

@ -79,6 +79,8 @@ dependencies {
// https://mvnrepository.com/artifact/com.tencent/mmkv-static // https://mvnrepository.com/artifact/com.tencent/mmkv-static
implementation("com.tencent:mmkv-static:1.2.10") implementation("com.tencent:mmkv-static:1.2.10")
implementation ("com.jakewharton:process-phoenix:3.0.0")
implementation("com.afollestad.material-dialogs:core:3.2.1") implementation("com.afollestad.material-dialogs:core:3.2.1")
//Retrofit 网络请求库 //Retrofit 网络请求库
api("com.squareup.retrofit2:retrofit:2.9.0") api("com.squareup.retrofit2:retrofit:2.9.0")
@ -95,7 +97,7 @@ dependencies {
// api("com.google.code.gson:gson:2.10.1") // api("com.google.code.gson:gson:2.10.1")
api("org.yaml:snakeyaml:1.29") api("org.yaml:snakeyaml:1.29")
// https://mvnrepository.com/artifact/com.al\ipay.sdk/alipaysdk-android // https://mvnrepository.com/artifact/com.alipay.sdk/alipaysdk-android
implementation("com.alipay.sdk:alipaysdk-android:15.8.17") implementation("com.alipay.sdk:alipaysdk-android:15.8.17")
// https://mvnrepository.com/artifact/com.journeyapps/zxing-android-embedded // https://mvnrepository.com/artifact/com.journeyapps/zxing-android-embedded
// implementation("com.journeyapps:zxing-android-embedded:3.6.0") // implementation("com.journeyapps:zxing-android-embedded:3.6.0")

View File

@ -15,6 +15,7 @@ import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.widget.AppCompatImageView import androidx.appcompat.widget.AppCompatImageView
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
@ -37,10 +38,12 @@ import com.yingmao.clash.remote.Resource
import com.cncat.vpn.service.model.Profile import com.cncat.vpn.service.model.Profile
import com.cncat.vpn.service.remote.IProfileManager import com.cncat.vpn.service.remote.IProfileManager
import com.cncat.vpn.service.remote.IRemoteService import com.cncat.vpn.service.remote.IRemoteService
import com.yingmao.clash.app.MainApplication
import com.yingmao.clash.util.Utils import com.yingmao.clash.util.Utils
import com.yingmao.clash.view.RxToast import com.yingmao.clash.view.RxToast
import com.yingmao.clash.view.adapter.NodeListAdapter import com.yingmao.clash.view.adapter.NodeListAdapter
import com.yingmao.clash.view.dialog.DialogDoMainChoose import com.yingmao.clash.view.dialog.DialogDoMainChoose
import com.yingmao.clash.view.dialog.DialogSureRestartChoose
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.MainScope import kotlinx.coroutines.MainScope
@ -322,10 +325,12 @@ class ChangeNodeActivity : BaseActivity(), View.OnClickListener {
showLoading("正在获取...", this@ChangeNodeActivity) showLoading("正在获取...", this@ChangeNodeActivity)
startTimer() startTimer()
updateProfile(false) updateProfile(false)
} }
private fun changeSubUrl(originalUrl: String, newUrl: String) { private fun changeSubUrl(originalUrl: String, newUrl: String) {
nowSubUrl = originalUrl.replace(Regex("https://[^/]+/"), "$newUrl/") nowSubUrl = originalUrl.replace(Regex("https://[^/]+/"), "$newUrl/")
MMKV.defaultMMKV().encode(BZYConstants.PROFILE_SUB_URL, nowSubUrl)
} }
val reloadLock = Semaphore(10) val reloadLock = Semaphore(10)
@ -341,7 +346,8 @@ class ChangeNodeActivity : BaseActivity(), View.OnClickListener {
testRuning = true testRuning = true
updateMoreBar("测速中") updateMoreBar("测速中")
launch(Dispatchers.IO) { launch(Dispatchers.IO) {
var group = reloadLock.withPermit { UIMainActivity.clashBinder?.let { cb -> var group = reloadLock.withPermit {
UIMainActivity.clashBinder?.let { cb ->
var names = cb.queryProxyGroupNames(false) var names = cb.queryProxyGroupNames(false)
if (names.isNotEmpty()) { if (names.isNotEmpty()) {
cb.healthCheck(names[0]) cb.healthCheck(names[0])
@ -510,11 +516,13 @@ class ChangeNodeActivity : BaseActivity(), View.OnClickListener {
} }
} }
} }
var dialogDoMainChoose: DialogDoMainChoose? = null var dialogDoMainChoose: DialogDoMainChoose? = null
private fun showDomainList() { private fun showDomainList() {
try { try {
SplashHelper(changeNodeVM).getHostWithFallback { success -> SplashHelper(changeNodeVM).getHostWithFallback { success ->
MainScope().launch { MainScope().launch {
if (success) { if (success) {
if (dialogDoMainChoose == null) { if (dialogDoMainChoose == null) {
dialogDoMainChoose = DialogDoMainChoose(this@ChangeNodeActivity) dialogDoMainChoose = DialogDoMainChoose(this@ChangeNodeActivity)
@ -523,20 +531,36 @@ class ChangeNodeActivity : BaseActivity(), View.OnClickListener {
dialogDoMainChoose?.setOnTryButtonListener(object : dialogDoMainChoose?.setOnTryButtonListener(object :
DialogDoMainChoose.OnTryButtonListener { DialogDoMainChoose.OnTryButtonListener {
override fun tryButton() { override fun tryButton() {
var currentHost = MMKV.defaultMMKV() saveSubUrl()
.decodeString(BZYConstants.MMKV_KEY_CURRENT_HOST, "")
// com.cncat.vpn.common.log.Log.d("tryButton currentHost==>${currentHost}")
var oldUrl = nowSubUrl
currentHost?.let { changeSubUrl(oldUrl, it) }
doProfile() doProfile()
dialogDoMainChoose?.dismiss()
} }
override fun cancel() { override fun cancel() {
com.cncat.vpn.common.log.Log.d("tryButton CHECK_LOGIN cancel") com.cncat.vpn.common.log.Log.d("tryButton CHECK_LOGIN cancel")
dialogDoMainChoose?.dismiss() dialogDoMainChoose?.dismiss()
} }
}) })
dialogDoMainChoose?.setOnListItemListener(object :
DialogDoMainChoose.OnListItemListener {
override fun listItemClick() {
saveSubUrl()
MainApplication.restartApp(this@ChangeNodeActivity, object :
MainApplication.OnRestartButtonListener {
override fun enterButton() {
}
override fun cancelButton() {
doProfile()
dialogDoMainChoose?.dismiss()
}
})
}
})
dialogDoMainChoose?.show() dialogDoMainChoose?.show()
} }
} }
@ -548,6 +572,14 @@ class ChangeNodeActivity : BaseActivity(), View.OnClickListener {
} }
} }
private fun saveSubUrl() {
var currentHost = MMKV.defaultMMKV()
.decodeString(BZYConstants.MMKV_KEY_CURRENT_HOST, "")
// com.cncat.vpn.common.log.Log.d("tryButton currentHost==>${currentHost}")
var oldUrl = nowSubUrl
currentHost?.let { changeSubUrl(oldUrl, it) }
}
private fun stopTimer() { private fun stopTimer() {
timerTask?.cancel() timerTask?.cancel()
timer?.purge() timer?.purge()

View File

@ -31,6 +31,7 @@ import com.stripe.android.model.StripeIntent
import com.tencent.mmkv.MMKV import com.tencent.mmkv.MMKV
import com.yingmao.clash.BuildConfig import com.yingmao.clash.BuildConfig
import com.yingmao.clash.R import com.yingmao.clash.R
import com.yingmao.clash.app.MainApplication
import com.yingmao.clash.base.BaseActivity import com.yingmao.clash.base.BaseActivity
import com.yingmao.clash.conf.BZYConstants import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.entity.CheckLoginRsp import com.yingmao.clash.entity.CheckLoginRsp
@ -49,6 +50,7 @@ import com.yingmao.clash.util.PayUtils
import com.yingmao.clash.util.ThreadUtils import com.yingmao.clash.util.ThreadUtils
import com.yingmao.clash.view.RxToast import com.yingmao.clash.view.RxToast
import com.yingmao.clash.view.dialog.DialogDoMainChoose import com.yingmao.clash.view.dialog.DialogDoMainChoose
import com.yingmao.clash.view.dialog.DialogSureRestartChoose
import com.yingmao.clash.view.dialog.RxDialogShapeLoading import com.yingmao.clash.view.dialog.RxDialogShapeLoading
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
@ -75,6 +77,7 @@ class MemberRechargeActivity: BaseActivity() {
private lateinit var rxDialogShapeLoading: RxDialogShapeLoading private lateinit var rxDialogShapeLoading: RxDialogShapeLoading
private var outTradeNo = "" private var outTradeNo = ""
private var selectedGradeID: Int = 0 private var selectedGradeID: Int = 0
//stripePay 支付 //stripePay 支付
private var paymentIntentClientSecret: String = "" private var paymentIntentClientSecret: String = ""
private val stripe: Stripe by lazy { private val stripe: Stripe by lazy {
@ -100,13 +103,15 @@ class MemberRechargeActivity: BaseActivity() {
} else { } else {
userIdentity.text = resources.getString(R.string.VIPMember) userIdentity.text = resources.getString(R.string.VIPMember)
} }
userIdentityNumber.text = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME) userIdentityNumber.text =
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME)
viewModel = ViewModelProvider(this)[RechargeViewModel::class.java] viewModel = ViewModelProvider(this)[RechargeViewModel::class.java]
observe(this, viewModel) observe(this, viewModel)
//获取充值列表 //获取充值列表
val username = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME,"")!! val username =
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")!!
val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN, "")!! val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN, "")!!
val userId = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_USER_ID)!! val userId = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_USER_ID)!!
viewModel.getPhRechargeInfo(username, phToken, userId) viewModel.getPhRechargeInfo(username, phToken, userId)
@ -126,7 +131,8 @@ class MemberRechargeActivity: BaseActivity() {
swipeLayout.setColorSchemeColors(Color.rgb(47, 223, 189)) swipeLayout.setColorSchemeColors(Color.rgb(47, 223, 189))
swipeLayout.setOnRefreshListener { swipeLayout.setOnRefreshListener {
selectedGrade = null selectedGrade = null
val username = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME,"")!! val username =
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")!!
val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN, "")!! val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN, "")!!
//获取充值列表 //获取充值列表
val userId = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_USER_ID)!! val userId = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_USER_ID)!!
@ -166,6 +172,7 @@ class MemberRechargeActivity: BaseActivity() {
} }
} }
@SuppressLint("SimpleDateFormat") @SuppressLint("SimpleDateFormat")
fun setExpireDate(validPeriod: Long) { fun setExpireDate(validPeriod: Long) {
val isExpire = checkExpire() val isExpire = checkExpire()
@ -240,10 +247,12 @@ class MemberRechargeActivity: BaseActivity() {
Logger.d("获取充值续费信息") Logger.d("获取充值续费信息")
swipeLayout.isRefreshing = true swipeLayout.isRefreshing = true
} }
HttpReqType.PAY -> { HttpReqType.PAY -> {
Logger.d("支付获取订单号") Logger.d("支付获取订单号")
showLoadingDialog(resources.getString(R.string.GeneratingOrder)) showLoadingDialog(resources.getString(R.string.GeneratingOrder))
} }
else -> { else -> {
} }
@ -265,6 +274,7 @@ class MemberRechargeActivity: BaseActivity() {
} }
} }
} }
HttpReqType.PAY -> { HttpReqType.PAY -> {
hideLoadingDialog() hideLoadingDialog()
Logger.d("生成订单请求成功") Logger.d("生成订单请求成功")
@ -281,6 +291,7 @@ class MemberRechargeActivity: BaseActivity() {
} }
} }
} }
HttpReqType.unionPay -> { HttpReqType.unionPay -> {
(httpStatus.rsp as PayRsp).let { rsp -> (httpStatus.rsp as PayRsp).let { rsp ->
if (rsp.code != "1000") { if (rsp.code != "1000") {
@ -292,6 +303,7 @@ class MemberRechargeActivity: BaseActivity() {
} }
} }
} }
HttpReqType.StripeType -> { HttpReqType.StripeType -> {
(httpStatus.rsp as PayUploadParamData).let { (httpStatus.rsp as PayUploadParamData).let {
if (it.data != null) { if (it.data != null) {
@ -303,6 +315,7 @@ class MemberRechargeActivity: BaseActivity() {
} }
} }
} }
HttpReqType.StripeWeChat -> { HttpReqType.StripeWeChat -> {
(httpStatus.rsp as PayUploadParamData).let { (httpStatus.rsp as PayUploadParamData).let {
if (it.data != null) { if (it.data != null) {
@ -311,7 +324,8 @@ class MemberRechargeActivity: BaseActivity() {
BZYConstants.MMKV_KEY_CURRENT_HOST, BZYConstants.MMKV_KEY_CURRENT_HOST,
BuildConfig.service_url BuildConfig.service_url
)!! )!!
val payUrl=serviceUrl+"/78zccgy0nsgknh9n4/iiii.html?s=${it.data.clientSecret.toString()}" val payUrl =
serviceUrl + "/78zccgy0nsgknh9n4/iiii.html?s=${it.data.clientSecret.toString()}"
val uri = Uri.parse(payUrl) val uri = Uri.parse(payUrl)
val intent = Intent(Intent.ACTION_VIEW) val intent = Intent(Intent.ACTION_VIEW)
intent.setData(uri) intent.setData(uri)
@ -322,6 +336,7 @@ class MemberRechargeActivity: BaseActivity() {
} }
} }
} }
HttpReqType.CHECK_LOGIN -> { HttpReqType.CHECK_LOGIN -> {
Logger.d("支付成功更新有效期") Logger.d("支付成功更新有效期")
val checkLoginRsp = httpStatus.rsp val checkLoginRsp = httpStatus.rsp
@ -337,6 +352,7 @@ class MemberRechargeActivity: BaseActivity() {
} }
} }
} }
else -> { else -> {
} }
@ -356,10 +372,12 @@ class MemberRechargeActivity: BaseActivity() {
Logger.d("获取支付订单号异常${httpStatus.msg}") Logger.d("获取支付订单号异常${httpStatus.msg}")
RxToast.error(resources.getString(R.string.DataPayNumber)) RxToast.error(resources.getString(R.string.DataPayNumber))
} }
HttpReqType.unionPay -> { HttpReqType.unionPay -> {
Logger.d("OrderGenerationFailed${httpStatus.msg}") Logger.d("OrderGenerationFailed${httpStatus.msg}")
RxToast.error(resources.getString(R.string.OrderGenerationFailed)) RxToast.error(resources.getString(R.string.OrderGenerationFailed))
} }
HttpReqType.StripeType -> { HttpReqType.StripeType -> {
hideLoading() hideLoading()
RxToast.error(resources.getString(R.string.NoPaymentReceipt)) RxToast.error(resources.getString(R.string.NoPaymentReceipt))
@ -370,6 +388,7 @@ class MemberRechargeActivity: BaseActivity() {
} }
} }
} }
var dialogDoMainChoose: DialogDoMainChoose? = null var dialogDoMainChoose: DialogDoMainChoose? = null
private fun showDomainList() { private fun showDomainList() {
try { try {
@ -392,6 +411,8 @@ class MemberRechargeActivity: BaseActivity() {
val userId = MMKV.defaultMMKV() val userId = MMKV.defaultMMKV()
.decodeString(BZYConstants.MMKV_KEY_USER_ID)!! .decodeString(BZYConstants.MMKV_KEY_USER_ID)!!
viewModel.getPhRechargeInfo(username, phToken, userId) viewModel.getPhRechargeInfo(username, phToken, userId)
dialogDoMainChoose?.dismiss()
} }
override fun cancel() { override fun cancel() {
@ -399,6 +420,32 @@ class MemberRechargeActivity: BaseActivity() {
dialogDoMainChoose?.dismiss() dialogDoMainChoose?.dismiss()
} }
}) })
dialogDoMainChoose?.setOnListItemListener(object :
DialogDoMainChoose.OnListItemListener {
override fun listItemClick() {
MainApplication.restartApp(this@MemberRechargeActivity, object :
MainApplication.OnRestartButtonListener {
override fun enterButton() {
}
override fun cancelButton() {
val username = MMKV.defaultMMKV()
.decodeString(
BZYConstants.MMKV_KEY_REMEMBER_USERNAME,
""
)!!
val phToken = MMKV.defaultMMKV()
.decodeString(BZYConstants.MMKV_KEY_PH_TOKEN, "")!!
val userId = MMKV.defaultMMKV()
.decodeString(BZYConstants.MMKV_KEY_USER_ID)!!
viewModel.getPhRechargeInfo(username, phToken, userId)
dialogDoMainChoose?.dismiss()
}
})
}
})
dialogDoMainChoose?.show() dialogDoMainChoose?.show()
} }
} }
@ -409,6 +456,7 @@ class MemberRechargeActivity: BaseActivity() {
e.printStackTrace() e.printStackTrace()
} }
} }
private fun showLoadingDialog(content: String) { private fun showLoadingDialog(content: String) {
apply { apply {
if (!::rxDialogShapeLoading.isInitialized) { if (!::rxDialogShapeLoading.isInitialized) {
@ -421,14 +469,17 @@ class MemberRechargeActivity: BaseActivity() {
} }
} }
} }
private fun hideLoadingDialog() { private fun hideLoadingDialog() {
if (::rxDialogShapeLoading.isInitialized && rxDialogShapeLoading.isShowing) { if (::rxDialogShapeLoading.isInitialized && rxDialogShapeLoading.isShowing) {
rxDialogShapeLoading.cancel() rxDialogShapeLoading.cancel()
} }
} }
private fun initAdapter(recharge: RechargeInfo) { private fun initAdapter(recharge: RechargeInfo) {
val rechargeListAdapter = VIPRechargeAdapter() val rechargeListAdapter = VIPRechargeAdapter()
rvRechargeList.layoutManager =GridLayoutManager(CommonUtils.getApp(), 2, GridLayoutManager.VERTICAL, false) rvRechargeList.layoutManager =
GridLayoutManager(CommonUtils.getApp(), 2, GridLayoutManager.VERTICAL, false)
rechargeListAdapter.setCloudServiceList(recharge, this@MemberRechargeActivity) rechargeListAdapter.setCloudServiceList(recharge, this@MemberRechargeActivity)
rvRechargeList.adapter = rechargeListAdapter rvRechargeList.adapter = rechargeListAdapter
rechargeListAdapter.setListener(object : VIPRechargeAdapter.VIPRechargeItemClickListener { rechargeListAdapter.setListener(object : VIPRechargeAdapter.VIPRechargeItemClickListener {
@ -441,12 +492,14 @@ class MemberRechargeActivity: BaseActivity() {
selectedGradeID = selectedGrade!!.id!! selectedGradeID = selectedGrade!!.id!!
} }
val decimalFormat = DecimalFormat("#0.00") val decimalFormat = DecimalFormat("#0.00")
tvPay.text =resources.getString(R.string.ActivateVIP)+"(¥${decimalFormat.format(amount)}" tvPay.text =
resources.getString(R.string.ActivateVIP) + "(¥${decimalFormat.format(amount)}"
} }
} }
}) })
} }
@OptIn(DelicateCoroutinesApi::class) @OptIn(DelicateCoroutinesApi::class)
private fun startCheckout() { private fun startCheckout() {
GlobalScope.launch { GlobalScope.launch {
@ -466,12 +519,14 @@ class MemberRechargeActivity: BaseActivity() {
RxToast.info(getString(R.string.PaymentCompleted)) RxToast.info(getString(R.string.PaymentCompleted))
} }
} }
StripeIntent.Status.RequiresAction -> { StripeIntent.Status.RequiresAction -> {
Log.i("startCheckoutRequiresAction") Log.i("startCheckoutRequiresAction")
ThreadUtils.runOnUiThread { ThreadUtils.runOnUiThread {
RxToast.info(getString(R.string.PaymentCancellation)) RxToast.info(getString(R.string.PaymentCancellation))
} }
} }
else -> { else -> {
Log.i("startCheckout status::${paymentIntent.status}") Log.i("startCheckout status::${paymentIntent.status}")
} }
@ -487,6 +542,7 @@ class MemberRechargeActivity: BaseActivity() {
) )
} }
} }
private fun orderPayment(data: Trade) { private fun orderPayment(data: Trade) {
Log.i("PayGradeIDTEST:${selectedGradeID}") Log.i("PayGradeIDTEST:${selectedGradeID}")
if (data.payType != null) { if (data.payType != null) {
@ -502,7 +558,8 @@ class MemberRechargeActivity: BaseActivity() {
) )
for (index in data.payType!!) { for (index in data.payType!!) {
if (index.payModel == 10) { if (index.payModel == 10) {
findViewById<LinearLayout>(R.id.llAggregatePayment).visibility= View.VISIBLE findViewById<LinearLayout>(R.id.llAggregatePayment).visibility =
View.VISIBLE
val JUhePay = findViewById<TextView>(R.id.JUhePay) val JUhePay = findViewById<TextView>(R.id.JUhePay)
JUhePay.visibility = View.VISIBLE JUhePay.visibility = View.VISIBLE
JUhePay.text = index.payChannel JUhePay.text = index.payChannel
@ -537,12 +594,14 @@ class MemberRechargeActivity: BaseActivity() {
dismiss() dismiss()
} }
} else if (index.payModel == 11) { } else if (index.payModel == 11) {
findViewById<LinearLayout>(R.id.llQuickPayment).visibility= View.VISIBLE findViewById<LinearLayout>(R.id.llQuickPayment).visibility =
View.VISIBLE
val KJPay = findViewById<TextView>(R.id.KJPay) val KJPay = findViewById<TextView>(R.id.KJPay)
KJPay.visibility = View.VISIBLE KJPay.visibility = View.VISIBLE
KJPay.text = index.payChannel KJPay.text = index.payChannel
if (index.payType == 1) { if (index.payType == 1) {
val ivQuickPayment=findViewById<AppCompatImageView>(R.id.ivQuickPayment) val ivQuickPayment =
findViewById<AppCompatImageView>(R.id.ivQuickPayment)
ivQuickPayment.visibility = View.VISIBLE ivQuickPayment.visibility = View.VISIBLE
ivQuickPayment.setOnClickListener { ivQuickPayment.setOnClickListener {
val payModel = index.payModel val payModel = index.payModel
@ -557,7 +616,8 @@ class MemberRechargeActivity: BaseActivity() {
} }
} }
} else if (index.payType == 2) { } else if (index.payType == 2) {
val ivQPWechatPay=findViewById<AppCompatImageView>(R.id.ivQPWechatPay) val ivQPWechatPay =
findViewById<AppCompatImageView>(R.id.ivQPWechatPay)
ivQPWechatPay.visibility = View.VISIBLE ivQPWechatPay.visibility = View.VISIBLE
ivQPWechatPay.setOnClickListener { ivQPWechatPay.setOnClickListener {
val payModel = index.payModel val payModel = index.payModel
@ -576,8 +636,10 @@ class MemberRechargeActivity: BaseActivity() {
findViewById<LinearLayout>(R.id.llStripe).visibility = View.VISIBLE findViewById<LinearLayout>(R.id.llStripe).visibility = View.VISIBLE
findViewById<LinearLayout>(R.id.llStripePay).visibility = View.VISIBLE findViewById<LinearLayout>(R.id.llStripePay).visibility = View.VISIBLE
findViewById<TextView>(R.id.tvStripePay).visibility = View.VISIBLE findViewById<TextView>(R.id.tvStripePay).visibility = View.VISIBLE
findViewById<AppCompatImageView>(R.id.ivStripeAlipay).visibility= View.VISIBLE findViewById<AppCompatImageView>(R.id.ivStripeAlipay).visibility =
val stripeWechatPay=findViewById<AppCompatImageView>(R.id.ivStripeWechatPay) View.VISIBLE
val stripeWechatPay =
findViewById<AppCompatImageView>(R.id.ivStripeWechatPay)
stripeWechatPay.visibility = View.VISIBLE stripeWechatPay.visibility = View.VISIBLE
findViewById<AppCompatImageView>(R.id.ivStripeAlipay).setOnClickListener { findViewById<AppCompatImageView>(R.id.ivStripeAlipay).setOnClickListener {
if (selectedGradeID != 0) { if (selectedGradeID != 0) {
@ -586,7 +648,10 @@ class MemberRechargeActivity: BaseActivity() {
return@setOnClickListener return@setOnClickListener
} }
dismiss() dismiss()
showLoading(resources.getString(R.string.PaymentIn),this@MemberRechargeActivity) showLoading(
resources.getString(R.string.PaymentIn),
this@MemberRechargeActivity
)
Log.i("PayGradeID:${selectedGradeID}") Log.i("PayGradeID:${selectedGradeID}")
viewModel.getPayClientSecret(selectedGradeID) viewModel.getPayClientSecret(selectedGradeID)
} else { } else {
@ -605,18 +670,21 @@ class MemberRechargeActivity: BaseActivity() {
} }
} }
} }
getCustomView().findViewById<AppCompatImageView>(R.id.ivBack).setOnClickListener { getCustomView().findViewById<AppCompatImageView>(R.id.ivBack)
.setOnClickListener {
dismiss() dismiss()
} }
} }
} }
} }
} }
override fun onRestart() { override fun onRestart() {
super.onRestart() super.onRestart()
android.util.Log.e("MemberRechargeActivity", " onRestart 重新可见之后刷新有效期") android.util.Log.e("MemberRechargeActivity", " onRestart 重新可见之后刷新有效期")
viewModel.checkLogin() viewModel.checkLogin()
} }
override fun onBackPressed() { override fun onBackPressed() {
val intent = Intent() val intent = Intent()
this.setResult(1000, intent) this.setResult(1000, intent)

View File

@ -1,6 +1,7 @@
package com.yingmao.clash.app package com.yingmao.clash.app
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity
import android.app.Application import android.app.Application
import android.app.NotificationChannel import android.app.NotificationChannel
import android.app.NotificationManager import android.app.NotificationManager
@ -9,6 +10,7 @@ import android.content.Intent
import android.content.res.Configuration import android.content.res.Configuration
import android.os.Build import android.os.Build
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat.getString
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import com.cncat.vpn.common.Global import com.cncat.vpn.common.Global
import com.cncat.vpn.common.compat.currentProcessName import com.cncat.vpn.common.compat.currentProcessName
@ -16,6 +18,7 @@ import com.cncat.vpn.common.log.Log
import com.github.gzuliyujiang.oaid.DeviceID import com.github.gzuliyujiang.oaid.DeviceID
import com.github.gzuliyujiang.oaid.DeviceIdentifier import com.github.gzuliyujiang.oaid.DeviceIdentifier
import com.github.gzuliyujiang.oaid.IGetter import com.github.gzuliyujiang.oaid.IGetter
import com.jakewharton.processphoenix.ProcessPhoenix
import com.orhanobut.logger.Logger import com.orhanobut.logger.Logger
import com.stripe.android.PaymentConfiguration import com.stripe.android.PaymentConfiguration
import com.tencent.mmkv.MMKV import com.tencent.mmkv.MMKV
@ -25,6 +28,12 @@ import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.entity.UserData import com.yingmao.clash.entity.UserData
import com.yingmao.clash.util.CrashCatchHandler import com.yingmao.clash.util.CrashCatchHandler
import com.yingmao.clash.util.clashDir import com.yingmao.clash.util.clashDir
import com.yingmao.clash.view.RxToast
import com.yingmao.clash.view.dialog.DialogDoMainChoose
import com.yingmao.clash.view.dialog.DialogSureRestartChoose
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.io.File import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
import java.util.Locale import java.util.Locale
@ -53,8 +62,39 @@ class MainApplication : Application() {
Log.d("setUserInfo") Log.d("setUserInfo")
userBean = bean userBean = bean
} }
fun restartApp(activity: Activity,listener:OnRestartButtonListener) {
var dialogDoMainChoose = DialogSureRestartChoose(activity)
if (!dialogDoMainChoose.isShowing) {
dialogDoMainChoose.setOnTryButtonListener(object :
DialogSureRestartChoose.OnTryButtonListener {
override fun tryButton() {
MainScope().launch {
delay(500)
ProcessPhoenix.triggerRebirth(mApp)
}
listener.enterButton()
dialogDoMainChoose.dismiss()
} }
override fun cancel() {
listener.cancelButton()
dialogDoMainChoose.dismiss()
}
})
dialogDoMainChoose.show()
}
}
}
interface OnRestartButtonListener{
fun enterButton()
fun cancelButton()
}
override fun attachBaseContext(base: Context?) { override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base) super.attachBaseContext(base)
} }
@ -103,7 +143,6 @@ class MainApplication : Application() {
} }
//openinstall //openinstall
// OpenInstall.init(applicationContext); // OpenInstall.init(applicationContext);
PaymentConfiguration.init( PaymentConfiguration.init(

View File

@ -1,6 +1,8 @@
package com.yingmao.clash.fragment.setting package com.yingmao.clash.fragment.setting
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.AlarmManager
import android.app.PendingIntent
import android.content.ClipData import android.content.ClipData
import android.content.ClipboardManager import android.content.ClipboardManager
import android.content.Context import android.content.Context
@ -9,6 +11,8 @@ import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Environment import android.os.Environment
import android.os.Handler
import android.os.Looper
import android.provider.Settings import android.provider.Settings
import android.text.TextUtils import android.text.TextUtils
import android.view.View import android.view.View
@ -39,6 +43,7 @@ import com.google.gson.Gson
import com.hjq.permissions.OnPermissionCallback import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.Permission import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions import com.hjq.permissions.XXPermissions
import com.jakewharton.processphoenix.ProcessPhoenix
import com.orhanobut.logger.Logger import com.orhanobut.logger.Logger
import com.tencent.mmkv.MMKV import com.tencent.mmkv.MMKV
import com.yingmao.clash.BuildConfig import com.yingmao.clash.BuildConfig
@ -77,6 +82,7 @@ import com.yingmao.clash.view.RxToast
import com.yingmao.clash.view.adapter.LanguageAdapter import com.yingmao.clash.view.adapter.LanguageAdapter
import com.yingmao.clash.view.dialog.DialogDoMainChoose import com.yingmao.clash.view.dialog.DialogDoMainChoose
import com.yingmao.clash.view.dialog.DialogNotice 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.view.dialog.RxDialogShapeLoading
import com.yingmao.clash.vm.MainAtyVM import com.yingmao.clash.vm.MainAtyVM
import com.yingmao.clash.webview.BZYWebViewKeFu import com.yingmao.clash.webview.BZYWebViewKeFu
@ -91,6 +97,7 @@ import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
import java.util.UUID import java.util.UUID
import kotlin.system.exitProcess
class SettingFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatchers.IO) { class SettingFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatchers.IO) {
@ -131,7 +138,7 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
backIv: ImageView, backIv: ImageView,
moreIv: TextView, moreIv: TextView,
titleTv: TextView, titleTv: TextView,
container: FrameLayout container: FrameLayout,
) { ) {
titleBarRl.visibility = View.GONE titleBarRl.visibility = View.GONE
titleTv.visibility = View.GONE titleTv.visibility = View.GONE
@ -145,48 +152,77 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
private fun initLanguage(view: View) { private fun initLanguage(view: View) {
userIdentityNumberCopy.text = requireActivity().resources.getString(R.string.copy) userIdentityNumberCopy.text = requireActivity().resources.getString(R.string.copy)
view.findViewById<TextView>(R.id.expirationTimeStr).text = requireActivity().resources.getString(R.string.expire_date) view.findViewById<TextView>(R.id.expirationTimeStr).text =
view.findViewById<TextView>(R.id.tvVip).text = requireActivity().resources.getString(R.string.vip_recharge) requireActivity().resources.getString(R.string.expire_date)
view.findViewById<TextView>(R.id.tvVipStr).text = requireActivity().resources.getString(R.string.RechargeDiscount) view.findViewById<TextView>(R.id.tvVip).text =
view.findViewById<TextView>(R.id.tvNotice).text = requireActivity().resources.getString(R.string.notice) requireActivity().resources.getString(R.string.vip_recharge)
view.findViewById<TextView>(R.id.tvNoticeStr).text = requireActivity().resources.getString(R.string.newNotice) view.findViewById<TextView>(R.id.tvVipStr).text =
requireActivity().resources.getString(R.string.RechargeDiscount)
view.findViewById<TextView>(R.id.tvNotice).text =
requireActivity().resources.getString(R.string.notice)
view.findViewById<TextView>(R.id.tvNoticeStr).text =
requireActivity().resources.getString(R.string.newNotice)
view.findViewById<TextView>(R.id.tvChangePsw).text = requireActivity().resources.getString(R.string.change_password) view.findViewById<TextView>(R.id.tvChangePsw).text =
view.findViewById<TextView>(R.id.tvChangePswStr).text = requireActivity().resources.getString(R.string.change_password) requireActivity().resources.getString(R.string.change_password)
view.findViewById<TextView>(R.id.tvFDS).text = requireActivity().resources.getString(R.string.PreventLoss) view.findViewById<TextView>(R.id.tvChangePswStr).text =
view.findViewById<TextView>(R.id.tvFDSStr).text = requireActivity().resources.getString(R.string.PreventLoss) requireActivity().resources.getString(R.string.change_password)
view.findViewById<TextView>(R.id.tvFDS).text =
requireActivity().resources.getString(R.string.PreventLoss)
view.findViewById<TextView>(R.id.tvFDSStr).text =
requireActivity().resources.getString(R.string.PreventLoss)
view.findViewById<TextView>(R.id.tvShare).text = requireActivity().resources.getString(R.string.share) view.findViewById<TextView>(R.id.tvShare).text =
view.findViewById<TextView>(R.id.tvShareStr).text = requireActivity().resources.getString(R.string.SharingDuration) requireActivity().resources.getString(R.string.share)
view.findViewById<TextView>(R.id.tvkefu).text = requireActivity().resources.getString(R.string.kefu) view.findViewById<TextView>(R.id.tvShareStr).text =
requireActivity().resources.getString(R.string.SharingDuration)
view.findViewById<TextView>(R.id.tvkefu).text =
requireActivity().resources.getString(R.string.kefu)
view.findViewById<TextView>(R.id.tvInit).text = requireActivity().resources.getString(R.string.InitializationRepair) view.findViewById<TextView>(R.id.tvInit).text =
view.findViewById<TextView>(R.id.tvInitStr).text = requireActivity().resources.getString(R.string.InitializationRepairStr) requireActivity().resources.getString(R.string.InitializationRepair)
view.findViewById<TextView>(R.id.tvExit).text = requireActivity().resources.getString(R.string.exit) view.findViewById<TextView>(R.id.tvInitStr).text =
view.findViewById<TextView>(R.id.tvExitStr).text = requireActivity().resources.getString(R.string.exitTxt) requireActivity().resources.getString(R.string.InitializationRepairStr)
view.findViewById<TextView>(R.id.tvExit).text =
requireActivity().resources.getString(R.string.exit)
view.findViewById<TextView>(R.id.tvExitStr).text =
requireActivity().resources.getString(R.string.exitTxt)
view.findViewById<TextView>(R.id.tvTermsService).text = requireActivity().resources.getString(R.string.ServiceTerms) view.findViewById<TextView>(R.id.tvTermsService).text =
view.findViewById<TextView>(R.id.tvTermsServiceStr).text = requireActivity().resources.getString(R.string.TermsOfService) requireActivity().resources.getString(R.string.ServiceTerms)
view.findViewById<TextView>(R.id.tvPrivacyPolicy).text = requireActivity().resources.getString(R.string.PrivacyPolicy) view.findViewById<TextView>(R.id.tvTermsServiceStr).text =
view.findViewById<TextView>(R.id.tvPrivacyPolicyStr).text = requireActivity().resources.getString(R.string.PrivacyOfPolicy) requireActivity().resources.getString(R.string.TermsOfService)
view.findViewById<TextView>(R.id.tvPrivacyPolicy).text =
requireActivity().resources.getString(R.string.PrivacyPolicy)
view.findViewById<TextView>(R.id.tvPrivacyPolicyStr).text =
requireActivity().resources.getString(R.string.PrivacyOfPolicy)
view.findViewById<TextView>(R.id.tvUploadErrorLog).text = requireActivity().resources.getString(R.string.UploadErrorLog) view.findViewById<TextView>(R.id.tvUploadErrorLog).text =
view.findViewById<TextView>(R.id.tvUploadErrorLogStr).text = requireActivity().resources.getString(R.string.UploadErrorLog) requireActivity().resources.getString(R.string.UploadErrorLog)
view.findViewById<TextView>(R.id.tvSubApplicationProxy).text = requireActivity().resources.getString(R.string.source_switch) view.findViewById<TextView>(R.id.tvUploadErrorLogStr).text =
view.findViewById<TextView>(R.id.tvSubApplicationProxyStr).text = requireActivity().resources.getString(R.string.source_switch_str) requireActivity().resources.getString(R.string.UploadErrorLog)
view.findViewById<TextView>(R.id.tvSubApplicationProxy).text =
requireActivity().resources.getString(R.string.source_switch)
view.findViewById<TextView>(R.id.tvSubApplicationProxyStr).text =
requireActivity().resources.getString(R.string.source_switch_str)
view.findViewById<TextView>(R.id.tvLanguageSwitching).text = requireActivity().resources.getString(R.string.LanguageSwitching) view.findViewById<TextView>(R.id.tvLanguageSwitching).text =
view.findViewById<TextView>(R.id.tvLanguageSwitchingStr).text = requireActivity().resources.getString(R.string.LanguageSwitchingStr) requireActivity().resources.getString(R.string.LanguageSwitching)
view.findViewById<TextView>(R.id.tvTelegram).text = requireActivity().resources.getString(R.string.telegram) view.findViewById<TextView>(R.id.tvLanguageSwitchingStr).text =
view.findViewById<TextView>(R.id.tvTelegramStr).text = requireActivity().resources.getString(R.string.TelegramStr) requireActivity().resources.getString(R.string.LanguageSwitchingStr)
view.findViewById<TextView>(R.id.tvTelegram).text =
requireActivity().resources.getString(R.string.telegram)
view.findViewById<TextView>(R.id.tvTelegramStr).text =
requireActivity().resources.getString(R.string.TelegramStr)
tvSignIn.text = requireActivity().resources.getString(R.string.SignIn) tvSignIn.text = requireActivity().resources.getString(R.string.SignIn)
tvExitLog.text = requireActivity().resources.getString(R.string.exit) tvExitLog.text = requireActivity().resources.getString(R.string.exit)
tvVersion.text=requireActivity().resources.getString(R.string.edition) + "${BuildConfig.VERSION_NAME}." + BuildConfig.productId tvVersion.text =
requireActivity().resources.getString(R.string.edition) + "${BuildConfig.VERSION_NAME}." + BuildConfig.productId
} }
private fun initView(view: View) { private fun initView(view: View) {
@ -221,18 +257,21 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
} else { } else {
userIdentity.text = requireActivity().resources.getString(R.string.VIPMember) userIdentity.text = requireActivity().resources.getString(R.string.VIPMember)
} }
userIdentityNumber.text = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME) userIdentityNumber.text =
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME)
userIdentityNumber.setOnClickListener { userIdentityNumber.setOnClickListener {
val userName = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME) val userName = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME)
val clipboardManager = requireActivity().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager val clipboardManager =
requireActivity().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clipData = ClipData.newPlainText("text", userName) val clipData = ClipData.newPlainText("text", userName)
clipboardManager.setPrimaryClip(clipData) clipboardManager.setPrimaryClip(clipData)
RxToast.info(resources.getString(R.string.CopyToClipboard)) RxToast.info(resources.getString(R.string.CopyToClipboard))
} }
userIdentityNumberCopy.setOnClickListener { userIdentityNumberCopy.setOnClickListener {
val userName = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME) val userName = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME)
val clipboardManager = requireActivity().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager val clipboardManager =
requireActivity().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clipData = ClipData.newPlainText("text", userName) val clipData = ClipData.newPlainText("text", userName)
clipboardManager.setPrimaryClip(clipData) clipboardManager.setPrimaryClip(clipData)
RxToast.info(resources.getString(R.string.CopyToClipboard)) RxToast.info(resources.getString(R.string.CopyToClipboard))
@ -310,7 +349,10 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
clUploadErrorLog.setOnClickListener { clUploadErrorLog.setOnClickListener {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (Environment.isExternalStorageManager()) { if (Environment.isExternalStorageManager()) {
showLoading(resources.getString(R.string.UploadingInProgress), requireActivity()) showLoading(
resources.getString(R.string.UploadingInProgress),
requireActivity()
)
// 已授予权限 // 已授予权限
val directory: File? = requireActivity().getExternalFilesDir("CrashLog") val directory: File? = requireActivity().getExternalFilesDir("CrashLog")
if (directory != null) { if (directory != null) {
@ -438,11 +480,14 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
intent.setData(uri) intent.setData(uri)
startActivity(intent) startActivity(intent)
} }
tvExitLog.setOnClickListener { tvExitLog.setOnClickListener {
cleanUserInfo() cleanUserInfo()
} }
} }
var dialogDoMainChoose: DialogDoMainChoose? = null var dialogDoMainChoose: DialogDoMainChoose? = null
private fun showDomainList() { private fun showDomainList() {
try { try {
@ -456,25 +501,42 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
dialogDoMainChoose?.setOnTryButtonListener(object : dialogDoMainChoose?.setOnTryButtonListener(object :
DialogDoMainChoose.OnTryButtonListener { DialogDoMainChoose.OnTryButtonListener {
override fun tryButton() { override fun tryButton() {
RxToast.info(getString(R.string.StorageSuccessful)) RxToast.info(getString(R.string.ModificationFailed))
dialogDoMainChoose?.dismiss() dialogDoMainChoose?.dismiss()
} }
override fun cancel() { override fun cancel() {
dialogDoMainChoose?.dismiss() dialogDoMainChoose?.dismiss()
} }
}) })
dialogDoMainChoose?.setOnListItemListener(object :
DialogDoMainChoose.OnListItemListener {
override fun listItemClick() {
RxToast.info(getString(R.string.StorageSuccessful))
MainApplication.restartApp(requireActivity(),object:MainApplication.OnRestartButtonListener{
override fun enterButton() {
}
override fun cancelButton() {
dialogDoMainChoose?.dismiss()
}
})
}
})
dialogDoMainChoose?.show() dialogDoMainChoose?.show()
} }
} }
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
} }
} }
@SuppressLint("SimpleDateFormat") @SuppressLint("SimpleDateFormat")
fun setExpireDate() { fun setExpireDate() {
val isExpire = checkExpire() val isExpire = checkExpire()
@ -547,6 +609,7 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
} }
return true return true
} }
private fun cleanUserInfo() { private fun cleanUserInfo() {
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_PH_TOKEN) MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_PH_TOKEN)
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_TOKEN) MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_TOKEN)
@ -564,6 +627,7 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
startActivity(Intent(CommonUtils.getApp(), LoginActivity::class.java)) startActivity(Intent(CommonUtils.getApp(), LoginActivity::class.java))
requireActivity().finish() requireActivity().finish()
} }
private fun cleanProfile() { private fun cleanProfile() {
launch(Dispatchers.IO) { launch(Dispatchers.IO) {
profileBinder?.let { pm -> profileBinder?.let { pm ->
@ -576,18 +640,21 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
} }
} }
} }
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState) super.onActivityCreated(savedInstanceState)
Logger.d("onActivityCreated") Logger.d("onActivityCreated")
mainAtyVM = ViewModelProvider(this)[MainAtyVM::class.java] mainAtyVM = ViewModelProvider(this)[MainAtyVM::class.java]
observe(this, mainAtyVM) observe(this, mainAtyVM)
} }
private fun stopUpLoadTimer() { private fun stopUpLoadTimer() {
if (activity != null) { if (activity != null) {
val uiMainActivity = activity as UIMainActivity val uiMainActivity = activity as UIMainActivity
uiMainActivity.stopUploadTimer() uiMainActivity.stopUploadTimer()
} }
} }
private fun goNewRecharge() { private fun goNewRecharge() {
if (activity != null) { if (activity != null) {
val uiMainActivity = activity as UIMainActivity val uiMainActivity = activity as UIMainActivity
@ -619,11 +686,13 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
RxToast.error(resources.getString(R.string.CheckFailed) + "${data.message}") RxToast.error(resources.getString(R.string.CheckFailed) + "${data.message}")
} }
} }
HttpReqType.CHECK_LOGIN -> { HttpReqType.CHECK_LOGIN -> {
(httpStatus.rsp as CheckLoginRsp).let { checkLoginRsp -> (httpStatus.rsp as CheckLoginRsp).let { checkLoginRsp ->
if (checkLoginRsp.code == 0) { if (checkLoginRsp.code == 0) {
val mmkv = MMKV.defaultMMKV() val mmkv = MMKV.defaultMMKV()
val oldExpireTime = mmkv.decodeLong(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD, 0) val oldExpireTime =
mmkv.decodeLong(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD, 0)
if (checkLoginRsp.data != null) { if (checkLoginRsp.data != null) {
val nowExpireTime = checkLoginRsp.data.vpnExpireTime val nowExpireTime = checkLoginRsp.data.vpnExpireTime
if (nowExpireTime > oldExpireTime) { if (nowExpireTime > oldExpireTime) {
@ -631,7 +700,8 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
mmkv.encode(BZYConstants.MMKV_KEY_VPN_EXPIRED, expired ?: true) mmkv.encode(BZYConstants.MMKV_KEY_VPN_EXPIRED, expired ?: true)
mmkv.encode(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD, nowExpireTime) mmkv.encode(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD, nowExpireTime)
setExpireDate() setExpireDate()
fragments.filterIsInstance<HomeFragment>().forEach { it.setExpireDate() } fragments.filterIsInstance<HomeFragment>()
.forEach { it.setExpireDate() }
mainAtyVM.getAirNodes() mainAtyVM.getAirNodes()
RxToast.info(resources.getString(R.string.SuccessfullyUpdatedUserInformation)) RxToast.info(resources.getString(R.string.SuccessfullyUpdatedUserInformation))
} }
@ -689,30 +759,37 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
hideLoading() hideLoading()
} }
} }
else -> { else -> {
} }
} }
} }
override fun httpFailure(httpStatus: HttpStatus.Failure) { override fun httpFailure(httpStatus: HttpStatus.Failure) {
when (httpStatus.reqType) { when (httpStatus.reqType) {
HttpReqType.VIPSIGN -> { HttpReqType.VIPSIGN -> {
RxToast.error(resources.getString(R.string.CheckFailed) + httpStatus.msg) RxToast.error(resources.getString(R.string.CheckFailed) + httpStatus.msg)
} }
HttpReqType.GET_AIRNODES -> { HttpReqType.GET_AIRNODES -> {
Logger.e("获取节点异常:${httpStatus.msg}") Logger.e("获取节点异常:${httpStatus.msg}")
} }
HttpReqType.CHECK_LOGIN -> { HttpReqType.CHECK_LOGIN -> {
RxToast.error(resources.getString(R.string.QueryFailed)) RxToast.error(resources.getString(R.string.QueryFailed))
} }
HttpReqType.UploadParameters -> { HttpReqType.UploadParameters -> {
hideLoading() hideLoading()
} }
else -> { else -> {
} }
} }
} }
private suspend fun setSub2(url: String) { private suspend fun setSub2(url: String) {
profileBinder?.let { pm -> profileBinder?.let { pm ->
pm.queryAll().forEach { itemPro -> pm.queryAll().forEach { itemPro ->
@ -753,6 +830,7 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
} }
} }
} }
fun showLoading(str: String, context: Context) { fun showLoading(str: String, context: Context) {
val message = if (TextUtils.isEmpty(str)) "进行中..." else str val message = if (TextUtils.isEmpty(str)) "进行中..." else str
if (baseLoading == null) { if (baseLoading == null) {
@ -769,6 +847,7 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
baseLoading?.cancel() baseLoading?.cancel()
} }
} }
private fun startTimer() { private fun startTimer() {
getNodeTimeOutNum = 5 getNodeTimeOutNum = 5
timerJob = launch { timerJob = launch {
@ -780,6 +859,7 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
errInit() errInit()
} }
} }
private fun errInit() { private fun errInit() {
requireActivity().runOnUiThread { requireActivity().runOnUiThread {
hideLoading() hideLoading()
@ -830,6 +910,7 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
} }
} }
private fun finishInit() { private fun finishInit() {
timerJob?.cancel() timerJob?.cancel()
@ -839,6 +920,7 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
} }
} }
private fun checkPermission() { private fun checkPermission() {
XXPermissions.with(this) XXPermissions.with(this)
// 申请单个权限 // 申请单个权限
@ -847,7 +929,10 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
.request(object : OnPermissionCallback { .request(object : OnPermissionCallback {
override fun onGranted(permissions: MutableList<String>, allGranted: Boolean) { override fun onGranted(permissions: MutableList<String>, allGranted: Boolean) {
if (!allGranted) { if (!allGranted) {
showLoading(resources.getString(R.string.UploadingInProgress), requireActivity()) showLoading(
resources.getString(R.string.UploadingInProgress),
requireActivity()
)
val directory: File? = requireActivity().getExternalFilesDir("CrashLog") val directory: File? = requireActivity().getExternalFilesDir("CrashLog")
if (directory != null) { if (directory != null) {
val allFilePath = getAllFilePath(directory.path) val allFilePath = getAllFilePath(directory.path)
@ -864,6 +949,7 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
return return
} }
} }
override fun onDenied(permissions: MutableList<String>, doNotAskAgain: Boolean) { override fun onDenied(permissions: MutableList<String>, doNotAskAgain: Boolean) {
if (doNotAskAgain) { if (doNotAskAgain) {
RxToast.error(resources.getString(R.string.ReadPermissionsDenied)) RxToast.error(resources.getString(R.string.ReadPermissionsDenied))
@ -877,6 +963,7 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
} }
}) })
} }
private fun showBottomDialog(data: List<LanguageInfoEntity>) { private fun showBottomDialog(data: List<LanguageInfoEntity>) {
//1、使用Dialog、设置style //1、使用Dialog、设置style
val bottomSheetDialog = BottomSheetDialog(requireActivity(), R.style.BottomSheetDialog) val bottomSheetDialog = BottomSheetDialog(requireActivity(), R.style.BottomSheetDialog)
@ -887,7 +974,8 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
//设置点击dialog外部不消失 //设置点击dialog外部不消失
//bottomSheetDialog.setCanceledOnTouchOutside(false); //bottomSheetDialog.setCanceledOnTouchOutside(false);
bottomSheetDialog.show() bottomSheetDialog.show()
bottomView.findViewById<View>(R.id.IVClose).setOnClickListener { bottomSheetDialog.dismiss() } bottomView.findViewById<View>(R.id.IVClose)
.setOnClickListener { bottomSheetDialog.dismiss() }
val abRecharge = bottomSheetDialog.findViewById<RecyclerView>(R.id.RvLanguage) val abRecharge = bottomSheetDialog.findViewById<RecyclerView>(R.id.RvLanguage)
abRecharge!!.layoutManager = LinearLayoutManager(requireActivity()) abRecharge!!.layoutManager = LinearLayoutManager(requireActivity())
val languageAdapter = LanguageAdapter() val languageAdapter = LanguageAdapter()
@ -906,12 +994,14 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
updateActivity("Chinese-CN", Locale.CHINA) updateActivity("Chinese-CN", Locale.CHINA)
RxToast.success("切换为简体中文!") RxToast.success("切换为简体中文!")
} }
2 -> { 2 -> {
languageItem.isChoose = true languageItem.isChoose = true
config.locale = Locale("zh", "HK") config.locale = Locale("zh", "HK")
updateActivity("Chinese-HK", Locale("zh", "HK")) updateActivity("Chinese-HK", Locale("zh", "HK"))
RxToast.success("切換爲中文繁體!") RxToast.success("切換爲中文繁體!")
} }
3 -> { 3 -> {
languageItem.isChoose = true languageItem.isChoose = true
config.locale = Locale.ENGLISH config.locale = Locale.ENGLISH
@ -926,6 +1016,7 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
}) })
} }
fun updateActivity(language: String, locale: Locale) { fun updateActivity(language: String, locale: Locale) {
MMKV.defaultMMKV().encode(BZYConstants.languageInfo, language) MMKV.defaultMMKV().encode(BZYConstants.languageInfo, language)
val resources = this.resources val resources = this.resources
@ -939,6 +1030,7 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
startActivity(intent) startActivity(intent)
requireActivity().finish() requireActivity().finish()
} }
private fun uploadForAliOss(data: ParamData, filePath: List<String>, dirStr: String) { private fun uploadForAliOss(data: ParamData, filePath: List<String>, dirStr: String) {
val endpoint = "oss-cn-hongkong.aliyuncs.com" val endpoint = "oss-cn-hongkong.aliyuncs.com"
val accessKeyId = data.credentials?.accessKeyId val accessKeyId = data.credentials?.accessKeyId
@ -983,7 +1075,7 @@ class SettingFragment: BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
override fun onFailure( override fun onFailure(
request: PutObjectRequest?, request: PutObjectRequest?,
clientExcepion: ClientException, clientExcepion: ClientException,
serviceException: ServiceException serviceException: ServiceException,
) { ) {
requireActivity().runOnUiThread { requireActivity().runOnUiThread {
hideLoading() hideLoading()

View File

@ -41,6 +41,8 @@ open class DialogDoMainChoose : RxDialog {
private set private set
lateinit var onTryListener: OnTryButtonListener lateinit var onTryListener: OnTryButtonListener
lateinit var onDomainListItemListener: OnListItemListener
constructor(context: Context?, themeResId: Int) : super(context!!, themeResId) { constructor(context: Context?, themeResId: Int) : super(context!!, themeResId) {
initView() initView()
} }
@ -110,6 +112,9 @@ open class DialogDoMainChoose : RxDialog {
fun setOnTryButtonListener(listener: OnTryButtonListener) { fun setOnTryButtonListener(listener: OnTryButtonListener) {
this.onTryListener = listener this.onTryListener = listener
} }
fun setOnListItemListener(listener: OnListItemListener) {
this.onDomainListItemListener = listener
}
var domainListAdapter: DomainListAdapter = DomainListAdapter(R.layout.domain_list_item_layout) var domainListAdapter: DomainListAdapter = DomainListAdapter(R.layout.domain_list_item_layout)
private fun initAdapter() { private fun initAdapter() {
@ -134,7 +139,7 @@ open class DialogDoMainChoose : RxDialog {
if (domainListAdapter.selectedPosition == position) -1 else position if (domainListAdapter.selectedPosition == position) -1 else position
domainListAdapter.notifyItemChanged(position) domainListAdapter.notifyItemChanged(position)
this.onTryListener.tryButton() this.onDomainListItemListener.listItemClick()
} }
} }
} }
@ -148,5 +153,8 @@ open class DialogDoMainChoose : RxDialog {
fun tryButton() fun tryButton()
fun cancel() fun cancel()
} }
interface OnListItemListener {
fun listItemClick()
} }
}

View File

@ -0,0 +1,95 @@
package com.yingmao.clash.view.dialog
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.chad.library.adapter.base.BaseQuickAdapter
import com.cncat.vpn.common.log.Log
import com.tencent.mmkv.MMKV
import com.yingmao.clash.R
import com.yingmao.clash.act.UIMainActivity
import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.entity.DomainItemBean
import com.yingmao.clash.view.adapter.DomainListAdapter
import com.yingmao.clash.view.dialog.DialogDoMainChoose.OnTryButtonListener
/**
* @author tamsiree
* @date 2016/7/19
* 确认 取消 Dialog
*/
open class DialogSureRestartChoose : 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
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()
}
fun setOnTryButtonListener(listener: OnTryButtonListener) {
this.onTryListener = listener
}
private fun initView() {
val dialogView = LayoutInflater.from(context).inflate(R.layout.dialog_app_restart_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)
but_try.setOnClickListener {
onTryListener.tryButton()
}
but_cancel.setOnClickListener { onTryListener.cancel() }
setContentView(dialogView)
setCancelable(false)
window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
interface OnTryButtonListener {
fun tryButton()
fun cancel()
}
}

View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@drawable/activity_bg"
android:gravity="center"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.8"
tools:ignore="MissingConstraints">
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="10dp"
android:gravity="center"
android:text="@string/sure_restart"
android:textColor="@color/blue_4072FE"
android:textSize="16sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_margin="15dp"
android:layout_height="wrap_content">
<TextView
android:id="@+id/but_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/activity_close_bg"
android:layout_weight="1"
android:gravity="center"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:text="@string/cancel">
</TextView>
<TextView
android:id="@+id/but_try"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/activity_jump_bg"
android:layout_marginStart="10dp"
android:layout_weight="1"
android:gravity="center"
android:text="@string/restart"
android:paddingTop="5dp"
android:paddingBottom="5dp">
</TextView>
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -3,7 +3,7 @@
<string name="app_name_backcn">波斯猫回国加速器</string> <string name="app_name_backcn">波斯猫回国加速器</string>
<string name="app_name_gz">影猫</string> <string name="app_name_gz">影猫</string>
<string name="app_name_gz2">影猫加速器</string> <string name="app_name_gz2">影猫加速器</string>
<string name="app_name_taizi">太子加速器</string> <string name="app_name_taizi">太子</string>
<string name="file">file</string> <string name="file">file</string>
<string name="rule">rule</string> <string name="rule">rule</string>
<string name="proxy">proxy</string> <string name="proxy">proxy</string>
@ -348,4 +348,6 @@ Service Description\n
<string name="everyDay">每天</string> <string name="everyDay">每天</string>
<string name="PopularApplications">Popular applications</string> <string name="PopularApplications">Popular applications</string>
<string name="PopularApplicationsStr">Popular Application Navigation</string> <string name="PopularApplicationsStr">Popular Application Navigation</string>
<string name="sure_restart">Suggest restarting</string>
<string name="restart">Restart</string>
</resources> </resources>

View File

@ -3,7 +3,7 @@
<string name="app_name_backcn">波斯貓回國加速器</string> <string name="app_name_backcn">波斯貓回國加速器</string>
<string name="app_name_gz">影貓</string> <string name="app_name_gz">影貓</string>
<string name="app_name_gz2">影貓加速器</string> <string name="app_name_gz2">影貓加速器</string>
<string name="app_name_taizi">太子加速器</string> <string name="app_name_taizi">太子</string>
<string name="file">文件</string> <string name="file">文件</string>
<string name="rule">規則</string> <string name="rule">規則</string>
<string name="proxy">代理</string> <string name="proxy">代理</string>
@ -338,4 +338,6 @@
<string name="everyDay">每天</string> <string name="everyDay">每天</string>
<string name="PopularApplications">熱門應用</string> <string name="PopularApplications">熱門應用</string>
<string name="PopularApplicationsStr">熱門應用導航</string> <string name="PopularApplicationsStr">熱門應用導航</string>
<string name="sure_restart">"建議重啓 "</string>
<string name="restart">"重啓 "</string>
</resources> </resources>

View File

@ -4,7 +4,7 @@
<string name="app_name_gz">影貓</string> <string name="app_name_gz">影貓</string>
<string name="app_name_gz2">影貓加速器</string> <string name="app_name_gz2">影貓加速器</string>
<string name="app_name_taizi">太子加速器</string> <string name="app_name_taizi">太子</string>
<string name="file">文件</string> <string name="file">文件</string>
<string name="rule">規則</string> <string name="rule">規則</string>
<string name="proxy">代理</string> <string name="proxy">代理</string>
@ -337,4 +337,6 @@
<string name="everyDay">每天</string> <string name="everyDay">每天</string>
<string name="PopularApplications">熱門應用</string> <string name="PopularApplications">熱門應用</string>
<string name="PopularApplicationsStr">熱門應用導航</string> <string name="PopularApplicationsStr">熱門應用導航</string>
<string name="sure_restart">"建議重啓 "</string>
<string name="restart">"重啓 "</string>
</resources> </resources>

View File

@ -3,7 +3,7 @@
<string name="app_name_backcn">波斯猫回国加速器</string> <string name="app_name_backcn">波斯猫回国加速器</string>
<string name="app_name_gz">影猫</string> <string name="app_name_gz">影猫</string>
<string name="app_name_gz2">影猫加速器</string> <string name="app_name_gz2">影猫加速器</string>
<string name="app_name_taizi">太子加速器</string> <string name="app_name_taizi">太子</string>
<string name="file">文件</string> <string name="file">文件</string>
<string name="rule">规则</string> <string name="rule">规则</string>
<string name="proxy">代理</string> <string name="proxy">代理</string>
@ -356,4 +356,6 @@
<string name="everyDay">每天</string> <string name="everyDay">每天</string>
<string name="PopularApplications">热门应用</string> <string name="PopularApplications">热门应用</string>
<string name="PopularApplicationsStr">热门应用导航</string> <string name="PopularApplicationsStr">热门应用导航</string>
<string name="sure_restart">建议重启</string>
<string name="restart">重启</string>
</resources> </resources>